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

Rendering reflection to floor

Started by jtagge75 Mar 5, 2009 at 5:14 PM 0 replies 1.9k views
Original Post
jtagge75
jtagge75
I've figure out how to reverse the camera view to render the 'reflection' and then to also render the reflection to a render target instead of the back buffer. But what I'm not sure about is taking the RT texture and putting it on my floor. I figure I have to do a multipass on my floor but just trying to render the reflection to a quad the size of my floor the reflection does not match up. If I skip the RT and just render the reflection to the back buffer then it appears as it should. I would almost just do that route but I have textured floors I want to use. Here is the code I use for rendering my scene to the RT:

        m_rtSize = 512;

	D3DXPLANE reflectionPlane;
	D3DXVECTOR3 vPlanePoint(0.0f, 0.0f, 0.0f);
	D3DXVECTOR3 vPlaneNormal(0.0f, 1.0f, 0.0f);
	D3DXPlaneFromPointNormal(&reflectionPlane, &vPlanePoint, &vPlaneNormal);

	D3DXMATRIX mReflect;
	D3DXMatrixReflect(&mReflect, &reflectionPlane);

	// First get current view matrix
	D3DXMATRIX mOldView;
	m_d3ddev->GetDevice()->GetTransform(D3DTS_VIEW, &mOldView);

	// Then create a reflection view matrix
	D3DXMATRIX mReflectView;
	D3DXMatrixMultiply(&mReflectView, &mReflect, &mOldView);

	// Set our view transformation matrix
	m_d3ddev->GetDevice()->SetTransform(D3DTS_VIEW, &mReflectView); 
	// We also need to reverse culling order
	m_d3ddev->GetDevice()->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);

	m_d3ddev->GetDevice()->SetClipPlane(0, reflectionPlane);
	m_d3ddev->GetDevice()->SetRenderState(D3DRS_CLIPPLANEENABLE, 0x01);

	//m_d3ddev->GetDevice()->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
	m_d3ddev->GetDevice()->SetRenderState(D3DRS_LIGHTING, TRUE);

	m_d3ddev->GetDevice()->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
	m_d3ddev->GetDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
	m_d3ddev->GetDevice()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

	m_d3ddev->GetDevice()->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
	m_d3ddev->GetDevice()->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_CURRENT);
	m_d3ddev->GetDevice()->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);

	m_d3ddev->GetDevice()->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
	m_d3ddev->GetDevice()->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
	m_d3ddev->GetDevice()->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);

	D3DXMatrixPerspectiveFovLH(&matProjection, D3DX_PI/4, (float)(m_rtSize/m_rtSize), 0.1f, 2000.0f);

	m_d3ddev->GetDevice()->GetTransform(D3DTS_PROJECTION, &matOldProjection);
	m_d3ddev->GetDevice()->GetRenderTarget(0, &pBackBuffer);

	m_d3ddev->GetDevice()->SetRenderTarget(0, pRenderSurface);
   
	//clear texture
	m_d3ddev->BeginFrame(D3DCOLOR_XRGB(20, 20, 200));
	
	m_d3ddev->GetDevice()->SetTransform(D3DTS_PROJECTION, &matProjection);

	for (size_t i=0; i<m_renderList.size(); ++i)
	{
		m_d3ddev->GetDevice()->SetMaterial(&m_renderList.GetMaterial().GetMaterial());
		m_d3ddev->GetDevice()->SetTexture(0, m_renderList.GetMaterial().GetTexture());
	
		for (int j=0; j<m_renderList.GetSize(); ++j)
		{			
			m_d3ddev->GetDevice()->SetTransform(D3DTS_WORLD, &m_renderList.GetEntity(j)->GetWorldMatrix());
			m_renderList.GetEntity(j)->Render();
		}
	}

	m_d3ddev->GetDevice()->SetRenderState(D3DRS_CLIPPLANEENABLE, 0x00);
	m_d3ddev->GetDevice()->SetTransform(D3DTS_VIEW, &mOldView); 
	m_d3ddev->GetDevice()->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);

	m_d3ddev->GetDevice()->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
	m_d3ddev->GetDevice()->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);

	m_d3ddev->GetDevice()->EndScene();

	m_d3ddev->GetDevice()->SetRenderTarget(0, pBackBuffer);

	m_d3ddev->GetDevice()->SetTransform(D3DTS_PROJECTION, &matOldProjection);


I'm fairly sure I'm rendering to the RT properly but I could be wrong too.
jtagge75
jtagge75
I went to using the stencil buffer to do my reflection but I'm still having troubles with it. In this picture the bottom box is supposed to be the reflected image. But it just looks like a mirrored image that has depth instead of the reflection. I realize the grass texture isn't the best to show a reflection but it should still work.

