Skip to main content
GameDev.net gamedev.net
🔒 Locked

Texture Projection Issue

Started by Programmer101 Feb 23, 2007 at 9:08 PM 14 replies 1.2k views
Original Post
Programmer101
Programmer101
I have a texture that is a render target for a reflection and I am having a bit of a problem with projecting it to the water surface. When I use D3DTSS_TCI_CAMERASPACEPOSITION the reflection looks fine if I'm looking at a river bank, but if i look downstream or change the camera x rotation the reflection does not meet up right. Is there an easier or better way to do this? Heres my code for texturing the 2 triangle water:

g_pD3DDevice->SetTexture( 0, m_pBackgroundTexture);
	D3DXMATRIXA16 mat;
	mat._11 = 0.8f; mat._12 = 0.0f; mat._13 = 0.0f;
	mat._21 = 0.0f; mat._22 = 0.8f; mat._23 = 0.0f;
	mat._31 = 0.5f; mat._32 =-0.5f; mat._33 = 1.0f;
	mat._41 = 0.0f; mat._42 = 0.0f; mat._43 = 0.0f;

	g_pD3DDevice->SetTransform( D3DTS_TEXTURE0, &mat );
	g_pD3DDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3|D3DTTFF_PROJECTED );
	g_pD3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);



Here is an image of when it looks right Here is an image of when I adjust the camera angles: And heres one looking down stream:
Programmer101
Programmer101
Okay, I've kinda given up on this. I can't get it to work. Does anyone have any alternative or better methods for doing a reflection?
SimmerD
SimmerD
You aren't setting the other 4 parts of your matrix, the mat_14...mat_44, so they most likely contain garbage.



Programmer101
Programmer101
Oh okay. Can you tell me what the parts of the matrix are? I know how to do the D3DX functions but i'm not really sure about what the values are.
TheAdmiral
TheAdmiral
Those matrix values look pretty strange to me, but I haven't seen the bigger picture. As SimmerD suggested, you should start off by completing the matrix initialisation:
mat._11 = 0.8f; mat._12 = 0.0f; mat._13 = 0.0f; mat._14 = 0.0f;mat._21 = 0.0f; mat._22 = 0.8f; mat._23 = 0.0f; mat._24 = 0.0f;mat._31 = 0.5f; mat._32 =-0.5f; mat._33 = 1.0f; mat._34 = 0.0f;mat._41 = 0.0f; mat._42 = 0.0f; mat._43 = 0.0f; mat._44 = 0.0f;
Tell us exactly what the render-texture looks like and we may be able to be more precise.

By the by, are you using a point mip-filter for the terrain? It looks very grainy. Maybe
g_pD3DDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
would make things prettier.

Admiral
Ring3 Circus - Diary of a programmer, journal of a hacker.
Programmer101
Programmer101
Okay, IU completed the matrix but it does not seem to make a difference.

Thanks for that mip thing, it helps.

Heres my render target reflection texture:



Heres the scene:



Thanks.
TheAdmiral
TheAdmiral
It seems you took me a little more literally than I expected [rolleyes]. The pictures are helpful, but better would be if you could tell us what changes you make to the world-view-projection matrix between rendering the scene and the water texture.

It's a little difficult to tell from a static image, but the texture you posted looks kind of 'backward'. Are you remembering to swap the cull-mode for the reflected render pass?

Admiral
Ring3 Circus - Diary of a programmer, journal of a hacker.
Programmer101
Programmer101
This is all that I do before rendering to the texture:

// Save the view matrixD3DXMATRIXA16 matViewSaved;g_pD3DDevice->GetTransform( D3DTS_VIEW, &matViewSaved );// Reflect camera in X-Z plane mirrorD3DXVECTOR3 vPoint(0,2.0f*waterHeight,0);D3DXVECTOR3 vNormal(0,(2.0f*waterHeight)+1.0f,0);D3DXMATRIXA16 matView, matReflect;D3DXPLANE plane;D3DXPlaneFromPointNormal( &plane, &vPoint, &vNormal );D3DXMatrixReflect( &matReflect, &plane );D3DXMatrixMultiply( &matView, &matReflect, &matViewSaved );g_pD3DDevice->SetTransform( D3DTS_VIEW, &matView );//g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);	g_pD3DDevice->SetClipPlane( 0, plane );g_pD3DDevice->SetRenderState( D3DRS_CLIPPLANEENABLE, 0x01 );


