Jump to content
  • Advertisement
dexam234

DX11 Water Reflections in DX8

Recommended Posts

hey guys,

i have a problem over here with vertex shaders and going to need some professional help, so i thought i create a thread here.

i just decided to work this feature out for me, 2 days ago. so please dont expect me to have any experience in programming D3D.

i am trying to work this out on my own as good as i can, but i would really appreciate if someone could help me a bit or give me a push in the right direction.

i am paying for the solution, so you won't waste your time, if you decide to join me on this case.

 

but ok, lets start:

first of all, you have to know that i am editing a very old game, which is using Direct X 8. the water in this game is basically a simple plane, which is using a normal texture projected onto it.

so basically its just a plane with a texuture, that is initializing a alpha state for the texture, so you can look through the water ingame.

no shadows, no reflections, no animations yet. my first goal is to get the inverseViewMatrix working, to make at least the shadows of the world appear in the water.

so, here's the code of the actual render state of the water:

Spoiler

void LoadWaterMaterial()
{
	char buf[256];
	for (int i = 0; i < 30; ++i)
	{
		sprintf(buf, "C:/test/water/%water_1d.dds", i+1);
		WaterInstances[i].SetImagePointer((CGraphicImage *) CResourceManager::Instance().GetResourcePointer(buf));
	}
}

void RenderWater()
{
	// Saving Render State
	D3DXMATRIX TransformTextureToWater;
	
	STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE);
	STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
	STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
	STATEMANAGER.SaveRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
	STATEMANAGER.SaveRenderState(D3DRS_COLORVERTEX, TRUE);

	STATEMANAGER.SetTexture(0, WaterInstances[((ELTimer_GetMSec() / 70) % 30)].GetTexturePointer()->GetD3DTexture());

	D3DXMatrixScaling(&TransformTextureToWater, WaterTextureCoordBase, -WaterTextureCoordBase, 0.0f);
	D3DXMatrixMultiply(&TransformTextureToWater, &InverseTheView, &TransformTextureToWater);
	
	STATEMANAGER.SaveTransform(D3DTS_TEXTURE0, &TransformTextureToWater);
	STATEMANAGER.SaveVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE);

	STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
	STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
	STATEMANAGER.SaveTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
	STATEMANAGER.SaveTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
	STATEMANAGER.SaveTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
	STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
	STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
	
	STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
	STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
	STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
	STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
	

	STATEMANAGER.SetTexture(1,NULL);
	STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
	STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
      
	// Restoring Render State
    STATEMANAGER.RestoreVertexShader();
	STATEMANAGER.RestoreTransform(D3DTS_TEXTURE0);
	STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MINFILTER);
	STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MAGFILTER);
	STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MIPFILTER);
	STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSU);
	STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSV);
	STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXCOORDINDEX);
	STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS);
	
	STATEMANAGER.RestoreRenderState(D3DRS_DIFFUSEMATERIALSOURCE);
	STATEMANAGER.RestoreRenderState(D3DRS_COLORVERTEX);
	STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
	STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
	STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
}

 

So, i noticed there's already something started for inversing the view ('&InverseTheView').

in another function, for setting the Inverse View and Shadow Matrices, its declared:

	InverseTheView = pCamera->GetInverseViewMatrix();
	
	D3DXVECTOR3 v3Target = pCamera->GetTarget();

	D3DXVECTOR3 v3LightEye(v3Target.x - 1.732f * 1250.0f,
						   v3Target.y - 1250.0f,
						   v3Target.z + 2.0f * 1.732f * 1250.0f);

	D3DXMatrixLookAtRH(&m_matLightView, &v3LightEye, &v3Target, &D3DXVECTOR3(0.0f, 0.0f, 1.0f));
	DynamicShadow = InverseTheView * LightView * DynamicShadowScale;

 

okay, so far so good. i tried to add the Inversed View to my Water rendering state:

void LoadWaterMaterial()
{
	char buf[256];
	for (int i = 0; i < 30; ++i)
	{
		sprintf(buf, "C:/test/water/%water_1d.dds", i+1);
		WaterInstances[i].SetImagePointer((CGraphicImage *) CResourceManager::Instance().GetResourcePointer(buf));
	}
}

