ich habe jetzt mal versucht ein simples Shadow-Mapping in GLSL Shadern auf dem iPhone zu implementieren und dabei diverse Tutorials durchforstet. Ich verwende also 2 Render-Passes... einmal um die ShadowMap zu generieren (Render to Texture) und dann einen zweiten Pass mit der vorher generierten ShadowMap als Textur. Die z-Werte werden dabei im ersten Durchgang in eine RGB8A Textur verpackt.
Die dazugehörigen FBOs, usw. scheinen soweit zu funktionieren. Das Ergebnis hat aber leider eher nichts mit einem Schatten zu tun :(
Ich habe das Gefühl nah dran zu sein... evtl. kann mir ja hier jemand helfen, wo mein Fehler liegt:
Der erste Render-Durchgang rendert in die ShadowMap-Textur aus Sicht der Lichtquelle:
ShadowMapper.vertexShader
Code: Alles auswählen
uniform mat4 u_modelMatrix;
uniform mat4 u_projectionMatrix;
attribute vec4 a_vertices;
varying vec4 position;
void main()
{
position = u_projectionMatrix * u_modelMatrix * a_vertices;
gl_Position = position;
}
Code: Alles auswählen
const highp vec4 packFactors = vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0);
const highp vec4 bitMask = vec4(0.0, 1.0/256.0, 1.0/256.0, 1.0/256.0);
varying highp vec4 position;
void main()
{
highp float normalizedDistance = position.z / position.w;
normalizedDistance = (normalizedDistance + 1.0) / 2.0;
highp vec4 packedValue = vec4(fract(packFactors*normalizedDistance));
packedValue -= packedValue.xxyz * bitMask;
gl_FragColor = packedValue;
}
Im zweiten Durchgang wird dann aus sich der "Kamera" gerendert:
SceneShader.vertexShader:
Code: Alles auswählen
uniform mat4 u_modelMatrix;
uniform mat4 u_projectionMatrix;
uniform mat4 u_lightProjectionMatrix;
attribute vec4 a_vertices;
varying vec4 v_shadowcoords;
void main()
{
// shadowcoords
v_shadowcoords = u_lightProjectionMatrix * u_modelMatrix * a_vertices;
// set position
gl_Position = u_projectionMatrix * u_modelMatrix * a_vertices;
}
SceneShader.fragmentShader:
Code: Alles auswählen
uniform sampler2D u_shadowmap;
varying highp vec4 v_shadowcoords;
const highp vec4 bitMask = vec4(1.0/(256.0*256.0*256.0), 1.0/(256.0*256.0), 1.0/256.0, 1.0);
void main()
{
highp vec4 shadowCoordinateWdivide = v_shadowcoords / v_shadowcoords.w ;
shadowCoordinateWdivide = 0.5 * shadowCoordinateWdivide + 0.5;
shadowCoordinateWdivide.z += 0.0005;
lowp vec4 shadowdepth = texture2D(u_shadowmap, shadowCoordinateWdivide.xy);
highp float distanceFromLight = dot(shadowdepth.xyzw , bitMask);
lowp float shadow = 1.0;
if (distanceFromLight < shadowCoordinateWdivide.z) shadow = 0.5;
gl_FragColor = vec4(shadow,shadow,shadow,1.0);
}
Soweit ich das testen konnte, wird die ShadowMap korrekt erzeugt, gepackt und wieder ausgepackt... irgendwas fehlt aber noch, damit ein richtiger Schatten draus wird. Im Moment ist das was man als Schatten bezeichnen könnte an völlig falscher Position auf dem Objekt, das eigentlich den Schatten werfen sollte.
Evtl. hat ja jemand einen Fingerzeig in die richtige Richtung.
Vielen Dank... Prost!