When does the perspective divide occur when using the shadow matrix to implement the planar shadow?

Started by
1 comment, last by Lucas-Li 7 years, 7 months ago

Hi,

Recently, I am reading Frank Luna's introduction to game programming with directx 11. Frankly, I am a dx noob. When reading how to implement the planar shadow using the shadow matrix(in chapter 10), I cannot go on any more :(. I cannot understand when the perspective divide occur when multiply a point by the 4x4 shadow matrix.

The following 4x4 matrix is the directional shadow matrix,

directional_shadow_matrix.png

The author said:

To use the shadow matrix, we combine it with our world matrix. However, after the world transform, the geometry has not really been projected on to the shadow plane yet because the perspective divide has not occurred yet.

if [p_x p_y p_z 1] is the point in the world space, we get s = [s_x s_y s_z n\cdot L] when multiplying it with the directional shadow matrix. This is not the projected point to the shadow plane (the shadow plane's equation in dx11 is denoted by (n, d)), but if all the components of s are divided by n\cdot L, we will get the correct projected point in the world space. The Mathematics is easy to understand, but I cannot understand the way using the shadow matrix in dx11 application.

?The code snippet in the book's demo is as follows:

?code_snippet.png

?

In the code, I cannot find when the divide occur. I need your help, thanks very much!

Advertisement

The short answer is that the perspective divide is done with the division by n dot L. While you can't see it in the code snippet you've given, it is done implicitly when the graphics pipeline converts from homogenous 4d space to normalized device coordinate space.

For a more thorough explanation, notice that your vertex shader usually returns a 4d floating point vector. You might ask, why a 4d vector rather than a 3d one? The answer is that having the extra information allows you to do convienient things to your 4d vector with matrices(it's very mathy, will skip). The importance of this 4th value is usually induced when you multiply with projection matrices(ie. your shadow matrix, the projection matrix that is implicitly generated when you call setperpective), and it is kept around.

The short answer is that the perspective divide is done with the division by n dot L. While you can't see it in the code snippet you've given, it is done implicitly when the graphics pipeline converts from homogenous 4d space to normalized device coordinate space.

For a more thorough explanation, notice that your vertex shader usually returns a 4d floating point vector. You might ask, why a 4d vector rather than a 3d one? The answer is that having the extra information allows you to do convienient things to your 4d vector with matrices(it's very mathy, will skip). The importance of this 4th value is usually induced when you multiply with projection matrices(ie. your shadow matrix, the projection matrix that is implicitly generated when you call setperpective), and it is kept around.

Thanks for your reply.

The corresponding vertex shader is the following: (in this book, it is located in the fx file)

fx_file.png

PosL(float3) is a point in local space and PosW(float3) is the point transformed to world space.

I think the value of vout.PosW( a 3D vector) is incorrect. Since the worldMatrix in the cpp code has been combined with the shadow matrix, the w componet of

mul(float4(vin.PosL, 1.0f), gWorld)

won't 1.0, n dot L instead. So

vout.PosW = mul(float4(vin.PosL, 1.0f), gWorld).xyz

is not the correct projected point. Using vout.PosW to calculate lighting in Pixel Shader will generate wrong color.

This topic is closed to new replies.

Advertisement