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:
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