片段着色器未在 ThreeJS 中显示

Fragment Shader not showing in ThreeJS

我不熟悉 threejs 并在其中实现着色器。我带来了一个有趣的着色器,但我在显示它时遇到了问题。我相信它与代码中的变量“len”有关,但我不确定。这是代码笔 https://codepen.io/Yerbs/pen/eYWgevO 的 link。任何帮助,将不胜感激 这是片段着色器

fragmentShader: `
uniform vec2 resolution;
uniform float time;

const int AMOUNT = 12;
         
        void main() {
    vec2 coord = 20.0 * (gl_FragCoord.xy - resolution / 2.0) / min(resolution.y, resolution.x);

    float len;

    for (int i = 0; i < AMOUNT; i++){
        len = length(vec2(coord.x, coord.y));

        coord.x = coord.x - cos(coord.y + sin(len)) + cos(time / 9.0);
        coord.y = coord.y + sin(coord.x + cos(len)) + sin(time / 12.0);
    }

    gl_FragColor = vec4(cos(len * 2.0), cos(len * 3.0), cos(len * 1.0), 1.0);
        }
      `
    });

我已经测试了之前的代码,所以我知道它与片段本身有关。

您需要设置统一变量 timeresolution 的值(参见 ShaderMaterial)。例如:

const material = new THREE.ShaderMaterial({
    uniforms: {
        time: { type: "f", value: 0.0 },
        resolution: { type: "v2", value: new THREE.Vector2() },
    },
    // [...]
function animate(timestamp) {
    requestAnimationFrame(animate);
    material.uniforms.time.value = timestamp / 1000;
    material.uniforms.resolution.value.x = renderer.domElement.width;
    material.uniforms.resolution.value.y = renderer.domElement.height;
    renderer.render(scene, camera);
}

完整示例:

const renderer = new THREE.WebGLRenderer({
    antialias: false
});

renderer.setSize(window.innerWidth, window.innerHeight, 2);
document.body.appendChild(renderer.domElement);
window.addEventListener( 'resize', function(e) {
    renderer.setSize(window.innerWidth, window.innerHeight, 2);
});

const scene = new THREE.Scene();
const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);

const material = new THREE.ShaderMaterial({
    uniforms: {
        time: { type: "f", value: 0.0 },
        resolution: { type: "v2", value: new THREE.Vector2() },
    },
    vertexShader: `
    varying vec2 vUv;
    
    void main() {
        vUv = uv;
        gl_Position = vec4( position, 1.0 );    
    }
    `,
    fragmentShader: `
    uniform vec2 resolution;
    uniform float time;

    const int AMOUNT = 12;
            
    void main() {
        vec2 coord = 20.0 * (gl_FragCoord.xy - resolution / 2.0) / min(resolution.y, resolution.x);

        float len;

        for (int i = 0; i < AMOUNT; i++){
            len = length(vec2(coord.x, coord.y));

            coord.x = coord.x - cos(coord.y + sin(len)) + cos(time / 9.0);
            coord.y = coord.y + sin(coord.x + cos(len)) + sin(time / 12.0);
        }

        gl_FragColor = vec4(1.0, cos(len * 3.0), cos(len * 1.0), 1.0);
    }
    `
});

const quad = new THREE.Mesh(new THREE.PlaneBufferGeometry( 2, 2, 1, 1 ), material);
scene.add(quad);

function animate(timestamp) {
    requestAnimationFrame(animate);
    material.uniforms.time.value = timestamp / 1000;
    material.uniforms.resolution.value.x = renderer.domElement.width;
    material.uniforms.resolution.value.y = renderer.domElement.height;
    renderer.render(scene, camera);
}

animate();
<script src="https://cdn.jsdelivr.net/npm/three@0.137/build/three.js"></script>