void RenderWater()
{
	// Saving Render State
	D3DXMATRIX oldView = LightView; // Old light view
	D3DXMATRIX oldLight; // old light
	D3DXPLANE plane(0.0f, 1.0f, 0.0f, 0.0f);
	D3DXMATRIX invertMatrix;
	D3DXMatrixReflect(&invertMatrix, &plane);

	oldView = ms_matWorldView;
	D3DXMATRIX vue = oldView;
	D3DXMatrixMultiply(&vue, &vue, &invertMatrix); // Inverse view
	D3DXMatrixMultiply(&LightView, &LightView, &invertMatrix); // Inverse light


	STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE);
	STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
	STATEMANAGER.SaveRenderState(D3DRS_STENCILENABLE, true);
	STATEMANAGER.SaveRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
	STATEMANAGER.SaveRenderState(D3DRS_STENCILREF, 0x1);
	STATEMANAGER.SaveRenderState(D3DRS_STENCILMASK, 0xffffffff);
	STATEMANAGER.SaveRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff);
	STATEMANAGER.SaveRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
	STATEMANAGER.SaveRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
	STATEMANAGER.SaveRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
	STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
	STATEMANAGER.SaveRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
	STATEMANAGER.SaveRenderState(D3DRS_COLORVERTEX, TRUE);
	STATEMANAGER.SaveRenderState(D3DRS_SPECULARENABLE, TRUE);
	STATEMANAGER.SaveRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);

	/// Reflection

	D3DXMATRIX reflection = vue;
	D3DXMatrixScaling(&reflection, m_fWaterTexCoordBase, -m_fWaterTexCoordBase, 0.0f);
	STATEMANAGER.SaveTransform(D3DTS_TEXTURE0, &reflection);
	LPDIRECT3DTEXTURE9 textureEau = m_WaterInstances[((ELTimer_GetMSec() / 30) % 250)].GetTexturePointer()->GetD3DTexture();

	STATEMANAGER.SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX0 | D3DFVF_TEX1);

	STATEMANAGER.SetTexture(0, textureEau);

	STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
	STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_PROJECTED);
	STATEMANAGER.SaveSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
	STATEMANAGER.SaveSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
	STATEMANAGER.SaveSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
	STATEMANAGER.SaveSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR);
	STATEMANAGER.SaveSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
	STATEMANAGER.SaveSamplerState(0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);

	STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
	STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
	STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
	STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);

	// Start of Water
	
	STATEMANAGER.SetTexture(0, WaterInstances[((ELTimer_GetMSec() / 70) % 30)].GetTexturePointer()->GetD3DTexture());

	D3DXMatrixScaling(&TransformTextureToWater, WaterTextureCoordBase, -WaterTextureCoordBase, 0.0f);
	D3DXMatrixMultiply(&TransformTextureToWater, &InverseTheView, &TransformTextureToWater);
	
	STATEMANAGER.SaveTransform(D3DTS_TEXTURE0, &TransformTextureToWater);
	STATEMANAGER.SaveVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE);

	STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
	STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
	STATEMANAGER.SaveTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
	STATEMANAGER.SaveTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
	STATEMANAGER.SaveTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
	STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
	STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
	
	STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
	STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
	STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
	STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
	

	STATEMANAGER.SetTexture(1,NULL);
	STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
	STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
      
	// Restoring Render State
    STATEMANAGER.RestoreVertexShader();
	STATEMANAGER.RestoreTransform(D3DTS_TEXTURE0);
	STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MINFILTER);
	STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MAGFILTER);
	STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MIPFILTER);
	STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSU);
	STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSV);
	STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXCOORDINDEX);
	STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS);
	
	STATEMANAGER.RestoreRenderState(D3DRS_DIFFUSEMATERIALSOURCE);
	STATEMANAGER.RestoreRenderState(D3DRS_COLORVERTEX);
	STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
	STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
	STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
}

The Output is, i would say strange. its flickering, framing between black and gray color. but its not inversing the view.

Does it have something to do, with clipping the frustum view?

 

I really do not have any clue how to work with this properly. i would really appreciate if someone here gives me the push in the right direction, as mentioned.

you'll get rewarded, too!

 

thanks for reading and best regards

Share this post


Link to post
Share on other sites
Advertisement

You really should try a graphics frame capture debugger like Pix to be sure your issue is what you think it is.

From that last snippet of code, if you comment this line out, does that fix your render from flickering?

D3DXMatrixMultiply(&TransformTextureToWater, &InverseTheView, &TransformTextureToWater);

Have you tried reversing the order of the matrix multiply?

 

 

 

Share this post


Link to post
Share on other sites

thanks for your reply. i will try it when i am at home. i managed to work a little further yesterday, but still have trouble with getting this to work.

I added D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR to the SaveTextureStageState and got a pretty accurate result.

its starting to reflect something, but gives me wrong output. i think there's something missing for projecting the scene back onto the plane (inverse).

Edited by dexam234

Share this post


Link to post
Share on other sites
On 9/10/2019 at 8:13 AM, Steve_Segreto said:

You really should try a graphics frame capture debugger like Pix

I don't think Pix or RenderDoc support DX8.

Share this post


Link to post
Share on other sites

ok, basically i managed to get some reflection, as i've posted before. so, the vector is already given, i just had to add those statements to the render part, to get this kinda "reflection". but the problem at the moment is, the water plane can't recognize the world environment. thats because there are still missing code parts. i think the right way in this case would be the cube mapping option. 

basically the water looks ingame, like something would mirror in it. there's like a white fade effect going over the plane, every few seconds. 

also i looked through the source and found some functions that are rendering the specular texture part for the game. they've been using D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR  also for this function, which causes a mirror-like effect ingame.

so basically i am on the right track, i think. but still gonna need some help, so please - if you ever worked with this DX rev. contact me! it won't be a waste of time, as mentioned before.

Link to Forsaken Online Water Shader (could be useful, also using DX8)

Edited by dexam234

Share this post


Link to post
Share on other sites
6 hours ago, bioglaze said:

I don't think Pix or RenderDoc support DX8.

It’s been almost 15 years since I last worked with D3D8, but at that time it was really trivial to convert even a large commercial program from 8 to 9, might be worth the effort for the better tools. If not you can try things like this: http://jrfonseca.blogspot.com/2008/07/tracing-d3d-applications.html?m=1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!