Why the image won't match with UV coordinates of shader?

I’m trying to match my UV coordinates image in shader but it won’t do but it has already loaded the texture so everything is fine… I forgot to match the UV coordinates can anyone help me?

Example source code here…

https://codesandbox.io/p/sandbox/vigorous-joji-nzgfq4?file=%2Fsrc%2Findex.js%3A10%2C13

This is my shaders…

const fragmentShader = `
    varying vec2 vUv;
    
    vec3 colorA = vec3(0.008,0.895,0.940);
    vec3 colorB = vec3(0.129,0.299,1.000);

    uniform sampler2D u_texture;
    uniform vec2 u_resolution; 

    void main() {
        vec2 st = gl_FragCoord.xy / u_resolution.xy;
        vec4 img = texture2D(u_texture,st);

        vec2 normalizedPixel = gl_FragCoord.xy/500.0;
        
        vec3 color = mix(colorA, colorB, normalizedPixel.x);
        gl_FragColor = vec4(img.xyz  ,1.0);
    }
`

const vertexShader = `
    uniform float u_time;

    varying vec2 vUv;

    void main() {
        vec4 modelPosition = modelMatrix * vec4(position, 1.0);
        modelPosition.y += sin(modelPosition.x * 4.0 + u_time * 2.0) * 0.2;
        modelPosition.x += sin(modelPosition.y * 4.0 + u_time * 2.0) * 0.2;
        modelPosition.z += sin((modelPosition.y * 4.0 + modelPosition.x * 4.0) + u_time * 2.0) * 0.2;
        
        // Uncomment the code and hit the refresh button below for a more complex effect 🪄
        // modelPosition.y += sin(modelPosition.z * 6.0 + u_time * 2.0) * 0.1;

        vec4 viewPosition = viewMatrix * modelPosition;
        vec4 projectedPosition = projectionMatrix * viewPosition;

        gl_Position = projectedPosition;
    }
`

And this is the react-three codes

export const Scene = () => {
    
    const shadersRef = useRef(null)

    const texture = useLoader(THREE.TextureLoader, './img/ase3.jpg');

    const data = useMemo(() => ({
        u_texture: { value: texture },
        u_time: { value: 0.0 },
        u_resolution: { value: new THREE.Vector2(0.0,0.0) },
        transform: { value: new THREE.Vector3(0,0,0) } 
    }),[texture])

    useFrame(({ clock }) => {
        if (shadersRef.current) {
            shadersRef.current.uniforms.u_time.value = clock.getElapsedTime();
        }
    });
    
    return (
        <>
            <ambientLight />
            <mesh position={[0,0,0]} rotation={[-Math.PI / 2 , 0, 0]}>
                <planeGeometry args={[2,2,64,64]} />
                <shaderMaterial
                    ref={shadersRef}
                    uniforms={data}
                    fragmentShader={fragmentShader}
                    vertexShader={vertexShader}
                    side={THREE.DoubleSide}
                />
                
            </mesh>
        </>
    )
}

somebody help me please :slight_smile: I don’t know why it isn’t working mate…

Perhaps a screenshot of some kind would be helpful, if you’re unable to provide the code in some working environment.

1 Like

Its not super clear what you want here. You mention UV’s but in your shader you are not using the UV’s and instead you are using the gl_FragCoord to drive your texture coordinates. If you want to use the UV then you should do vec4 img = texture2D(u_texture, vUv); instead of what you have now.

1 Like

Thank you for response here is a working sample

https://codesandbox.io/p/sandbox/vigorous-joji-nzgfq4?file=%2Fsrc%2Findex.js%3A10%2C13

I tried that but it is neither working you can see the example here below

https://codesandbox.io/p/sandbox/vigorous-joji-nzgfq4?file=%2Fsrc%2Findex.js%3A10%2C13

I’m also not 100% sure what you are trying to achieve. But I’ve noticed from the codesandbox you’ve provided that you do not set vUv in your vertex shader. The attribute uv is provided by threejs for you. The Plane geometry you are using already has proper UVs.

So, if indeed you just want to map the image to the plane, you need to set vUv in your vertex shader:

void main() {
    // ...
    vUv = uv;
    // ...
}

Also, you probably don’t want to devide vUv by u_resolution:

  1. vUv is already normalized
  2. at least in your codesandbox you don’t set its value, so you are effectively dividing by vec2(0.0, 0.0).

Thanks it works finally… Here

https://codesandbox.io/p/sandbox/vigorous-joji-nzgfq4?file=%2Fsrc%2FComplexDesign%2FImageShader.jsx%3A20%2C1

but my problem why it won’t work in my browser? I’m using brave. It’s not popping up in my browser

Update it works after 30mins of keep refreshing the browser