DGL
https://delphigl.com/forum/

Position des Schattens ist fehlerhaft
https://delphigl.com/forum/viewtopic.php?f=20&t=10586
Seite 1 von 1

Autor:  AMD [ Fr Sep 14, 2012 20:49 ]
Betreff des Beitrags:  Position des Schattens ist fehlerhaft

Hey,

meine Schatten werden nicht an der Stelle dargestellt, wo ich es eig. gerne hätte. Es ist alles ein Stück zu tief (mal grob gesagt :? ) und ich finde den Fehler einfach nicht.

Shader:
Code:
  1. uniform sampler2DShadow ShadowMap;
  2. uniform sampler2DShadow ShadowMapFar;
  3. uniform sampler2D NormalMap;
  4.  
  5. varying vec4 ShadowCoord;
  6. varying vec4 ShadowCoord2;
  7. varying vec3 vertex_normal;
  8. varying vec3 vertex_light_position;
  9.  
  10. uniform float xPixelOffset;
  11. uniform float yPixelOffset;
  12.  
  13.  
  14. float lookupNear(vec2 offSet)
  15. {
  16.     return shadow2D(ShadowMap, vec3(ShadowCoord) + vec3(offSet.x * xPixelOffset * ShadowCoord.r, offSet.y * yPixelOffset * ShadowCoord.r, 0.0)).r;
  17. }
  18.  
  19. float lookupFar(vec2 offSet)
  20. {
  21.     return shadow2D(ShadowMapFar, vec3(ShadowCoord2) + vec3(offSet.x * xPixelOffset * ShadowCoord2.r, offSet.y * yPixelOffset * ShadowCoord2.r, 0.0)).r;
  22. }
  23.  
  24.  
  25. void main()
  26. {  
  27.     float shadow=0.0, x, y;
  28.  
  29.     vec2 o = mod(floor(gl_FragCoord.xy), 2.0);
  30.     shadow = lookupNear(vec2(-1.5, 1.5) + o);
  31.     shadow += lookupNear(vec2( 0.5, 1.5) + o);
  32.     shadow += lookupNear(vec2(-1.5, -0.5) + o);
  33.     shadow += lookupNear(vec2( 0.5, -0.5) + o);
  34.     shadow = (shadow * 0.25) + 0.3;
  35.  
  36.     if (shadow >= 0.5) {
  37.         shadow = lookupFar(vec2(-1.5, 1.5) + o);
  38.         shadow += lookupFar(vec2( 0.5, 1.5) + o);
  39.         shadow += lookupFar(vec2(-1.5, -0.5) + o);
  40.         shadow += lookupFar(vec2( 0.5, -0.5) + o);
  41.         shadow = (shadow * 0.25) + 0.3;
  42.     }
  43.  
  44.     float diffuse_value = max(dot(vertex_normal, vertex_light_position), 0.0) + 0.3;
  45.     vec4 texel = texture2DProj(NormalMap, gl_TexCoord[0]);
  46.     if (diffuse_value < shadow)
  47.         texel.rgb *= diffuse_value;
  48.     else
  49.         texel.rgb *= shadow;
  50.  
  51.     gl_FragColor = texel * gl_Color;
  52. }


Vertex Shader:
Code:
  1. varying vec4 ShadowCoord;
  2. varying vec4 ShadowCoord2;
  3. varying vec3 vertex_normal;
  4. varying vec3 vertex_light_position;
  5.  
  6. void main()
  7. {
  8.     ShadowCoord = gl_TextureMatrix[1] * gl_Vertex;
  9.     ShadowCoord2 = gl_TextureMatrix[2] * gl_Vertex;
  10.     gl_TexCoord[0] = gl_MultiTexCoord0;
  11.     gl_Position = ftransform();
  12.  
  13.     vertex_normal = normalize(gl_NormalMatrix * gl_Normal);
  14.     vertex_light_position = normalize(gl_LightSource[0].position.xyz);
  15.     gl_FrontColor = gl_Color;
  16. }


Im C Code selber packe ich die Shadowmap einfach in ein FBO (Orthogonale Projektion), addiere außerdem noch Bias-Matrix * Projektionsmatrix * Viewmatrix (jeweils vom Licht) und übergebe es an den Shader.
Bias-Matrix:
0.5f, 0.0f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f

Das Problem sieht man im Anhang. Wäre über Hilfe sehr dankbar, da ich schon ewig eine Lösung suche aber ich finde einfach nichts.

Dateianhänge:
shadow.jpg [202.03 KiB]
Noch nie heruntergeladen

Autor:  Bergmann89 [ Fr Sep 14, 2012 23:26 ]
Betreff des Beitrags:  Re: Position des Schattens ist fehlerhaft

Hey,

ich hatte damals ähnliche Probleme, weiß aber leider nich mehr wie ich das gelöst hab. Kannst dich ja hier ma durch wühlen: viewtopic.php?f=20&t=10436
MfG Bergmann.

Autor:  AMD [ Do Nov 22, 2012 20:14 ]
Betreff des Beitrags:  Re: Position des Schattens ist fehlerhaft

Ich pushe die Sache einfach nochmal hoch, da ich einfach nicht den Fehler finden will :?

