HLSL bumpmapping issue
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.
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]
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]
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
Screen1
Screen2
The FVF code is as follows:
(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:
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:
I have no idea why the bumpmapping algorithm isn''t working. I hope someone here can help.
//-----------------------------------------------------------------------------// 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:
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
Popular Topics
Advertisement