I'm trying to write a shader for terrain that will color the mesh based on slope angle, ie color the sides of mountains or other steep surfaces a different color than the ground. In my shader I am checking the normal of a vertex, and if its angle is past a certain threshold then I set the vertex color to black, otherwise white.

What I'm getting is that solid colors are being applied across entire faces:

enter image description here

But I'm expecting the colors to smoothly transition between vertices:

enter image description here

enter image description here

Here's my shader code:

shader_type spatial;

uniform float slope_threshold;
varying vec3 vColor;

void vertex() {
    float slope_angle = degrees(dot(NORMAL, vec3(0, 1, 0)));
    if (slope_angle < slope_threshold) {
        vColor = vec3(0, 0, 0);
    else {
        vColor = vec3(1, 1, 1);

void fragment() {
    ALBEDO = vColor;

Am I writing the shader wrong somehow? Am I exporting my terrain model from Blender incorrectly? Any help would be greatly appreciated!


1 Answer 1


This is what happens: All the vertex of each triangle of your mesh has the triangle Normal. You decide a Color per Vertex based on that Normal. The GPU interpolates the Colors of the Vertex of each triangle. But since they are on the same triangle, they have the same Normal, and thus the same Color, so there is no visible interpolation.

You can enable the visualization of Vertex Normals in Blender. Ask me where the option is if you want a rant about Blender UI. Search a tutorial if you want to know where the option is.

Anyway, the solution? Tell Blender to do Shade Smooth.

What actually happens is that flat shading results in duplicate Vertex. So they aren't shared between triangles. With smooth shading, the triangle actually share Vertex.

By the way, the dot product gives you (a value proportional to) the cosine of the angle between the vectors. Not the angle. Applying the conversion from radians to degrees to cosine of the angle makes no sense.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .