0
\$\begingroup\$

UV coordinates for shadow mapping are usually calculated from world position. I want to make it compliant with my screen space reflection (SSR) pipeline which works in view space.

Is it possible to calculate the shadow map uv coordinate from a recovered viewspace position?

Currently, I'm retrieving the viewspace position for my lighting made compliant with SSR using viewspace normals. Now I would like to use the same viewspace position to calculate the uv coordinates for shadow maps (and especially shadow cubemaps).

Alternatively, I've started to write an SSR pipeline starting with world space data, but it is slower probably because I have to use a mul(float4, matrix) to get back the world position. In view space the calculation is shorter, with a single appropriate float4 for my InvProj matrix.

\$\endgroup\$

2 Answers 2

0
\$\begingroup\$

In any form of shadow mapping, you need to multiply by a matrix (stored as a uniform variable or looked up from a buffer) representing the light's point of view and projection.

If that matrix is currently set up to accept an input in world space, and you want the input to be expressed in view space instead, then all you have to do is one extra matrix multiply outside the shader when you populate that uniform / buffer:

mat4x4 lightFromView = light.viewProjectionMatrix * camera.viewToWorldMatrix;

This concatenates the two matrices into one, so inside your shader, the single matrix multiplication that you were going to do anyway does both jobs: mapping the camera view space point to world space, and mapping that world space point to the light's projected space.

\$\endgroup\$
5
  • \$\begingroup\$ Thanks I was womdering if some divide by w was needed. \$\endgroup\$
    – philB
    Commented Sep 16, 2022 at 8:26
  • \$\begingroup\$ You'd need that for the projection step at the end, not for transitions between non-projected spaces like world and view. \$\endgroup\$
    – DMGregory
    Commented Sep 16, 2022 at 11:04
  • \$\begingroup\$ @philB If you found this answer helpful, consider voting it up &/or marking it as the accepted solution. Doing so can increase the visibility of this Q&A for others having similar problems. \$\endgroup\$
    – Pikalek
    Commented Sep 24, 2022 at 15:07
  • \$\begingroup\$ I should have mentioned I'm looking for a solution in deferrred rendering. The solution of DMG is probably for forward rendering. In my deferred rendering I have a world matrix per object. So when doing the final pass for shadows I can't have practical acces to the world matrix of the object. \$\endgroup\$
    – philB
    Commented Sep 26, 2022 at 8:30
  • \$\begingroup\$ You have misunderstood. The matrices we're dealing with here work the same in deferred and forward rendering. My answer does not ask for object world matrices. It does need the transform of the camera, which is constant for the entire frame. You pre-multiply this is into your light matrices that you're already sending to the GPU anyway before the shader even runs, so this does not demand any new information be available in the shader. \$\endgroup\$
    – DMGregory
    Commented Sep 26, 2022 at 11:07
0
\$\begingroup\$

I got it for directional shadowmaps in deferred mode. At the end as we need to perform a last multiplication with the shadow matrix projection I find it simpler for deferred rendering to start from screen space

 float4 SPos = mul(float4(uv.x*2-1, 1- uv.y*2, Depth, 1), InvSceneViewProj_LightViewProj); 
 SPos.xy=mad(SPos.xy/SPos.w, float2(0.5,-0.5),float2(0.5,0.5);
 float S = shadowmap.Sample(clamp, SPos.xy).r+bias;
 Shadow = (S*SPos.w < SPos.z)?0.5:1;//avoid divide SPos.z/SPos.w 
 

where Depth comes from the scene depth buffer and InvSceneViewProj_LightViewProj is the concatenation store in the constant buffer of Inverse(View*Proj) for the scene with ViewProj for the directional light, an adaptation of the comments

After revising this answer I finally can also directly use the position in view space. A lack of attention in my matix stteings. The SPos line becomes:

  float4 SPos = mul(PosViewSpace, InvSceneView_LightViewProj); 

I guess both calculs have the same gpu cost.

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .