Archived

This topic is now archived and is closed to further replies.

NeoKenobi

HLSL bumpmapping issue

Recommended Posts

I''m relatively new to DX, but I''ve been coding with OpenGL for quite some time now. I''m trying to port my bsp level renderer to DirectX, but I''m having some major problems with my shader. I''m using the same rendering algorithm in my shaders as I used in my old OGL engine for DOT3 bumpmapping. For some reason the result is completely screwed up. Something in the shader code must be completely wrong, but I can''t figure out what it is. I''m using .fx files for my shaders (a really nice feature of DX) and I''ve put a little demo showing the problem on my website: http://members.home.nl/r.blewanus/IxDx%20engine.zip . When you run the executable you can see the lighting is totally wrong, the shader is located in the folder data/shaders/ . Can someone please help to figure out what is wrong with my shader code? Thanks in Advance.

Share this post


Link to post
Share on other sites
I have taken some screenshots, just so we can get clear what is totally wrong. I really don't see anything alarming. Could you perhaps post a screenshot from your OGL engine?

Screen 1
Screen 2

These screenshots were taken with a radeon 9800xt.


Dustin Franklin
Mircrosoft DirectX MVP

[edited by - circlesoft on May 19, 2004 5:20:13 PM]

Share this post


Link to post
Share on other sites
The FVF code is as follows:


