c++ - DirectX Converting Pixel World Position to Shadow Map Position Gives Weird, Tiled Results -


i've been trying time screen-space pixel (provided deferred hlsl shader) convert light space. results have been surprising me light rendering seems tiling depth buffer.

importantly, scene camera (or eye) , light being rendered start in same position.

first, extract world position of pixel using code below:

float3 eye = eye; float4 position = {     in.texcoord.x * 2 - 1,     (1 - in.texcoord.y) * 2 - 1,     zbuffer.r,     1 }; float4 hposition = mul(position, eyeviewprojectioninverse); position = float4(hposition.xyz / hposition.w, hposition.w); float3 eyedirection = normalize(eye - position.xyz); 

the result seems correct rendering xyz position rgb respectively yields (apparently correct) result:

correctly rendered xyz

the red component seems correctly outputting x moves right, , blue shows z moving forward. y factor looks correct ground below y axis.

next (and sure i'm not going crazy), decided output original depth buffer. keep depth buffer in texture2d called depthmap passed shader input. in case, however, try undo pixel transformation offsetting proper position , multiplying eye's view-projection matrix:

float4 cpos = mul(position, eyeviewprojection); cpos.xyz = cpos.xyz / cpos.w; cpos.x = cpos.x * 0.5f + 0.5f; cpos.y = 1 - (cpos.y * 0.5f + 0.5f); float camera_depth = pow(depthmap.sample(sampler, cpos.xy).r, 100); // power 100 visualize map since scales tiny return float4(camera_depth, camera_depth, camera_depth, 1); 

this yields correct looking result (though i'm not 100% sure z value). note i've made results exponential better visualize depth information (this not done when attempting live comparisons):

reinterpreting xyz zbuffer space

so theoretically, can use same code convert pixel world position light space multiplying light's view-projection matrix. correct? here's tried:

float4 lpos = mul(position, shadowlightviewprojection[0]); lpos.xyz = lpos.xyz / lpos.w; lpos.x = lpos.x * 0.5f + 0.5f; lpos.y = 1 - (lpos.y * 0.5f + 0.5f); float shadow_map_depth = pow(shadowlightmap[0].sample(sampler, lpos.xy).r, 100); // power 100 visualize map since scales tiny return float4(shadow_map_depth, shadow_map_depth, shadow_map_depth, 1); 

and here's result:

broken light space

and show better how it's mapping world:

broken light space #2

i don't understand going on here. seems might have projection matrix, i'm not math know sure happening. it's not width/height of light map i've tried multiple map sizes , projection matrix calculated using fov , aspect ratios never inputing width/height ever.

finally, here's c++ code showing how perspective matrix (used both eye , light) calculated:

    const auto ys = std::tan((t)1.57079632679f - (fov / (t)2.0));     const auto xs = ys / aspect;     const auto& zf = view_far;     const auto& zn = view_near;     const auto zfn = zf - zn;      row1(xs, 0, 0, 0);     row2(0, ys, 0, 0);     row3(0, 0, zf / zfn, 1);     row4(0, 0, -zn * zf / zfn, 0);     return *this; 

i'm @ loss here. guidance or recommendations appreciated!

edit - forgot mention tiled image upside down if y flip broke it. that's strange me it's required eye texture space correctly.

i did tweaking , fixed things here , there. ultimately, biggest issue unexpectedly transposed matrix. it's bit complicated how matrix got transposed, that's why things flipped. changed d32 depth buffers (though i'm not sure helped any) , made sure positions divided w affected component (including w).

so code this: hposition.xyz = hposition.xyz / hposition.w became this: hposition = hposition / hposition.w

after tweaking, it's starting more shadow map.

oh , transposed matrix viewprojection of light.


Comments