Advertisement

[dx9] Projecting decal texture with volume mesh

Started by May 13, 2012 03:53 PM
0 comments, last by belfegor 12 years, 9 months ago
I need help as i am not be able to do right math to project decal texture onto my terrain.

Some blood decal texture:
decaltex.jpg

Based on tips from user mikaelc from this topic about lights mesh volumes (got this working thanks!) i thought to use similar technique for decals.

Debug view of [s]light[/s] decal volume mesh (one sphere):
decalsd.jpg

but when i try to "project" my texture i got this:
decls.jpg
(i placed multiple spheres to be able to see decal placement)

Veretex shader:

#pragma pack_matrix(row_major)

float4x4 WorldViewProjection : register(c0);
float4 ScreenParams : register(c4);// x - screen w; y - screen h; z - 1 / (2 *target/screen w); w - 1 / (2 *target/screen h)

struct A2V
{
float3 Position : POSITION;
};

struct V2P
{
float4 Position : POSITION;
float4 TexCoord : TEXCOORD0;
};

void main(in A2V IN, out V2P OUT)
{
float4 oPosition = mul(float4(IN.Position, 1.0f), WorldViewProjection);
OUT.Position = oPosition;
oPosition.x = ((oPosition.x + oPosition.w) * ScreenParams.x + oPosition.w) * ScreenParams.z;
oPosition.y = ((oPosition.w - oPosition.y) * ScreenParams.y + oPosition.w) * ScreenParams.w;
OUT.TexCoord = oPosition;
}



pixel shader (wrong):

#pragma pack_matrix(row_major)

sampler position_samp : register(s0);
sampler decal_samp : register(s1);

float4x4 ViewInv : register(c0);

struct V2P
{
float4 Position : POSITION;
float4 TexCoord : TEXCOORD0;
};

struct P2A
{
float4 Color : COLOR0;
};

void main(in V2P IN, out P2A OUT, in float2 svPos : VPOS)
{
float3 posVS = tex2Dproj(position_samp, IN.TexCoord).xyz;
float4 coord = mul(float4(posVS.xyz, 1.0f), ViewInv);
OUT.Color = tex2Dproj(decal_samp, coord);
}



How to get correct tex. coords for decal textures?

Thanks for your time.
I got this working, well sort of working, its not perfect so question still stands.
I used approach same as for shadow mapping, setting up decal projection "camera" matrices:

D3DXVECTOR2 decTexDim(256.0f, 256.0f);
D3DXVECTOR3 decCamPos, decCamUp, decCamTarget, decNrm;
decCamPos = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
decCamUp = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
decCamTarget = (*it).pos;
D3DXMATRIX decCamView, decCamProj, camViewInv;
float OffsetX = 0.5f + (0.5f / decTexDim.x);
float OffsetY = 0.5f + (0.5f / decTexDim.y);
D3DXMATRIX texScaleBiasMat(
0.5f, 0.0f, 0.0f, 0.0f,
0.0f, -0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
OffsetX, OffsetY, 0.0f, 1.0f );
D3DXMatrixPerspectiveFovLH(&decCamProj, D3DX_PI / 2.0f, decTexDim.x / decTexDim.y, 0.1f, volRadius * 2.0f);
D3DXVec3Normalize(&decNrm, &(*it).nrm);
decCamPos = decCamTarget + (decNrm * volRadius);
D3DXMatrixLookAtLH(&decCamView, &decCamPos, &decCamTarget, &decCamUp);
D3DXMatrixInverse(&camViewInv, 0, &cam->View);

D3DXMATRIX decCamViewProjScaleBias = decCamView * decCamProj * texScaleBiasMat;
D3DXMATRIX matViewToDecalViewProj = camViewInv * decCamViewProjScaleBias;

d3d9device->SetPixelShaderConstantF(0, matViewToDecalViewProj, 4);


Where 'it' is iterator to:

// Used to setup decal "camera" matrices
struct Decal
{
D3DXVECTOR3 pos;// point of intersection on terrain
D3DXVECTOR3 nrm;// triangle normal at intersection
};
std::vector<Decal> v;


Is there some other way?

This topic is closed to new replies.

Advertisement