Here's some code excerption (beware that there are probably some hacks in there right now):
Two renderpasses:
glBindFramebuffer(GL_FRAMEBUFFER, fboShadowPass); //Rendering offscreen { //glViewport(0, 0, depthShadowMapSize, depthShadowMapSize); glClear(GL_DEPTH_BUFFER_BIT); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); //Disable color rendering, we only want to write to the Z-Buffer // Cull switching, rendering only backface, this is done to avoid self-shadowing glCullFace(GL_FRONT); if(coreManager->getStateManager()->getCurrentState()->getPerspectiveCamera()) { coreManager->getStateManager()->getCurrentState()->getPerspectiveCamera()->lookAt(siut::simd::Vec3f(580.0f, 280.0f, 680.0f), siut::simd::Vec3f(64.0f*8.0f, 100.0f, 64.0f*8.0f), siut::simd::Vec3f(0.0f, 1.0f, 0.0f)); lightView = coreManager->getStateManager()->getCurrentState()->getPerspectiveCamera()->getViewMatrix(); } displayScene(false, true, lightView); } glBindFramebuffer(GL_FRAMEBUFFER, 0); //glViewport(viewport[0], viewport[1], viewport[2], viewport[4]); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glCullFace(GL_BACK); if(coreManager->getStateManager()->getCurrentState()->getPerspectiveCamera()) coreManager->getStateManager()->getCurrentState()->getPerspectiveCamera()->setViewMatrix(prevView); displayScene(true, false, lightView);
Vertex shader for the terrain (shadow receiver)
#version 140uniform struct PointLight{ vec3 position; vec4 ambient; vec4 diffuse; vec4 specular;} PointLight1;uniform struct Material{ vec4 ambient; vec4 diffuse; vec4 specular; float shininess;} Material1;uniform struct Transform{ mat4 projectionMatrix; mat4 viewMatrix; mat4 modelMatrix; mat4 normalMatrix; mat4 textureMatrix;} Transform1;in vec3 in_Position;in vec3 in_Normal;in vec2 in_TexCoord;in vec4 in_Color;smooth out vec2 ex_TexCoord;out vec3 ex_ViewDir;out vec3 ex_LightDir;out vec4 ex_ShadowCoord;vec3 calcTangent(in vec3 normal){ vec3 tangent; vec3 c1 = cross(normal, vec3(0.0, 0.0, 1.0)); vec3 c2 = cross(normal, vec3(0.0, 1.0, 0.0)); if(length(c1) > length(c2)) { tangent = c1; } else { tangent = c2; } return tangent;}void main(void){ mat4 mvMatrix = Transform1.viewMatrix * Transform1.modelMatrix; vec3 n = normalize(Transform1.normalMatrix * vec4(in_Normal, 1.0)).xyz; vec3 t = normalize(Transform1.normalMatrix * vec4(calcTangent(in_Normal), 1.0)).xyz; vec3 b = cross(n, t); mat3 tbnMatrix = mat3(t.x, b.x, n.x, t.y, b.y, n.y, t.z, b.z, n.z); //Transform view dir to eye space (inverse of any vertex that has been transformed to eye space), then to tangent space vec4 pos = mvMatrix * vec4(in_Position, 1.0); ex_ViewDir = -(pos.xyz / pos.w); ex_ViewDir = tbnMatrix * ex_ViewDir; //Transform light dir to eye space, then to tangent space vec4 lightDir = vec4(PointLight1.position, 1.0) - pos; ex_LightDir = vec3(Transform1.viewMatrix * lightDir); ex_LightDir = tbnMatrix * ex_LightDir; ex_TexCoord = in_TexCoord; ex_ShadowCoord = Transform1.textureMatrix * vec4(in_Position, 1.0); gl_Position = Transform1.projectionMatrix * mvMatrix * vec4(in_Position, 1.0);}
Fragment shader for terrain (shadow receiver)
#version 140uniform struct PointLight{ vec3 position; vec4 ambient; vec4 diffuse; vec4 specular;} PointLight1;uniform struct Material{ vec4 ambient; vec4 diffuse; vec4 specular; float shininess;} Material1;uniform sampler2D uni_DiffuseTex;uniform sampler2D uni_NormalTex;uniform sampler2DShadow uni_ShadowMap;smooth in vec2 ex_TexCoord;in vec3 ex_ViewDir;in vec3 ex_LightDir;in vec4 ex_ShadowCoord;out vec4 out_Color;void main(void){ vec3 L = normalize(ex_LightDir); vec3 N = normalize(texture2D(uni_NormalTex, ex_TexCoord.st).xyz * 2.0 - 1.0); vec3 V = normalize(ex_ViewDir); vec3 R = normalize(- reflect(L, N)); float nDotL = max(0.0, dot(N, L)); float rDotV = max(0.0, dot(R, V)); vec4 ambient = PointLight1.ambient * Material1.ambient; vec4 diffuse = PointLight1.diffuse * Material1.diffuse * nDotL; vec4 specular = PointLight1.specular * Material1.specular * pow(rDotV, Material1.shininess); vec4 texel = texture2D(uni_DiffuseTex, ex_TexCoord.st); float gloss = 1.0; vec4 shadowCoordinateWdivide = ex_ShadowCoord / ex_ShadowCoord.w; shadowCoordinateWdivide.z += 0.0005; float distanceFromLight = textureProj(uni_ShadowMap, shadowCoordinateWdivide); float shadow = 1.0; if (ex_ShadowCoord.w > 0.0) shadow = distanceFromLight < shadowCoordinateWdivide.z ? 0.5 : 1.0 ; out_Color = (ambient + diffuse + (gloss * specular)) * texel * shadow;}