How to add light to ShaderMaterial

I’m new to GLSL and shader, and here is my code:

    const vertexShader = `
      attribute vec3 aPosition;
      attribute vec3 aColor;

      varying vec3 vColor;

      varying vec3 vNormal;
      void main(){
        vColor = aColor;

        vNormal = normal;

        vec3 transformed =;
        transformed += aPosition;
        gl_Position = projectionMatrix* modelViewMatrix * vec4(transformed, 1.);

    const fragmentShader = `
      uniform vec3 color;
      varying vec3 vColor;

      vec3 lightColor = vec3(1.0, 1.0, 1.0);
      uniform vec3 lightDirection;

      varying vec3 vNormal;
      void main(){
        vec3 norm = normalize(vNormal);

        float nDotL = clamp(dot(-lightDirection, norm), 0.0, 1.0);

        vec4 diffuseColor = vec4(lightColor, 1.0) * vec4(vColor, 1.0) * nDotL;

        gl_FragColor = vec4( color * vColor, 1.0) * diffuseColor;
    const material = new Three.ShaderMaterial({
      uniforms: {
        color: { value: new Three.Color(0xffffff) },
        lightDirection: { value: new Three.Vector3(1.0, 1.0, 1.0).normalize() }

I want to add directional light to my custom ShaderMaterial(point light and ambient light too, if possible), but I found the result of the above code is strange. The original color I appointed to the mesh is entirely gone, only left with white color. Besides, the light seems too intensive. So does anyone can help me modify my code? Your help is highly appreciated.

There are more questions, than answers.

Why do you negate lightDirection?

After that line you change position of a vertex, adding aPosition, but it doesn’t mean that vertex’s normal stays the same. Though, I don’t know how your object looks like and how aPosition changes object’s form.

Would be cool to provide an editable live code working example, that demonstrates the issue.

1 Like

Thanks for your reply :grinning:. The light direction issue is because I tried to figure out the true direcition by making some modification, which I forget to change back. The normal issue is due to my little experience on GLSL, and I have no idea how to fix it.
I made a simple demo:

And I found more issues, like the light color is dominated by the background color. Anyway, I’d appreciate if you can give me some advice.

You didn’t mention that you use InstancedBufferGeometry, so without that info, the moment with normals was confusing for me :slight_smile:

Here is an option of how you can do it:

1 Like

Thank you so much for your help. :smiling_face_with_three_hearts: Your answer perfectly solved my problem!

1 Like