Quantcast
Channel: GameDev.net
Viewing all articles
Browse latest Browse all 17560

Direct9x Water Reflection in HLSL

$
0
0

Hello everybody,

I work on water reflection on my project. And I have some problems with HLSL code.

My water work with many primitives and work like a large plane with coordinates.

I cannot found the right way to make an mirror of the view and use it with my water rendering.
 

D3DXMATRIX matTextTransformWater // Represent the texture matrix of my water.

float m_fWaterTextCoordBase // Represent the size of the texture.

LPDIRECT3DTEXTURE9 water // Represent the texture of my water.

Part of Texture size calculation:

D3DXMatrixScaling(&matTexTransformWater, m_fWaterTexCoordBase, -m_fWaterTexCoordBase, 0.0f);
D3DXMatrixMultiply(&matTexTransformWater, &m_matViewInverse, &matTexTransformWater);



Part of setting texture with matrix:
 

STATEMANAGER.SetTexture(0, water);

STATEMANAGER.SaveTransform(D3DTS_TEXTURE0, &matTexTransformWater);


Part of get Reflection Texture map:

 

void CMapOutdoor::MapTextureReflection()
{
	D3DXMATRIX oldView; // Ancienne vue.
	D3DXMATRIX oldWorld; // Ancien monde.
	D3DXMATRIX oldProj; // Ancienne projection.

	STATEMANAGER.GetTransform(D3DTS_VIEW, &oldView); // récupération de la vue.
	STATEMANAGER.GetTransform(D3DTS_WORLD, &oldWorld); // récupération du monde.
	STATEMANAGER.GetTransform(D3DTS_PROJECTION, &oldProj); // récupération de la projection.

	STATEMANAGER.SetTransform(D3DTS_VIEW, &ReflectionView());


	LPDIRECT3DSURFACE9 pBackBuffer;



	if (SUCCEEDED(STATEMANAGER.m_lpD3DDev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer)))
	{

		D3DVIEWPORT9 viewPort;
		STATEMANAGER.m_lpD3DDev->GetViewport(&viewPort);
		D3DXCreateTexture(STATEMANAGER.m_lpD3DDev, viewPort.Width, viewPort.Height, D3DX_DEFAULT, D3DUSAGE_RENDERTARGET,
			D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &TextureReflectionMap);

		LPDIRECT3DSURFACE9 pTexSurface;
		TextureReflectionMap->GetSurfaceLevel(0, &pTexSurface);
		STATEMANAGER.m_lpD3DDev->StretchRect(pBackBuffer, NULL, pTexSurface, NULL, D3DTEXF_NONE);
		pBackBuffer->Release();
		pTexSurface->Release();

	}

	STATEMANAGER.SetTransform(D3DTS_VIEW, &oldView);
	STATEMANAGER.SetTransform(D3DTS_WORLD, &oldWorld);
	STATEMANAGER.SetTransform(D3DTS_PROJECTION, &oldProj);
}

D3DXMATRIX CMapOutdoor::ReflectedCameraPositionMatrix()
{
	D3DXMATRIX CameraReflected;
	D3DXMatrixTranslation(&CameraReflected, ReflectedCameraPositionVector3().x, ReflectedCameraPositionVector3().y, ReflectedCameraPositionVector3().z);

	return CameraReflected;
}

D3DXVECTOR3 CMapOutdoor::ReflectedCameraPositionVector3()
{
	D3DXVECTOR3 CameraReflectedPosition;

	CCamera * pCurrentCamera = CCameraManager::Instance().GetCurrentCamera();
	CameraReflectedPosition = pCurrentCamera->GetTarget();
	CameraReflectedPosition.z = -CameraReflectedPosition.z;

	return CameraReflectedPosition;
}

D3DXMATRIX CMapOutdoor::ReflectionView()
{
	CCamera * pCurrentCamera = CCameraManager::Instance().GetCurrentCamera();


	D3DXVECTOR3 CameraReflectedPosition;
	D3DXMATRIX ReflectionMatrix;

	CameraReflectedPosition = ReflectedCameraPositionVector3();

	D3DXVECTOR3 CameraLookTowards(pCurrentCamera->GetTarget().x, pCurrentCamera->GetTarget().y, pCurrentCamera->GetTarget().z);
	CameraLookTowards += CameraReflectedPosition;

	D3DXVECTOR3 vectorUP(0.0f, 0.0f, 1.0f);
	//D3DXMatrixAffineTransformation(&ReflectionMatrix, &CameraLookTowards, &CameraReflectedPosition, &vectorUP);
	D3DXMatrixLookAtLH(&ReflectionMatrix, &CameraLookTowards, &CameraReflectedPosition, &vectorUP);
	return ReflectionMatrix;
}


 

Part of HLSL code:

float4x4 World;
float4x4 View;
float4x4 Projection;
float3 CameraPosition;
float4x4 ReflectionView;
float ViewPortWidth;
float ViewPortHeight;
texture ReflectionMap;

sampler2D ReflectionSampler = sampler_state
{
    texture = <ReflectionMap>;
    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Linear;
    AddressU = Clamp;
    AddressV = Clamp;
};

// TODO: add effect parameters here.
float2 postProjToScreen(float4 position)
{
  float2 screenPos = position.xy / position.w;
  return 0.5f * (float2(screenPos.x, -screenPos.y) + 1);
}

float2 halfPixel()
{
  return 0.5f / float2(ViewPortWidth, ViewPortHeight);
}



struct VertexShaderInput
{
    float4 Position : POSITION0;
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float4 ReflectionPosition : TEXCOORD1;

    // TODO: add vertex shader outputs such as colors and texture
    // coordinates here. These values will automatically be interpolated
    // over the triangle, and provided as input to your pixel shader.
};

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
    VertexShaderOutput output;

    float4 worldPosition = mul(input.Position, World);
    float4 viewPosition = mul(worldPosition, View);
    output.Position = mul(viewPosition, Projection);

    // TODO: add your vertex shader code here.
    float4x4 Reflected = mul(World, mul(ReflectionView, Projection));
    output.ReflectionPosition = mul(input.Position, Reflected);

    return output;
}

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
    // TODO: add your pixel shader code here.

    //float2 ReflectionUV = float2(input.ReflectionPosition.x/input.ReflectionPosition.w/2.0f + 0.5f, input.ReflectionPosition.y/input.ReflectionPosition.w/2.0f + 0.5f);
    float2 ReflectionUV = postProjToScreen(input.ReflectionPosition) + halfPixel();
    float3 Reflection = tex2D(ReflectionSampler, ReflectionUV);

    return float4(Reflection, 1);
}



technique Technique1
{
    pass Pass1
    {
        // TODO: set renderstates here.

        VertexShader = compile vs_2_0 VertexShaderFunction();
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}

Part of Rendering primitive with HLSL initialization:

	if (EffetEau) // If water hlsl file is correctly readed.
	{
		// Variable
		D3DVIEWPORT9 viewport;
		D3DXMATRIX oldWorld;
		D3DXMATRIX oldView;
		D3DXMATRIX oldProj;
		STATEMANAGER.GetTransform(D3DTS_WORLD, &oldWorld);
		STATEMANAGER.GetTransform(D3DTS_VIEW, &oldView);
		STATEMANAGER.GetTransform(D3DTS_PROJECTION, &oldProj);


		D3DXMATRIX invertWorld;
		D3DXMATRIX transposeWorld;

		D3DXMatrixInverse(&invertWorld, 0, &oldWorld);
		D3DXMatrixTranspose(&transposeWorld, &invertWorld);
		STATEMANAGER.m_lpD3DDev->GetViewport(&viewport);


		// Handle de l'effet;
		D3DXHANDLE Technique = matEauEffet->GetTechniqueByName("Technique1");
		D3DXHANDLE World = matEauEffet->GetParameterByName(0, "World");
		D3DXHANDLE View = matEauEffet->GetParameterByName(0, "View");
		D3DXHANDLE Proj = matEauEffet->GetParameterByName(0, "Projection");
		D3DXHANDLE CameraPosition = matEauEffet->GetParameterByName(0, "CameraPosition");
		D3DXHANDLE ReflectionView = matEauEffet->GetParameterByName(0, "ReflectionView");
		D3DXHANDLE ViewPortWidth = matEauEffet->GetParameterByName(0, "ViewPortWidth");
		D3DXHANDLE ViewPortHeight = matEauEffet->GetParameterByName(0, "ViewPortHeight");
		D3DXHANDLE ReflectionMap = matEauEffet->GetParameterByName(0, "ReflectionMap");


		HRESULT hr;
		hr = matEauEffet->SetMatrix(View, &oldView);
		if (FAILED(hr))
		{
			TraceError("Erreur Effet View");
		}
		hr = matEauEffet->SetMatrix(World, &oldWorld);
		if (FAILED(hr))
		{
			TraceError("Erreur Effet World");
		}
		hr = matEauEffet->SetMatrix(Proj, &oldProj);
		if (FAILED(hr))
		{
			TraceError("Erreur Effet Proj");
		}


		hr = matEauEffet->SetValue(CameraPosition, &CCameraManager::Instance().GetCurrentCamera()->GetView(), sizeof(D3DXVECTOR3));
		if (FAILED(hr))
		{
			TraceError("Erreur Effet CameraPosition");
		}

		hr = matEauEffet->SetMatrix(ReflectionView, &invertWorld);
		if (FAILED(hr))
		{
			TraceError("Erreur Effet ReflectionView");
		}
		hr = matEauEffet->SetFloat(ViewPortWidth, viewport.Width);
		if (FAILED(hr))
		{
			TraceError("Erreur Effet Viewport Height");
		}
		hr = matEauEffet->SetFloat(ViewPortHeight, viewport.Height);
		if (FAILED(hr))
		{
			TraceError("Erreur Effet Viewport Width");
		}
		hr = matEauEffet->SetTexture(ReflectionMap, TextureReflectionMap);
		if (FAILED(hr))
		{
			TraceError("Erreur Effet Reflection Texture");
		}
		hr = matEauEffet->SetTechnique(Technique);
		if (FAILED(hr))
		{
			TraceError("Erreur Effet Technique");
		}
		UINT cPasses;
		matEauEffet->Begin(&cPasses, 0);
		for (int k = 0; k < cPasses; k++)
		{
			matEauEffet->BeginPass(k);
			matEauEffet->CommitChanges();
			STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLELIST, 0, uPriCount);

			matEauEffet->EndPass();
		}
		matEauEffet->End();
	}
	else
	{
		STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLELIST, 0, uPriCount);
	}

The result:

resultat.png


I hope you can help me, thank you in advance.


Viewing all articles
Browse latest Browse all 17560

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>