How to setup paraboloid's view matrix in dual paraboloid shadow map?

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

Recommended Posts

I am trying to implement the dual paraboloid base on this site http://gamedevelop.e...dow-mapping.htm

I am using a point light located at the origin, so how do we setup the paraboloid's view matrix for the front and back map?

Instead of using d0(0, 0, -1) and d1(0, 0, 1) to set value for direction variable in shader source code like

pos.z *= direction //for front and back map

I use it to setup the view matrix like

LighPostion + d0 (for front map)
LighPostion + d1 (for back map)

 D3DXVECTOR3 temp = D3DXVECTOR3( 0.0f, 0.0, fDirection ); //fDirection = -1 for the back map, 1 for the front map D3DXVECTOR3 lightTargetW = vLightPos + temp; D3DXVECTOR3 lightUpW(0.0f, 1.0f, 0.0f); D3DXMatrixLookAtLH(&mDPView, &vLightPos, &lightTargetW, &lightUpW); 

I did that to setup the LookAt point being used for paraboloid's view matrix. Then before rendering the scene, I create shadow maps for front and back paraboloid by modifying view matrix for each map. But how can I modify it when I render the scene?

Share on other sites
If I understood you correctly: You can't change the position until the process. You can place the light and the matrix arbitrary,
but you have to render the scene according to your light position and shadow maps.
What you have done so far looks right.

Share on other sites
Zero01, thank for replying but I do not think I am clear about your answer, so what about the final view matrix for the second pass, rendering the scene base on shadow map textures. Let's me give you all information about my situation

First, I have a floor located at from -10 to 10 on xz plane, -8 at y axis.
Second, I have a sphere located at (-2, -5, -2) and the point light is at the origin

Like I said above, I modified the view matrix in the first pass, creating shadow maps ( LightPosition + d0 / d1 ). And in the second pass, I do not know how to set up the view matrix, so I tried to set LookAt point is (0, -1, 0). Then everything is black

This is the shader source code in the second pass:

 DP_OutputVS RenderShadowMapVS( DP_InputVS In ) { DP_OutputVS output; output.pos = mul( float4(In.pos, 1), g_mWVP ); output.posWorld = mul( float4(In.pos, 1), g_mWorld).xyz; output.normal = mul( float4(In.normal, 0), g_mWorld ).xyz; output.light = g_vLightPos - output.posWorld; return output; } float4 RenderShadowMapPS( DP_OutputVS In ) : COLOR { float3 color; float4 vPosDP = mul( float4(In.posWorld, 1), g_mDPView ); float fLength = length( vPosDP.xyz ); vPosDP /= fLength; float fSceneDepth = ( fLength - g_fNear ) / ( g_fFar - g_fNear ); float fDPDepthBack; float fDPDepthFront; float fDPDepth; if ( vPosDP.z >= 0.0f ) { //Project to front map float2 vTexFront; float posX_Front = vPosDP.x / ( 1.0f + vPosDP.z ); float posY_Front = vPosDP.y / ( 1.0f + vPosDP.z ); vTexFront.x = posX_Front * 0.5f + 0.5f; vTexFront.y = 1.0 - ( posY_Front * 0.5f + 0.5f ); fDPDepth = tex2D( DPFrontSampler, vTexFront ); } else { //Project to back map float2 vTexBack; float posX_Back = vPosDP.x / ( 1.0f - vPosDP.z ); float posY_Back = vPosDP.y / ( 1.0f - vPosDP.z ); vTexBack.x = posX_Back * 0.5f + 0.5f; vTexBack.y = 1.0 - ( posY_Back * 0.5f + 0.5f ); fDPDepth = tex2D( DPBackSampler, vTexBack ); } //Lighting and shadow float3 vNormal = normalize( In.normal ); float3 vLight = normalize( In.light ); float diffuse = saturate( dot(vLight, vNormal) ) * g_LightDiffuse * g_MaterialDiffuse; float ambient = g_LightAmbient * g_MaterialAmbient; if ( (fDPDepth + SHADOW_EPSILON) < fSceneDepth ) { color = g_mColor * ambient; } else { color = g_mColor * ( ambient + diffuse ); } return float4(color, 1); }

And this is the C++/DirectX source code, of course I've already set the effect parameters

 D3DXMATRIX lightView; D3DXVECTOR3 lightPosW = vLightPos; D3DXVECTOR3 lightTargetW(0.0f, -1.0f, 0.0f); D3DXVECTOR3 lightUpW(0.0f, 1.0f, 0.0f); D3DXMatrixLookAtLH(&mDPView, &lightPosW, &lightTargetW, &lightUpW); for(UINT i = 0; i < cPass; i++) { V( g_pEffect9->BeginPass( 0 ) ); V( g_pEffect9->SetMatrix( mhWVP , &(mFloorWorld * mView * mProj) ) ); V( g_pEffect9->SetMatrix( mhWorld, &mFloorWorld ) ); D3DXVECTOR4 vColor = D3DXVECTOR4( 1.0f, 1.0f, 0.0f, 1.0f ); g_pEffect9->SetVector(mhEmissive, &vColor); V( g_pEffect9->CommitChanges() ); pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 ); vColor = D3DXVECTOR4( 1.0f, 0.0f, 0.0f, 1.0f ); V( g_pEffect9->SetVector(mhEmissive, &vColor) ); V( g_pEffect9->SetMatrix( mhWVP, &(mSphereWorld * mView * mProj) ) ); V( g_pEffect9->SetMatrix( mhWorld, &mSphereWorld ) ); V( g_pEffect9->CommitChanges() ); V( g_pSphere->DrawSubset(0) ); V( g_pEffect9->EndPass() ); } V( g_pEffect9->End() ); 

Share on other sites
Hidden
I think I've already figured out that the 2 paraboloids located at the origin, then we set up the view matrix is position(0,0,0) lookAt(0,0,5) as building the shadow maps. Next, in the second pass, we need to use the view matrix of the light, completely different with the paraboloid's matrix 'cause the light can locate anywhere we set.

You're only partially right.

The most important steps:

- render scene from light's perspective (pos. dir: g_fDir = 1)

- disable back-face culling

- render scene from light's perspective (neg. dir: g_fDir = -1)

b.) render final scene

