First, I want to warn everybody that I'm really noob with shaders, this is my first attemp to update a shader by reading tutorials about GLSL. Also I don't understand math equations, but still can understand when I'm explained in code.
I was able to work on the terrain shader made by Andres that blend 4 textures and use the height value to set the blend factor (that part was made by Andres and it work really well). I just added more parameters to it and it still worked fine.
Since 2 day, I'm trying to incorporate lighting (pixel based lighting) and was successful yesterday, by having the terrain support 1 directionnal light (fake sun using the ambiant light color) and a point light (at the camera position to light the scene when it's dark. (night scenes)
Everything work fine, except that my terrain is made by object "tiles", each tile is a mesh that has the shader applied on it. And the problem is only there: The lighting seem to affect all the "land tiles" the same, I see lighting problem at the edges.
Here is a screenshot:
If you see from the screenshot, if you look at the mountain in front, the lighting seem to start to fade to dark, then start bright from the edge of the other mesh. Is there anything I could do in the shader to stop the edge problem?
Here is the current vertex shader:
- Code: Select all
varying vec3 normal;
varying vec3 position;
void main(void)
{
//gl_Position = ftransform();
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
gl_FogFragCoord = gl_Position.z;
normal = gl_Normal.xyz;
position = gl_Vertex.xyz;
}
Here is the pixel (fragment) shader:
- Code: Select all
uniform sampler2D terrainLayer0;
uniform sampler2D terrainLayer1;
uniform sampler2D terrainLayer2;
uniform sampler2D terrainLayer3;
uniform sampler2D terrainLayer4;
uniform float plateau;
uniform int terrainTextureScale;
uniform int terrainScale;
uniform bool editingTerrain;
uniform vec4 AmbientLight;
uniform vec3 mLightPos;
uniform vec3 mCamPos;
varying vec3 normal;
varying vec3 position;
void main()
{
int scale = terrainScale / 4;
if (terrainScale==1)
scale = 1;
vec2 texCoord = vec2(gl_TexCoord[0]);
vec4 tex0 = texture2D( terrainLayer0, texCoord.xy*terrainTextureScale );
vec4 tex1 = texture2D( terrainLayer1, texCoord.xy*terrainTextureScale );
vec4 tex2 = texture2D( terrainLayer2, texCoord.xy*terrainTextureScale );
vec4 tex3 = texture2D( terrainLayer3, texCoord.xy*terrainTextureScale );
tex1 = mix( tex1, tex0, min(1-normal.y,1) );
tex2 = mix( tex1, tex2, (position.y/scale));
vec4 tex10;
if(position.y >= 0)
{
tex10 = mix( tex1, tex3, (position.y/scale));
tex10 = mix( tex10, tex2, (min(1-normal.y-0.2,1)) );
}
else
{
tex10 = mix( tex1, tex2, min(1-normal.y-0.2,1));
tex10 = mix( tex10, tex0, min(1,-(position.y/scale)*10));
}
if(position.y>(plateau-2.5) && position.y<(plateau+2.5) && editingTerrain) tex10*=vec4(1,0.6,0.4,1);
// Point light with attenuation calculation
vec4 diffuse;
vec3 norm = normalize(normal);
vec3 lightVector = mLightPos - position;
float dist = length(lightVector);
float attenuation = 1.0 /( gl_LightSource[0].constantAttenuation +
gl_LightSource[0].linearAttenuation * dist +
gl_LightSource[0].quadraticAttenuation * dist * dist);
lightVector = normalize(lightVector);
float nxDir = max(0.0, dot(norm, lightVector));
// Directional light no attenuation
vec4 sunDiffuse;
vec3 sunVector = normalize(vec3(0,500,0) - position);
float sunDir = max(0.0, dot(norm, sunVector));
//Seem to cause seams with lighting
diffuse = (gl_LightSource[1].diffuse * sunDir) + (gl_LightSource[0].diffuse * nxDir * attenuation);
//diffuse = AmbientLight +(gl_LightSource[0].diffuse * nxDir * attenuation);
// Flat rendering with FOG possible
//vec4 finalColor = tex10;
// Rendering with 1 point light source
vec4 finalColor = gl_LightSource[0].ambient + (diffuse * vec4(tex10.rgb, 1.0));
float fog = (gl_Fog.end - gl_FogFragCoord) * gl_Fog.scale;
gl_FragColor = mix(gl_Fog.color,finalColor, fog);
//mix(gl_Fog.color,finalColor, fog);
}