Autor:  Bergmann89 [ Do Nov 22, 2012 21:07 ]
Betreff des Beitrags:  Re: Position des Schattens ist fehlerhaft

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:
  1. procedure TglEngine.RenderShadow(const aFBO: TgluFrameBufferObject; const Size: Integer = 1024);
  2. var
  3.   lVec, p: TgluVector4f;
  4.   Cam: TgluCamera;
  5.  
  6.   procedure SaveTextureMatrix(const aTextureUnit: glEnum);
  7.   var
  8.     mMod, mPro, mBias: TgluMatrix4f;
  9.   begin
  10.     mBias[maAxisX] := gluVector4f(0.5, 0.0, 0.0, 0.0);
  11.     mBias[maAxisY] := gluVector4f(0.0, 0.5, 0.0, 0.0);
  12.     mBias[maAxisZ] := gluVector4f(0.0, 0.0, 0.5, 0.0);
  13.     mBias[maPos]   := gluVector4f(0.5, 0.5, 0.5, 1.0);
  14.  
  15.     glGetFloatv(GL_MODELVIEW_MATRIX, @mMod[0,0]);
  16.     glGetFloatv(GL_PROJECTION_MATRIX, @mPro[0,0]);
  17.  
  18.     glMatrixMode(GL_TEXTURE);
  19.     glActiveTexture(aTextureUnit);
  20.     glLoadIdentity;
  21.     glLoadMatrixf(@mBias[0,0]);
  22.     glMultMatrixf(@mPro[0,0]);
  23.     glMultMatrixf(@mMod[0,0]);
  24.     glActiveTexture(GL_TEXTURE0);
  25.     glMatrixMode(GL_MODELVIEW);
  26.   end;
  27.  
  28. begin
  29.   if Assigned(fScene) and Assigned(aFBO) then begin
  30.     aFBO.Bind;
  31.     glClear(GL_DEPTH_BUFFER_BIT or GL_COLOR_BUFFER_BIT);
  32.  
  33.     p := gluVector4f(0, 0, 0, 0);
  34.     Cam := fScene.ActiveCam;
  35.     if Assigned(Cam) then
  36.       p := gluMatrixInvert(Cam.Position)[maPos];
  37.     p[3] := Size/2;
  38.  
  39.     glMatrixMode(GL_PROJECTION);
  40.     glLoadIdentity;
  41.     glOrtho(-p[3], p[3], -p[3], p[3], -p[3], p[3]);
  42.     glMatrixMode(GL_MODELVIEW);
  43.     glLoadIdentity;
  44.  
  45.     lVec := fScene.GlobLight.Position;
  46.     gluLookAt(
  47.       p[0], p[1], p[2],                             //Pos
  48.       -lVec[0]+p[0], -lVec[1]+p[1], -lVec[2]+p[2],  //Center
  49.       0, 1, 0);                                     //UP-Vec
  50.  
  51.     glEnable(GL_DEPTH_TEST);
  52.     glEnable(GL_CULL_FACE);
  53.     glCullFace(GL_FRONT);
  54.     SaveTextureMatrix(GL_TEXTURE7);
  55.     RenderScene([rmShadowMapObj]);
  56.     glCullFace(GL_BACK);
  57.  
  58.     aFBO.Unbind;
  59.   end;
  60. end;    


Vertex-Shader:
Code:
  1. varying vec3 N;
  2. varying vec3 V;
  3. varying vec3 LightVec;
  4. varying vec4 ShadowPos;
  5.  
  6. void main(void)
  7. {
  8.     gl_TexCoord[0]  = gl_MultiTexCoord0;
  9.     gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;
  10.     N               = normalize(gl_NormalMatrix * gl_Normal);
  11.     V               = vec3(gl_ModelViewMatrix * gl_Vertex);
  12.     LightVec        = normalize(gl_LightSource[0].position.xyz - V * gl_LightSource[0].position.w);
  13.     ShadowPos       = gl_TextureMatrix[7] * gl_Vertex;
  14. }


Fragment-Shader:
Code:
  1. varying vec3 N;
  2. varying vec3 V;
  3. varying vec3 LightVec;
  4. varying vec4 ShadowPos;
  5.  
  6. void main(void){
  7.     vec2 TexCoord = gl_TexCoord[0].xy;
  8.     vec3 Eye = normalize(-V);
  9.  
  10.     vec3 Reflected = normalize(reflect(-LightVec, N));
  11.     vec4 IAmbient  = gl_LightSource[0].ambient  * gl_FrontMaterial.ambient;
  12.     vec4 IDiffuse  = gl_LightSource[0].diffuse  * gl_FrontMaterial.diffuse  * max(dot(/*IFDEF NORMALMAP*/normal/*ELSE*/N/*ENDIF*/, LightVec), 0.0);
  13.     vec4 ISpecular = gl_LightSource[0].specular * gl_FrontMaterial.specular * pow(max(dot(Reflected, Eye), 0.0), gl_FrontMaterial.shininess);
  14.  
  15.     float shadow = 1.0;
  16.     if (ShadowPos.w > 0.0){
  17.         vec4 NormalShadowPos = ShadowPos / ShadowPos.w;
  18.         float distanceFromLight = texture2D(uShadowMap, NormalShadowPos.xy).r;
  19.         shadow = ((NormalShadowPos.z - distanceFromLight) > 0.0 ? 0.0 : 1.0);
  20.        
  21.         float depth = texture2D(uShadowMap, NormalShadowPos.xy).r;
  22.         vec4 border = vec4(0.0, 0.0, 0.0, 0.0);
  23.         border.xy = smoothstep(0.0, 0.1, NormalShadowPos.xy);
  24.         border.zw = smoothstep(0.0, 0.1, -NormalShadowPos.xy + vec2(1.0, 1.0));
  25.         float f = border.x * border.y * border.z * border.w * smoothstep(0.0, 0.1, -depth + 1.0) * smoothstep(0.0, 0.1, depth);
  26.         shadow = shadow * f + (1.0 - f);
  27.     }  
  28.  
  29.     gl_FragColor = (IAmbient + (IDiffuse + ISpecular) * shadow);
  30. }


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.

Seite 1 von 1 Alle Zeiten sind UTC + 1 Stunde
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/