Yerbs
Yerbs

Reputation: 177

Fragment Shader not showing in ThreeJS

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.

Upvotes: 1

Views: 883

Answers (1)

Rabbid76
Rabbid76

Reputation: 210928

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>

Upvotes: 2

Related Questions