- set scene render target and the shadow maps

- render from cam (view matrix)

that's it!

Your shadow maps have to be placed at the final light position.

Share on other sites
Zero01, thanks for helping me but when I tried to render the scene but everything is in shadow , so I checked the shadows created in the first pass. The following images is the front and back shadow maps

the whole screen

Front
Back

The code for setting up the light's view matrix
 D3DXVECTOR3 lightPosW = vLightPos; D3DXVECTOR3 lightTargetW(0, 0, 0); D3DXVECTOR3 lightUpW(0.0f, 1.0f, 0.0f); D3DXMatrixLookAtLH(&mLightView, &lightPosW, &lightTargetW, &lightUpW); 

The shader for the first pass:
 DPDepthInput_PS BuildShadowMapVS( DPDepthInput_VS In ) { DPDepthInput_PS output; output.pos = mul( float4(In.pos, 1), g_mDPWorldView ); //Project to DP space output.pos /= output.pos.w; output.pos.z *= g_fDir; float fLength = length( output.pos.xyz ); output.pos /= fLength; output.clipDepth = output.pos.z; //calculate the normal vector at the intersection point output.pos.x /= (output.pos.z + 1.0f); output.pos.y /= (output.pos.z + 1.0f); output.pos.z = ( fLength - g_fNear ) / ( g_fFar - g_fNear ); output.pos.w = 1.0f; output.depth = output.pos.z; return output; } float4 BuildShadowMapPS( DPDepthInput_PS In ) : COLOR { clip( In.clipDepth ); return In.depth; //skip w because w = 1 } 

light vLightPos( 0.0f, 8.0f, 3.0f );
the sphere at (-2, 2, -2)
//Triangle's vertices

MYVERTEX VertTriangle[3] = {
{ D3DXVECTOR3(-3.0f, 0.0f, 5.0f), D3DXVECTOR3(0.0f, 0.0f, 1.0f) },
{ D3DXVECTOR3(0.0f, 3.0f, 7.0f), D3DXVECTOR3(0.0f, .0f, 1.0f) },
{ D3DXVECTOR3(3.0f, 0.0f, 5.0f), D3DXVECTOR3(0.0f, 0.0f, 1.0f) }
};

Maybe there's something wrong with shadow maps because the sphere and triangle is closer to the light than the floor, but the floor's color is lighter in the sense that closer

Share on other sites
The code is correct but there is definitly something wrong with your shadow maps -> are you sure that you use the above shader? -> there is no paraboloid projection on your shadow map! Maybe the effect params are wrong? and which format to you use? (R32F is recommended)

Share on other sites
For the start, try to use highly tesselated geometry, so you would see does it actually looks like a paraboloid mappping or not.

Sorry, I didn't checked your code, too tired right now. Try using mine as a referrence. "uniform float direction" input value to vertex shader set's which part of hemisphere you need to render.
I'm using dx9 and input matrix is just a simple inverse of position\rotation\scale matrix of my light, it just sets it's position in world space and orientation.

ParBasis - inverse of position\rotation\scale matrix of my light
object_to_world - world matrix of geometry to render

 // Vertex shader in_sm_ps par_sm_vs(in_vs input, uniform float direction) { in_sm_ps output; float4 toWorld = mul(float4(input.pos.xyz, 1), object_to_world); float4 clip_pos = mul(toWorld, ParBasis); clip_pos = clip_pos / clip_pos.w; clip_pos.z = clip_pos.z * direction; float L = length( clip_pos.xyz ); clip_pos = clip_pos / L; output.z_value = clip_pos.z; clip_pos.z = clip_pos.z + 1; clip_pos.xy = clip_pos.xy / clip_pos.z; clip_pos.xy = clamp(clip_pos.xy, -1, 1); //trying to avoid overlaps clip_pos.xy += sector.xy; clip_pos.xy *= 1.f/4.f; clip_pos.z = L / 1000; clip_pos.w = 1; output.clip_pos = clip_pos; output.vertex_to_light = toWorld.xyz - light_position; return output; } //--------------------------------------------------------------- float4 par_sm_ps(in_sm_ps input) : COLOR { clip(input.z_value + 0.2); float d = length(input.vertex_to_light); float2 moments = GetMoments(d); return float4(moments, 1, 1); } //--------------------------------------------------------------- // Techniques technique sm_parabaloid_render { //Tech #2 pass P0 { ZEnable = TRUE; ZWriteEnable = TRUE; CullMode = CCW; VertexShader = compile vs_3_0 par_sm_vs(1); PixelShader = compile ps_3_0 par_sm_ps(); } } 

Share on other sites
[font="arial, verdana, tahoma, sans-serif"]Thank Viik, I am really appreciate it and I am also using dx9 but could you upload the complete project for me to reference or send to my email aiuvoanh@nate.com?. Because I want to do it on my own

Thank Zero01, now I am using R32F but it's slower [/font]

The front and back shadow map are the same

The final screen

The shader with a slightly difference
 DPDepthInput_PS BuildShadowMapVS( DPDepthInput_VS In ) { DPDepthInput_PS output; output.pos = mul( float4(In.pos, 1), g_mDPWorldView ); //Project to DP space output.pos /= output.pos.w; //output.pos.z *= g_fDir; float fLength = length( output.pos.xyz ); output.pos /= fLength; output.clipDepth = output.pos.z; //calculate the normal vector at the intersection point output.pos.x /= (output.pos.z + 1.0f); output.pos.y /= (output.pos.z + 1.0f); output.pos.z = ( fLength - g_fNear ) / ( g_fFar - g_fNear ); output.pos.w = 1.0f; output.depth = output.pos.z; return output; } float4 BuildShadowMapPS( DPDepthInput_PS In ) : COLOR { clip( In.clipDepth ); return In.depth; //skip w because w = 1 } 

the code for setting up parameters
 void setupLightView( float fDirection ) { D3DXVECTOR3 lightPosW = vLightPos; D3DXVECTOR3 lightTargetW( 0.0f, 0.0f, 0.0f ); D3DXVECTOR3 lightUpW(0.0f, 1.0f, 0.0f); D3DXMatrixLookAtLH(&mLightView, &lightPosW, &lightTargetW, &lightUpW); HRESULT hr; V( g_pEffect9->SetFloat( mhDirection, fDirection ) ); V( g_pEffect9->SetFloat( mhFar, 30.0f ) ); V( g_pEffect9->SetFloat( mhNear, 0.10f ) ); } 

I comment the following line in shader, otherwise the whole screen will be black in the second pass . One more thing, when I comment it, the front and shadow map is the same
output.pos.z *= g_fDir

It's about the shadow, if you take a look at the final screen, you will see that there's something wrong with the floor's border and the sphere's shadow

Share on other sites
1. The R32F format is slower, but more accurate!
2. You shouldn't comment out the g_fDir param!

If you want, send me your code (mail address in my profile) and I will fix it!

1. 1
2. 2
3. 3
Rutin
15
4. 4
khawk
14
5. 5
frob
12

• 9
• 11
• 11
• 23
• 12
• Forum Statistics

• Total Topics
633662
• Total Posts
3013228
×