Free Image Hosting at www.ImageShack.us

Here is the code to setup the stencil buffer and render the image to screen.

	m_d3ddev->GetDevice()->Clear(0, 0, D3DCLEAR_STENCIL, D3DCOLOR_XRGB(255,255,255), 1.0f, 0);		m_d3ddev->GetDevice()->SetRenderState(D3DRS_STENCILENABLE, true);	m_d3ddev->GetDevice()->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);	m_d3ddev->GetDevice()->SetRenderState(D3DRS_STENCILREF,	0x1);	m_d3ddev->GetDevice()->SetRenderState(D3DRS_STENCILMASK, 0xffffffff);	m_d3ddev->GetDevice()->SetRenderState(D3DRS_STENCILWRITEMASK, ffffffff);	m_d3ddev->GetDevice()->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);	m_d3ddev->GetDevice()->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);	m_d3ddev->GetDevice()->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);		//disable write to the depth and back buffer	m_d3ddev->GetDevice()->SetRenderState(D3DRS_ZWRITEENABLE, false);	m_d3ddev->GetDevice()->SetRenderState(D3DRS_ALPHABLENDENABLE, true);	m_d3ddev->GetDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);	m_d3ddev->GetDevice()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);	D3DXMATRIX mat;	D3DXMatrixIdentity(&mat);	D3DXMatrixTranslation(&mat, 0, 0, 0);	m_d3ddev->GetDevice()->SetTransform(D3DTS_WORLD, &mat);	level->Render();	m_d3ddev->GetDevice()->SetRenderState(D3DRS_ZWRITEENABLE, true);	//Setup so that we only render to the pixels that are the mirror	m_d3ddev->GetDevice()->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);	m_d3ddev->GetDevice()->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);	m_d3ddev->GetDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR);	m_d3ddev->GetDevice()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);	m_d3ddev->GetDevice()->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);	m_d3ddev->GetDevice()->Clear(0, 0, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);	D3DXPLANE reflectionPlane;	D3DXVECTOR3 vPlanePoint(0.0f, 0.0f, 0.0f);	D3DXVECTOR3 vPlaneNormal(0.0f, 1.0f, 0.0f);	D3DXPlaneFromPointNormal(&reflectionPlane, &vPlanePoint, &vPlaneNormal);	D3DXMATRIX mReflect;	D3DXMATRIX mReflectView;	D3DXMATRIX mOldView;	D3DXMatrixReflect(&mReflect, &reflectionPlane);	// First get current view matrix	m_d3ddev->GetDevice()->GetTransform(D3DTS_VIEW, &mOldView);	// Then create a reflection view matrix	D3DXMatrixMultiply(&mReflectView, &mReflect, &mOldView);	// Set our view transformation matrix	m_d3ddev->GetDevice()->SetTransform(D3DTS_VIEW, &mReflectView); 	m_d3ddev->GetDevice()->SetClipPlane(0, reflectionPlane);	m_d3ddev->GetDevice()->SetRenderState(D3DRS_CLIPPLANEENABLE, 0x01);	m_d3ddev->GetDevice()->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);	m_d3ddev->GetDevice()->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_CURRENT);	m_d3ddev->GetDevice()->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);	for (size_t i=0; i<m_renderList.size(); ++i)	{		m_d3ddev->GetDevice()->SetMaterial(&m_renderList.GetMaterial().GetMaterial());		m_d3ddev->GetDevice()->SetTexture(0, m_renderList.GetMaterial().GetTexture());			for (int j=0; j<m_renderList.GetSize(); ++j)		{						m_d3ddev->GetDevice()->SetTransform(D3DTS_WORLD, &m_renderList.GetEntity(j)->GetWorldMatrix());			m_renderList.GetEntity(j)->Render();		}	}	m_d3ddev->GetDevice()->SetRenderState(D3DRS_CLIPPLANEENABLE, 0x00);	m_d3ddev->GetDevice()->SetTransform(D3DTS_VIEW, &mOldView); 	m_d3ddev->GetDevice()->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);	m_d3ddev->GetDevice()->SetRenderState(D3DRS_ALPHABLENDENABLE, false);	m_d3ddev->GetDevice()->SetRenderState(D3DRS_STENCILENABLE, false);


'level' is a renderable entity that is passed to the function that I use to create the write area for the stencil.

Not sure what else I'm supposed to do to get a proper reflection effect going on.

Topic Locked

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

Sign in to reply to this topic.