Hey,
ich würde dir empfehlen den Teil deines Programms noch einmal neu zu implementieren. Hab ich damals auch gemacht un dann war es weg. Ich hab den Fehler bis heute nicht gefunden, aber solange es geht, is das ja auch ega^^ Als Orientierung für die Neuumsetzung kann ich dir meinen Code zur verfügung stellen. Musst ihn nur übersetzen:
Programm:
Code: procedure TglEngine.RenderShadow(const aFBO: TgluFrameBufferObject; const Size: Integer = 1024); var lVec, p: TgluVector4f; Cam: TgluCamera; procedure SaveTextureMatrix(const aTextureUnit: glEnum); var mMod, mPro, mBias: TgluMatrix4f; begin mBias[maAxisX] := gluVector4f(0.5, 0.0, 0.0, 0.0); mBias[maAxisY] := gluVector4f(0.0, 0.5, 0.0, 0.0); mBias[maAxisZ] := gluVector4f(0.0, 0.0, 0.5, 0.0); mBias[maPos] := gluVector4f(0.5, 0.5, 0.5, 1.0); glGetFloatv(GL_MODELVIEW_MATRIX, @mMod[0,0]); glGetFloatv(GL_PROJECTION_MATRIX, @mPro[0,0]); glMatrixMode(GL_TEXTURE); glActiveTexture(aTextureUnit); glLoadIdentity; glLoadMatrixf(@mBias[0,0]); glMultMatrixf(@mPro[0,0]); glMultMatrixf(@mMod[0,0]); glActiveTexture(GL_TEXTURE0); glMatrixMode(GL_MODELVIEW); end; begin if Assigned(fScene) and Assigned(aFBO) then begin aFBO.Bind; glClear(GL_DEPTH_BUFFER_BIT or GL_COLOR_BUFFER_BIT); p := gluVector4f(0, 0, 0, 0); Cam := fScene.ActiveCam; if Assigned(Cam) then p := gluMatrixInvert(Cam.Position)[maPos]; p[3] := Size/2; glMatrixMode(GL_PROJECTION); glLoadIdentity; glOrtho(-p[3], p[3], -p[3], p[3], -p[3], p[3]); glMatrixMode(GL_MODELVIEW); glLoadIdentity; lVec := fScene.GlobLight.Position; gluLookAt( p[0], p[1], p[2], //Pos -lVec[0]+p[0], -lVec[1]+p[1], -lVec[2]+p[2], //Center 0, 1, 0); //UP-Vec glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); SaveTextureMatrix(GL_TEXTURE7); RenderScene([rmShadowMapObj]); glCullFace(GL_BACK); aFBO.Unbind; end; end;
Vertex-Shader:
Code: varying vec3 N; varying vec3 V; varying vec3 LightVec; varying vec4 ShadowPos; void main(void) { gl_TexCoord[0] = gl_MultiTexCoord0; gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; N = normalize(gl_NormalMatrix * gl_Normal); V = vec3(gl_ModelViewMatrix * gl_Vertex); LightVec = normalize(gl_LightSource[0].position.xyz - V * gl_LightSource[0].position.w); ShadowPos = gl_TextureMatrix[7] * gl_Vertex; }
Fragment-Shader:
Code: varying vec3 N; varying vec3 V; varying vec3 LightVec; varying vec4 ShadowPos; void main(void){ vec2 TexCoord = gl_TexCoord[0].xy; vec3 Eye = normalize(-V); vec3 Reflected = normalize(reflect(-LightVec, N)); vec4 IAmbient = gl_LightSource[0].ambient * gl_FrontMaterial.ambient; vec4 IDiffuse = gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * max(dot(/*IFDEF NORMALMAP*/normal/*ELSE*/N/*ENDIF*/, LightVec), 0.0); vec4 ISpecular = gl_LightSource[0].specular * gl_FrontMaterial.specular * pow(max(dot(Reflected, Eye), 0.0), gl_FrontMaterial.shininess); float shadow = 1.0; if (ShadowPos.w > 0.0){ vec4 NormalShadowPos = ShadowPos / ShadowPos.w; float distanceFromLight = texture2D(uShadowMap, NormalShadowPos.xy).r; shadow = ((NormalShadowPos.z - distanceFromLight) > 0.0 ? 0.0 : 1.0); float depth = texture2D(uShadowMap, NormalShadowPos.xy).r; vec4 border = vec4(0.0, 0.0, 0.0, 0.0); border.xy = smoothstep(0.0, 0.1, NormalShadowPos.xy); border.zw = smoothstep(0.0, 0.1, -NormalShadowPos.xy + vec2(1.0, 1.0)); float f = border.x * border.y * border.z * border.w * smoothstep(0.0, 0.1, -depth + 1.0) * smoothstep(0.0, 0.1, depth); shadow = shadow * f + (1.0 - f); } gl_FragColor = (IAmbient + (IDiffuse + ISpecular) * shadow); }
Ich hab bei den Objekten aber nur die Backplanes in das FBO gerendert, damit vermeide ich eine Selbstschattierung. Das mach ich dann mit per PHONG im Shader. Sieht so besser aus, finde ich. Man hat diese unsauberen Übergänge vom hellen ins dunkle nicht.
MfG Bergmann.
|