Search code examples
three.jsgraphicsglslshaderwebgl

How to color a steep plane based on its height using vertex shader?


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 terrain to be colored based on its height using vertex shaders. For example, the top could be color 1, the middle color 2 and so on...

Here's what I tried:

Vertex shader:

varying vec3 vColor;

void main(void) {
    float uAmp = 20.0;

    float z = uAmp * sin(position.x*0.7) * cos(position.y*0.7);

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

    if (gl_Position.z <= 2.0*uAmp/3.0) {
        vColor = vec3(1.0, 0.0, 0.0);
    }
    else if (gl_Position.z <= 2.0*uAmp*(2.0/3.0)) {
        vColor = vec3(0.0, 1.0, 0.0); //this goes to fragment shader
    }
    else {
        vColor = vec3(0.0, 0.0, 1.0); //this goes to fragment shader
    }
}

Fragment shader:

precision mediump float;

        varying vec3 vColor;
        
        void main(void) {   
            gl_FragColor = vec4(vColor, 1.0);
            }

This doesn't produce the expected result. Instead, the object is almost fully blue: enter image description here


Solution

  • I think you only care about the unprojected value of Z. Does it work if you change

    if (z <= 2.0*uAmp/3.0) {
       vColor = vec3(1.0, 0.0, 0.0);
    }
    ...