D3DVERTEXELEMENT9 VPosTexTBN[] =
{
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0, sizeof(Vector3D) * 1, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
{0, sizeof(Vector3D) * 1 + sizeof(Vector2D), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
{0, sizeof(Vector3D) * 2 + sizeof(Vector2D), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
{0, sizeof(Vector3D) * 3 + sizeof(Vector2D), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
D3DDECL_END()
};

D3DDevice->CreateVertexDeclaration(VPosTexTBN, &VDeclPosTexTBN);

(Vector3D is simply a class with 3 floats and some functions, Vector2D has 2 floats and a couple of functions)

This is the code which sets the shader''s parameters:

D3DDevice->SetVertexDeclaration(VDeclPosTexTBN);

D3DXMATRIX worldviewprojection = matWorld * matView * matProject;
LightShader->SetMatrixTranspose("worldViewProj", &worldviewprojection);
D3DXMATRIX worldview = matView;
D3DXMATRIX inverseview;
D3DXMatrixInverse(&inverseview, NULL, &worldview);
LightShader->SetMatrix("invView", &inverseview);
D3DXVECTOR4 shadercampos;
shadercampos.x = Cam.Position.x;
shadercampos.y = Cam.Position.y;
shadercampos.z = Cam.Position.z;
LightShader->SetVector("CamPos", &shadercampos);

D3DXVECTOR4 shaderlightpos;
shaderlightpos.x = 0; shaderlightpos.y = 0; shaderlightpos.z = 0;
LightShader->SetVector("LightPos", &shaderlightpos);




Share this post


Link to post
Share on other sites
And this is the .fx effect file itself:

//-----------------------------------------------------------------------------

// Effect File Variables

//-----------------------------------------------------------------------------


float4x4 worldViewProj : WorldViewProjection; // This matrix will be loaded by the application

float4x4 invView : ViewInverse;
float3 LightPos;
float3 CamPos;
sampler Base: register(s0);
sampler Bump: register(s1);

//-----------------------------------------------------------------------------

// Vertex Definitions

//-----------------------------------------------------------------------------


struct vertex
{
float3 position : POSITION;
float2 texture0 : TEXCOORD0;
float3 tangent : TANGENT;
float3 binormal : BINORMAL;
float3 normal : NORMAL;
};

struct fragment
{
float4 hposition : POSITION;
float2 texture0 : TEXCOORD0;
float3 lightvec : TEXCOORD1;
float3 viewvec : TEXCOORD2;
};

struct pixel
{
float4 color : COLOR;
};

//-----------------------------------------------------------------------------

// Vertex Shader

//-----------------------------------------------------------------------------


fragment mainvs( vertex IN )
{
fragment OUT;

OUT.hposition = mul( worldViewProj, float4(IN.position, 1) );
OUT.texture0 = IN.texture0;

float3 lightVec = (LightPos - IN.position);
OUT.lightvec.x = dot(lightVec, IN.tangent);
OUT.lightvec.y = dot(lightVec, IN.binormal);
OUT.lightvec.z = dot(lightVec, IN.normal);

float3 viewVec = (CamPos - IN.position);
OUT.viewvec.x = dot(viewVec, IN.tangent);
OUT.viewvec.y = dot(viewVec, IN.binormal);
OUT.viewvec.z = dot(viewVec, IN.normal);

return OUT;
}

//-----------------------------------------------------------------------------

// Pixel Shader

//-----------------------------------------------------------------------------


pixel mainps( fragment IN )
{
pixel OUT;

float4 base = tex2D(Base, IN.texture0);
float3 bump = tex2D(Bump, IN.texture0) * 2 - 1;

bump = normalize(bump);

float distsqr = dot(IN.lightvec, IN.lightvec);
float3 lVec = distsqr * (1/sqrt(distsqr));

float atten = saturate(1.0 - 0.004 * sqrt(distsqr));
float diffuse = saturate(dot(IN.lightvec, bump));

float specular = pow(saturate(dot(reflect(normalize(IN.viewvec), bump), lVec)), 32.0);

OUT.color = 0.5 * base + (diffuse * base + 0.6 * specular) * atten;

return OUT;
}

//-----------------------------------------------------------------------------

// Effect (1 technique with 1 pass)

//-----------------------------------------------------------------------------


technique Technique0
{
pass Pass0
{
Lighting = FALSE;

VertexShader = compile vs_2_0 mainvs();
PixelShader = compile ps_2_0 mainps();
}
}


I have no idea why the bumpmapping algorithm isn''t working. I hope someone here can help.

Share this post


Link to post
Share on other sites
Never mind, I''ve figured it out myself. I changed a couple of lines in the shader and now the lighting works correctly. If you want to see a demo of the engine in action, you can download it from here. It does require vertex and pixel shaders 2.0 .

By the way, this is the updated shader:

//-----------------------------------------------------------------------------

// Effect File Variables

//-----------------------------------------------------------------------------


float4x4 worldViewProj : WorldViewProjection; // This matrix will be loaded by the application

float4x4 invView : ViewInverse;
float4x4 worldMat : World;
float3 LightPos;
float3 CamPos;
sampler Base: register(s0);
sampler Bump: register(s1);

//-----------------------------------------------------------------------------

// Vertex Definitions

//-----------------------------------------------------------------------------


struct vertex
{
float3 position : POSITION;
float2 texture0 : TEXCOORD0;
float3 tangent : TANGENT;
float3 binormal : BINORMAL;
float3 normal : NORMAL;
};

struct fragment
{
float4 hposition : POSITION;
float2 texture0 : TEXCOORD0;
float3 lightvec : TEXCOORD1;
float3 viewvec : TEXCOORD2;
};

struct pixel
{
float4 color : COLOR;
};

//-----------------------------------------------------------------------------

// Vertex Shader

//-----------------------------------------------------------------------------


fragment mainvs( vertex IN )
{
fragment OUT;

OUT.hposition = mul( worldViewProj, float4(IN.position, 1) );
OUT.texture0 = IN.texture0;

float3 lightVec = (LightPos - IN.position);
OUT.lightvec.x = dot(lightVec, IN.tangent);
OUT.lightvec.y = dot(lightVec, IN.binormal);
OUT.lightvec.z = dot(lightVec, IN.normal);

float3 viewVec = (CamPos - IN.position);
OUT.viewvec.x = dot(viewVec, IN.tangent);
OUT.viewvec.y = dot(viewVec, IN.binormal);
OUT.viewvec.z = dot(viewVec, IN.normal);

return OUT;
}

//-----------------------------------------------------------------------------

// Pixel Shader

//-----------------------------------------------------------------------------


pixel mainps( fragment IN )
{
pixel OUT;

float4 base = tex2D(Base, IN.texture0);
float3 bump = tex2D(Bump, IN.texture0) * 2.0 - 1.0; //scale and bias


//normalize bumpmap-vector

bump = normalize(bump);

//normalize lightvector

float3 normlightvec = normalize(IN.lightvec);

//attenuation

float dist = dot(IN.lightvec, IN.lightvec);
float atten = saturate(1.0 - 0.002 * sqrt(dist));

//diffuse

float diffuse = saturate(dot(normlightvec, bump));

//normalize viewvector

float3 normviewvec = normalize(IN.viewvec);

//reflection vector

float reflection = dot(normlightvec, bump)*0.1*bump;
normlightvec = normlightvec - reflection;

//specular

float specular = pow(saturate(dot(reflect(-normviewvec, bump), normlightvec)), 32);

//ambient * base + (diffuse * base + specular) * attenuation

OUT.color = 0.5 * base + (diffuse * base + specular) * atten;

return OUT;
}

//-----------------------------------------------------------------------------

// Effect (1 technique with 1 pass)

//-----------------------------------------------------------------------------


technique Technique0
{
pass Pass0
{
Lighting = FALSE;

VertexShader = compile vs_2_0 mainvs();
PixelShader = compile ps_2_0 mainps();
}
}

Share this post


Link to post
Share on other sites