Terrain lighting artifacts

Started by
19 comments, last by Mihumihu 9 years, 5 months ago

normali1.jpgHere is strange artifacts during the lighting. I've tried a different average normals calculations, but nothing. I think that it may be bad light shaders I've made. Or may be something else...please help.

Advertisement

No normal calculation function will help you here. You'll need to use per pixel lighting and store the terrain normals to a texture, so that each triangle smoothly interpolates 4 normals (instead of just 3).

Can you show some shader code?

Cheers!

Thanks, bro! This is my shaders:


attribute vec3 aVertexNormal;
attribute vec3 aVertexPosition;


uniform mat4 uPMatrix;
uniform mat4 uMVMatrix;
uniform mat3 uNMatrix;


varying vec3 vTransformedNormal;
varying vec4 vPosition;


void main(void) {
        vPosition = uMVMatrix * vec4(aVertexPosition, 1.0);
        gl_Position = uPMatrix * vPosition;
        vTransformedNormal = uNMatrix * aVertexNormal;
}

precision highp float;


varying vec3 vTransformedNormal;
varying vec4 vPosition;


uniform vec4 uColor;


#define MAX_POINT_LIGHTS 1


uniform int pointLightsQuantity;
uniform vec3 pointLightsPositions[MAX_POINT_LIGHTS];
uniform vec3 pointLightsParamsv[MAX_POINT_LIGHTS * 3];
uniform float pointLightsParamsf[MAX_POINT_LIGHTS];


void main(void) {


    vec3 lightWeighting;
vec3 lightDirection;
vec3 normal;
vec3 eyeDirection;
vec3 reflectionDirection;
float specularLightWeighting;
float diffuseLightWeighting;

//i=0
    lightDirection = normalize(pointLightsPositions[0] - vPosition.xyz);
    //float distance = length(dir);
    //float attenuation = 1.0/(1.0+0.1*distance+0.01*distance*distance);
    normal = normalize(vTransformedNormal);
    eyeDirection = normalize(-vPosition.xyz);
    reflectionDirection = reflect(-lightDirection, normal); 
    specularLightWeighting = pow(max(dot(reflectionDirection, eyeDirection), 0.0), pointLightsParamsf[0]);
    diffuseLightWeighting = max(dot(normal, lightDirection), 0.0);
    lightWeighting += pointLightsParamsv[0] + pointLightsParamsv[1] * diffuseLightWeighting + pointLightsParamsv[2] * specularLightWeighting; //0-ambient rgb; 1-diffuse rgb; 2 = specular rgb
        
    gl_FragColor = vec4(uColor.rgb * lightWeighting, uColor.a);
}

I use only normals aVertexNormal, I dont create texture...is it ok?

Have you tried texturing your terrain yet - most of these artefacts disappear when you apply textures. And kauna is correct that ideally you need to bake your normal into a 3Dc compressed texture to completely get rid of the artefacts.

But actually I doubt about my terrain grid tile is 33x33 points, so I have 33x33 calculated vertices normals, therefore my texture is 33x33 pixels. And next I have to apply lighting to the terrain tile with 33x33 normals texture. Is it right way?

P.S.

I have tried...but it s realy noticed on the snow.

Yes, this is just a common artifact from vertex based lighting. You can kind of fix this with texturing (the details in your texture will mostly cover it up, and you can also compensate: such as making the edges darker and doing the opposite of what this artifact is doing), or as others said, store the normals in a texture. Bilinear filtering will smooth this out nicely.

But actually I doubt about my terrain grid tile is 33x33 points, so I have 33x33 calculated vertices normals, therefore my texture is 33x33 pixels. And next I have to apply lighting to the terrain tile with 33x33 normals texture. Is it right way?

Yes, one pixel for each vertex. Your pixel shader can handle the lighting based on the normals it gets from the texture and your scene's lights, yes.

Thank You, people! I begin to make textured normals. Will see:)

You can also re-orient your triangulation so it follows the main slope line, and that will sharply reduce these artifacts.

See near the end of this post ("additional optimizations"):

http://mtnphil.wordpress.com/2011/09/22/terrain-engine/

Then here's how I managed to do the triangulation on the GPU:

http://mtnphil.wordpress.com/2012/10/15/terrain-triangulation-summary/

You can calculate vertex normals offline or in vertex shader. I did that and used normals in fragment shader for lighting. chech yor code for vertex normal generation.


You can calculate vertex normals offline or in vertex shader. I did that and used normals in fragment shader for lighting. chech yor code for vertex normal generation.

I don't think that's the OP's problem. If they're calculated in the vertex shader, the interpolated normals will result in exactly the screenshot posted in the first post.

This topic is closed to new replies.

Advertisement