1

I am new to threejs and implementing shaders in it. I brought a fun shader in but I am having issues with displaying it. I believe it is related to the variable "len" in the code but I am not sure. Here is the link to the codepen https://codepen.io/Yerbs/pen/eYWgevO. Any Help would be appreciated This is the frag shader

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);
        }
      `
    });

I have tested out previous code so I know it is related to the fragment itself.

1 Answer 1

2

You need to set the values of the uniforms variables time and resolution (see ShaderMaterial). e.g:

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);
}

Complete example:

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/[email protected]/build/three.js"></script>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.