HLSL bumpmapping issue

Started by
5 comments, last by NeoKenobi 19 years, 11 months ago
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.
Advertisement
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]
Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )
I''ve taken some screenshots from the same level with my opengl renderer. As you can see the opengl version looks "bumpy" as a bumpmapped surface should look.

Screen1
Screen2
Can you post your vertex declaration code, and your shader constant setting code?
Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )
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);




And this is the .fx effect file itself:
//-----------------------------------------------------------------------------// Effect File Variables//-----------------------------------------------------------------------------float4x4 worldViewProj : WorldViewProjection; // This matrix will be loaded by the applicationfloat4x4 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.
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 applicationfloat4x4 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();    }}

This topic is closed to new replies.

Advertisement