and then to project the texture i use this:
g_pD3DDevice->SetTexture( 0, m_pBackgroundTexture);D3DXMATRIXA16 mat;mat._11 = 0.8f; mat._12 = 0.0f; mat._13 = 0.0f; mat._14 = 0.0f;mat._21 = 0.0f; mat._22 = 0.8f; mat._23 = 0.0f; mat._24 = 0.0f;mat._31 = 0.5f; mat._32 =-0.5f; mat._33 = 1.0f; mat._34 = 0.0f;mat._41 = 0.0f; mat._42 = 0.0f; mat._43 = 0.0f; mat._44 = 0.0f;g_pD3DDevice->SetTransform( D3DTS_TEXTURE0, &mat );g_pD3DDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3|D3DTTFF_PROJECTED );g_pD3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);


If you mean setting the culling to D3DCULL_CW by swapping the cull mode, I just tried that but it did not seems to have changed it but now there are a whole bunch of little triangle strips.
TheAdmiral
TheAdmiral
Okay. Your code is a mystery to me. There seem to be quite a few magic numbers thrown about. From what source are you adapting your it (especially the projection matrix)? I'm in a little deep as things stand, but I have a couple of comments anyway.

Don't disable the cull-mode switch call. Even if the results look better without it, you won't get the right results unless it's in place.

While debugging, you should disable the clipping plane. While it's necessary in release code to prevent ghost reflections in non-monotonic terrains, it's one more thing to go wrong when testing.

You may find it helpful to write some code to render the reflected texture in the corner of the screen in real-time. This way, you can be sure that the render-texture is correct.
D3DXVECTOR3 vPoint(0,2.0f*waterHeight,0);D3DXVECTOR3 vNormal(0,(2.0f*waterHeight)+1.0f,0);
- looks very suspicious to me. Why are you multiplying the water's height by two, and why does the height even feature in the normal? Provided that the water is guaranteed to lie in the xz plane, a simple constant y-axis reflection matrix will suffice:
D3DXVECTOR3 matReflect;D3DXMatrixIdentity(&matReflect);matReflect._22 = -1.0f; // Or _33, if 'z' is up.


Admiral
Ring3 Circus - Diary of a programmer, journal of a hacker.
Programmer101
Programmer101
Quote:
Original post by TheAdmiral
Okay. Your code is a mystery to me. There seem to be quite a few magic numbers thrown about. From what source are you adapting your it (especially the projection matrix)? I'm in a little deep as things stand, but I have a couple of comments anyway.


I got the matrix from the directx sample, "Bump Waves" because when I tried a making a simple matrix it didn't work.

Quote:
Don't disable the cull-mode switch call. Even if the results look better without it, you won't get the right results unless it's in place.


Okay.

Quote:
D3DXVECTOR3 vPoint(0,2.0f*waterHeight,0);D3DXVECTOR3 vNormal(0,(2.0f*waterHeight)+1.0f,0);
- looks very suspicious to me. Why are you multiplying the water's height by two

The terrain is scaled so i scale the water height too.

Quote:
, and why does the height even feature in the normal? Provided that the water is guaranteed to lie in the xz plane, a simple constant y-axis reflection matrix will suffice:

Wow, your right. I didn't even think about that. Thanks.
Programmer101
Programmer101
Thanks, that helped. My problem now seems to be that the texture is not being flipped upside down. Is there any way I can do that?

Heres an image:
Alex-R
Alex-R
I think, the matrix you're using is wrong. Try to use following:

mat._11 = 0.5f; mat._12 = 0.0f; mat._13 = 0.0f; mat._14 = 0.0f;
mat._21 = 0.0f; mat._22 =-0.5f; mat._23 = 0.0f; mat._24 = 0.0f;
mat._31 = 0.0f; mat._32 = 0.0f; mat._33 = 1.0f; mat._34 = 0.0f;
mat._41 = 0.5f; mat._42 = 0.5f; mat._43 = 0.0f; mat._44 = 1.0f;

I use this matrix in my application and it works (but i'm using shaders for water simulation). Here is the screenshot from my application:



[Edited by - Alex-R on February 26, 2007 5:14:21 AM]
ankhd
ankhd
Hello, Im new to D3D and was looking for tut's like this could you post or send me a copy of you code or if you have a web page a link to this.
thanks. looks good any way
Programmer101
Programmer101
Yeah, if you still want my code, just private message me your email address.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.