• Advertisement
Sign in to follow this  

Terrain lighting artifacts

This topic is 1210 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Edited by Turbochist

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites

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?

Share this post


Link to post
Share on other sites

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.

Edited by mark ds

Share this post


Link to post
Share on other sites

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.

Edited by Turbochist

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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/

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites


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.

Share this post


Link to post
Share on other sites
I generate vertex normals in vertex shader, use them for water waves and terrain and have not seen such artifacts

Share this post


Link to post
Share on other sites

If the interpolation is the case then every mesh you render would have same artifacts.

Every mesh does have the same artefacts. This isn't something specific to untextured low-poly terrain grids, but it just happens to be obvious in that case.

Share this post


Link to post
Share on other sites

Agreed.

 

The ultimate case is a cube.

 

If you model your cube as 8 points and 12 tri's  then the lighting will be awful.

 

All 8 verts will have normals pointing at 45 degrees away from the vert, (well 45 degrees in two planes).

 

To get around this you can store "face normals" but not many engines support those, or you export your cube as 24 verts with three verts having the same position, but different normals.

 

If you get into this position of having strange lighting effects, it's always good to think back to this extreme case and see if the same problem is causing the artifacts you are seeing.

 

It's a bit like writing L and R on your wellies, a handy check when you are confused. smile.png

Share this post


Link to post
Share on other sites

OK maybe the artifacts can be seen if normals are not computed properly. I have not experiences such artifacts in my 10 year engine development experience. I can only remember these kind of artifacts, if using vertex lighting and not fragment shader lighting. I as stated previously check your vertex normal generation code. Also check you triangle winding, CW or CCW because i think some of the normals are negative. Check your index and vertex buffers.

Share this post


Link to post
Share on other sites

I'm having similar issues with my terrain lighting.  I've found multiple threads related to this very same issue, but no actual solutions.  I've checked and double checked my vertex normal.  I've even added the ability to render them to visually confirm they at least look correct.  I've also tried using per-pixel lighting shaders from multiple tutorial websites, but I always have this diamond-like pattern artifact.  Could it be my Intel HD Graphics 4000 video card??  I've got the latest drivers.  Still no luck.

 

Can anyone please make a suggestion on what to try next?

 

image001.png

 

 

With mesh overlay and vertex normal

image002.png

 

image003.png

Share this post


Link to post
Share on other sites

As has been explained several times already in this thread, this is just the way it is. When you triangulate quads and interpolate between 3 points, you will have "artifacts" that depend on how you triangulate it.

 

There are various mitigations:

- Sample the normals from a texture in your pixel shader. That way you'll be interpolating between 4 points, and not 3.

- Orient your triangulation along the slope line

- Increase the resolution of your height map

- Put a texture on it so it's not so noticeable

Share this post


Link to post
Share on other sites

Shaders are new technology to me.  I'm a bit late to the game.

 

I recall looking at a per-pixel lighting tutorial a few years ago.  It used the standard teapot model and none of these lighting artifacts were noticable from what I remember.  The quads in that teapot model mesh were also simply split into two triangles.  I guess the lighting artifacts just become more and more noticeable when the curvature of the mesh increases??  Is that correct?

 

If you could point me to a tutorial that describes interpolating a normals texture in a pixel shader, I'd appreciate it.

 

Thanks.

Share this post


Link to post
Share on other sites

Wouldn't using GL_QUADS instead of GL_TRIANGLES cause the pixel shader to interpolate between four points?  I tried this, but the issue still exists.  

Share this post


Link to post
Share on other sites

Wouldn't using GL_QUADS instead of GL_TRIANGLES cause the pixel shader to interpolate between four points?  I tried this, but the issue still exists.  

 

Quads are simply converted to triangles which is why GL_QUADS was removed from the OpenGL API.

Share this post


Link to post
Share on other sites

I've made simple terrain normals into texture rendering function(without tanget and bitangent calculations). And picture had became good.  

101144_1414764337_good.jpg

but there is like above artifacts still here

arte.jpg

 

Is it can be solved?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement