I made a plane in THREEjs using Mesh, PlaneGeometry and ShaderMaterial. It's a very simple/basic form. I applied a simple phormula to make the plain more steep. Now I'm trying to make the lower surface darker than the higher surface. Here is what I tried.

Vertex shader:

    varying vec3 vColor;
    varying vec3 test;

    void main(void) {
        float amp = 2.5;
        float z = amp * sin(position.x*0.2)  * cos(position.y*0.5); //this makes the surface steeper
        test = vec3(1, 1, -z); //this goes to fragment shader

        gl_Position = projectionMatrix * modelViewMatrix * vec4(position.x, position.y, z, 1.0);

Fragment shader:

    precision mediump float;
    varying vec3 test;
    void main(void) {   
        vec3 st = gl_FragCoord.xyz/test;
        gl_FragColor = vec4(st.xyz, 1.0);


Result from this

This result is not desirable, since the contrast between top and down is too aggressive and I'd like the lower surface less white. What do I have to change to accomplish this?

  • $\begingroup$ gl_Fragcoord gives you the coordinates with respect to the camera orientation and projection... So it is not the height of the world... When moving the camera, your colors would change... It seems to me, that you want the world coordinates. Am I right? In case I am, you could varying the model vertex position from vertex to fragment shader. $\endgroup$
    – Thomas
    Oct 27, 2022 at 20:23
  • $\begingroup$ Yeah, don't understand the gl_FragCoord there. It's supposed to give screen space coordinates afaik. You could just try to divide the color by the steepness? $\endgroup$ Nov 1, 2022 at 6:50


Your Answer

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

Browse other questions tagged or ask your own question.