This topic is 388 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi,

I have found this paper dealing with how to compute the perfect bias when dealing with shadow map.

The idea is to:

• get the texel used when sampling the shadowMap
• project the texel location back to eyeSpace (ray tracing)
• get the difference between your frament.z and the intersection with the fragment's face and your ray.

This way you have calculated the error which serve as the appropriate bias for z-fighting.

Now I am trying to implement it, but I experiment some troubles: I am using a OrthoProjectionMatrix, so i think I don't need to divide by w back and forth.

I am good until I am computing the ray intersection with the face. I have a lot of faces failing the test, and my bias is way to important.

This is my fragment shader code:

 float getBias(float depthFromTexture)
{
vec3 n = lightFragNormal.xyz;
//no need to divide by w, we got an ortho projection
//we are in NDC [-1,1] we go to [0,1]
//vec4 smTexCoord = 0.5 * shadowCoord + vec4(0.5, 0.5, 0.5, 0.0);
vec4 smTexCoord = lightProjectionMatrix * lightFragmentCoord;
smTexCoord = 0.5 * smTexCoord + vec4(0.5, 0.5, 0.5, 0.5);
//we are in [0,1] we go to texture_space [0,1]->[0,shadowMap.dimension]:[0,1024]
//get the nearest index in the shadow map, the texel corresponding to our fragment
//we use floor (125.6,237.9) -> (125,237)
vec2 delta      = vec2(xPixelOffset, yPixelOffset);
vec2 textureDim = vec2(1/xPixelOffset, 1/yPixelOffset);
vec2 index      = floor(smTexCoord.xy * textureDim);

//we get the center of the current texel, we had 0.5 to put us in the middle (125,237) -> (125.5,237.5)
//we go back to [0,1024] -> [0,1],    (125.5,237.5) -> (0.125, 0.235)
vec2 nlsGridCenter = delta*(index + vec2(0.5f, 0.5f));

// go back to NDC [0,1] -> [-1,1]
vec2 lsGridCenter = 2.0 * nlsGridCenter - vec2(1.0);

//compute lightSpace grid direction, multiply by the inverse projection matrice or
vec4 lsGridCenter4 = inverse(lightProjectionMatrix) * vec4(lsGridCenter, -frustrumNear, 0);
vec3 lsGridLineDir = vec3(normalize(lsGridCenter4));

/** Plane ray intersection **/
// Locate the potential occluder for the shading fragment
//compute the distance t we need to continue in the gridDir direction, the point is "t" far
float ls_t_hit = dot(n, lightFragmentCoord.xyz) / dot(n, lsGridLineDir);
if(ls_t_hit<=0){
return 0; // i got a lot of negativ values it shouldn t be the case
}
//compute the point p with the face
vec3  ls_hit_p = ls_t_hit * lsGridLineDir;

float intersectionDepth = lightProjectionMatrix * vec4(ls_hit_p, 1.0f).z / 2 + 0.5;
float fragmentDepth     = lightProjectionMatrix * lightFragmentCoord.z / 2 + 0.5;
float result = abs(intersectionDepth - fragmentDepth);

return result;
}

My intersectionDepth don't match my fragmentDepth, they should be really close

I am struggling with this line of code and the ray plane intersection:

vec4 lsGridCenter4 = inverse(lightProjectionMatrix) * vec4(lsGridCenter, -1.0, 0);

I need to go from NDC space to Eye space, i don't know what should be my z and w component. I am starting with a point in the shadowMap I think my z component should match the near plane so in NDC space it should be -1 but i am not sure. Same for w it's a ray so maybe 0 is a better a choice than one.

I don't know if my plane/ray intersection is wrong but from wikipedia:

$$d = { dot(Po - O) \cdot n \over dir \cdot n}$$

where:

• dir = my vector normalized direction
• Po = a point belonging to the the plane
• O = point belonging to the ray, the origin should match. in eye space the origin should be my light position -> (0,0,0) ?
• n = normal of the plane, the normal of my fragment in eyespace
Edited by Thibault Ober

1. 1
Rutin
42
2. 2
3. 3
4. 4
5. 5

• 9
• 27
• 20
• 14
• 14
• ### Forum Statistics

• Total Topics
633388
• Total Posts
3011614
• ### Who's Online (See full list)

There are no registered users currently online

×