Как именно работают эти коды GLSL? - PullRequest
0 голосов
/ 30 апреля 2019

Я создал приведенный ниже пример, чтобы попрактиковаться в кодировании GLSL, используя Three.js. Я ссылался на некоторые примеры кодов, поэтому не совсем уверен, как работают некоторые коды GLSL.

Я добавил комментарии (★) к двум кодам ниже, где я не понимаю, что происходит.

Короче говоря, я не понимаю, как создается этот белый круг и как изменяется его размер.

Я новичок в GLSL и чувствую, что это может быть математический вопрос, но я был бы очень признателен, если бы кто-то мог помочь мне точно понять, что происходит в приведенных ниже кодах GLSL.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/104/three.min.js"></script>
    <title>shader01</title>
    <style>
        body {
            width: 100%;
            height: 100%;
            overflow: hidden;
            margin: 0;
            padding: 0;
        }
    </style>
</head>

<body>

    <div id="container"></div>

    <script id="fragmentShader" type="x-shader/x-fragment">

        #ifdef GL_ES
        precision mediump float;
        #endif

        uniform vec2  mouse;  
        uniform float time;    
        uniform vec2  resolution; 

        void main(void){

        vec2 st = gl_FragCoord.xy/resolution; 
        
        //★What exactly is this calculation for? Why is it using a length method?   
        float f = 0.1/ length(st - mouse); 

        vec3 colorA = vec3(0.14,0.14,0.90); 
        vec3 colorB = vec3(1.00,0.80,0.20);
        float pct = abs(sin(time));

        //★colorA is 'vec3' while f is 'float', so what kind of calculation is made here? 
        //How does using a mix method make it possible for the size of the white circle to change like this?
        vec3 tmp = mix((colorA) + f, colorB, pct);

        gl_FragColor = vec4(tmp, 1.0);

        }

    </script>

    <script>
        var container;
        var camera, scene, renderer;
        var uniforms;

        init();
        animate();

        function init() {
            container = document.getElementById('container');

            camera = new THREE.Camera();
            camera.position.z = 1;

            scene = new THREE.Scene();

            var geometry = new THREE.PlaneBufferGeometry(2, 2);

            uniforms = {

                time: { type: "f", value: 1.0 },
                resolution: { type: "v2", value: new THREE.Vector2() },
                mouse: { type: "v2", value: new THREE.Vector2() }
            };

            var material = new THREE.ShaderMaterial({
                uniforms: uniforms,
                fragmentShader: document.getElementById('fragmentShader').textContent
            });

            var mesh = new THREE.Mesh(geometry, material);
            scene.add(mesh);

            renderer = new THREE.WebGLRenderer();
            renderer.setPixelRatio(window.devicePixelRatio);

            container.appendChild(renderer.domElement);

            onWindowResize();
            window.addEventListener('resize', onWindowResize, false);


        }

        function onWindowResize(e) {
            renderer.setSize(window.innerWidth, window.innerHeight);
            uniforms.resolution.value.x = renderer.domElement.width;
            uniforms.resolution.value.y = renderer.domElement.height;
        }

        function animate() {
            requestAnimationFrame(animate);
            render();
        }

        document.onmousemove = function (e) {
            uniforms.mouse.value.x = e.pageX / window.innerWidth;
            uniforms.mouse.value.y = 1 - (e.pageY / window.innerHeight);

        }


        function render() {
            uniforms.time.value += 0.01;
            renderer.render(scene, camera);
        }

    </script>

</body>

</html>
...