I just wrote a simple Phong shader and I got issues with the Lambert term of the diffuse component
the shading should be smooth no matter the object resolution
really subtle, but one can see the faces of the sphere while normals should be smoothly interpolated
I managed to isolate the problem around the normals
once again, hard to see, but faces should bee smooth, but appears flat shaded
seams appears on normals values
so in the shader
vec3 lightPosition=vec3(10,10,10); // hard coded for debug
void main(){
v = vec4(worldViewMatrix * vec4(modelPosition,1));
normal = normalize(normalMatrix * normal); <-------------- normals should be smoothly interpolated, not sure it is the case
lightDir = normalize(vec3(lightPosition - v.xyz));
}
so is there a way to tell the mesh to render smooth instead of flat?
thought this was automatic
as comparison, here is the original shader (in demoniak software)
sphere is low res like mine
here is the final (A+S+D) result
clearly there is something wrong
also the light spot is always visible around the object while it should be present when one is one the same side of the light
That’s because you’re computing the normal in the vertex shader.
Normal is then linearly interpolated between vertices when passed as a varying to the fragment shader, and that’s why you can see the faces.
I also see it in the demoniac shot on the blue sphere btw. The torus doesn’t have this artifact because I guess it’s a lot more tessellated.
There is no real way around this, except having a higher number of polygons or, using normal mapping.
Remember, normals are linearly interpolated from tip to tip. That’s one of the reasons you should normalize them in the frag shader, to at least get them to be a curve again.
…but note that there will still be an error because normalizing a linearly interpolated normal will change the curve. This gets more dramatic the larger the different between the normals… which is why shapes will look better with more triangles.
Give how you have entirely dark triangles near the edges, it does seem like something is wrong, though.
Flat shading is very different
see this
the left sphere is flat shaded, the right one is smooth shaded. See how the right one present the same artefacts you’re talking about.
Yes, that’s what most game do (though not really to alleviate this issue, but more to add in some small details that the mesh resolution doesn’t allow).
You can try to normalize the normal in the frag shader as Paul said, maybe it will be less noticeable.
Seems that there are shadows, so maybe it’s another artefact.
what I dont understand is why the light spec spot is always visible, should’nt it only visible on the side facing the light ?
It really follows the camera view as I turn around the object
vec3 lightPosition=vec3(10,10,10);
void main(){
v = vec4(worldViewMatrix * vec4(modelPosition,1));
normal = normalMatrix * normal;
lightDir = vec3(lightPosition - v.xyz);
if lightPosition is hardcoded as a global world position, should’nt it be converted with worldview matrix ?
I have spent some time trying to get rid of this effect myself (not jME but shaders are shaders), but it seems not practical to get rid of starburst pattern. The problem is that linear interpolation of normals is only an approximation, and not a high quality one at that. It is however a very cheap approximation. For my use case the best way to make it less visible is to use more triangles and I guess that’s the way most people do it.
Here is a short PDF detailing another way to do interpolation of normals that is more expensive but better quality (according to the authors, haven’t implemented it myself yet)