Skip to main content
gamedev.net
🔒 Locked

problem with bump mapping

Started by ramy Oct 21, 2005 at 7:46 AM 5 replies 950+ views
Original Post
ramy
ramy
hello guys, im having a problem with my bump mapping. the problem is, i have a cube, and every side is texturedwith one texture. and i have the normal texture as well with me. now, i pass to the shader my camera position, as if its the light position. and the shader calculates the does the bump mapping. now, the issue is, only two sides of the cube work correctly, and the rest of the sides, dont show the bumps when im near, if i go far from them, the bumps appear, i can just see the bump when im far away. why do u think that is? here is my vertex shader code:

Vs_Output vs_out;

   // Set output vertex pos, and texture coords.
   vs_out.vertexPos = mul(worldViewProj, float4(IN.vertexPos, 1));
   vs_out.texture0 = IN.texture0;
   
   // Set the object space light direction.
   vs_out.lightDirection = lightPos - IN.vertexPos;

   
   // Build TBN matrix.
   float3x3 tbnMatrix;
   tbnMatrix[0] = mul(IN.sTangent, worldView);
   tbnMatrix[1] = mul(IN.binormal, worldView);
   tbnMatrix[2] = mul(IN.normal, worldView);
   
   // Convert light direction to texture space.
   vs_out.lightDirection = mul(tbnMatrix, vs_out.lightDirection);
   
   return vs_out;


i also realized that i see the bumps correctly when i stand facing the corner of the cube where both sides of the cube are viewed. here is the corerct display: screenshot152135ao.th.jpg and here is the wrong display: screenshot152165gb.th.jpg
Armadon
Armadon
You could follow this sample code
float4x4 ModelViewProj : WORLDVIEWPROJ; //our world view projection matrixfloat4x4 ModelViewIT : WORLDVIEWIT; //our inverse transpose matrixfloat4x4 ModelWorld : WORLD; //our world matrixfloat4 lightPos; //our light position in object spacetexture texture0; //our texturetexture texture1; //our normal mapsampler2D texSampler0 : TEXUNIT0 = sampler_state{     Texture = (texture0);    MIPFILTER = LINEAR;    MAGFILTER = LINEAR;    MINFILTER = LINEAR;};sampler2D texSampler1 : TEXUNIT1 = sampler_state{    Texture = (texture1);   MIPFILTER = LINEAR;   MAGFILTER = LINEAR;   MINFILTER = LINEAR;};//application to vertex structurestruct a2v{     float4 position : POSITION0;     float3 normal : NORMAL;     float2 tex0 : TEXCOORD0;     float3 tangent : TANGENT;     float3 binormal : BINORMAL;};//vertex to pixel shader structurestruct v2p{     float4 position : POSITION0;     float2 tex0 : TEXCOORD0;     float2 tex1 : TEXCOORD1;     float3 lightVec : TEXCOORD2;     float att : TEXCOORD3;};//pixel shader to screenstruct p2f{     float4 color : COLOR0;};//VERTEX SHADERvoid vs( in a2v IN, out v2p OUT ){     //getting to position to object space    OUT.position = mul(IN.position, ModelViewProj);    //getting the position of the vertex in the world    float4 posWorld = mul(IN.position, ModelWorld);    //getting vertex -> light vector    float3 light = normalize(lightPos - posWorld);    //calculating the binormal and setting the Tangent Binormal and Normal matrix    float3x3 TBNMatrix = float3x3(IN.tangent, IN.binormal , IN.normal);    //setting the lightVector    OUT.lightVec = mul(TBNMatrix, light);    //calculate the attenuation    OUT.att = 1/( 1 + ( 0.005 * distance(lightPos.xyz, posWorld) ) );     OUT.tex0 = IN.tex0;    OUT.tex1 = IN.tex0;}//PIXEL SHADERvoid ps( in v2p IN, out p2f OUT ){    //calculate the color and the normal    float4 color = tex2D(texSampler0, IN.tex0);    /*this is how you uncompress a normal map*/    float3 normal = 2.0f * tex2D(texSampler1, IN.tex1).rgb - 1.0f;    //normalize the light    float3 light = normalize(IN.lightVec);    //set the output color    float diffuse = saturate(dot(normal, light));    //multiply the attenuation with the color    OUT.color = IN.att * color * diffuse;}technique test{    pass p0    {        vertexshader = compile vs_1_1 vs();        pixelshader = compile ps_2_0 ps();    }}


#1 Basically from what I can see is that you might have a problem here
vs_out.vertexPos = mul(worldViewProj, float4(IN.vertexPos, 1));
this should be
vs_out.vertexPos = mul(IN.vertexPos, worldViewProj);

#2 Make sure that your normals, tangents etc are correct. This might cause some problems

#3 Make sure the light vector is in the correct space.

Basically the point is that you should work in the correct spaces.. normally it's easy to transform all the "components" to the same space such as the object and the light and do the calculations...

I hope this helps.
Take care.
ramy
ramy
i used ur shader and it works when the object is at the origin, 0,0,0.

but when i translate the object to another positon the bumps dont work. only two sides of the cube work.

any clue why?
Armadon
Armadon
Some things to check is the check if you are sending the right transformation matrices and an object(mesh) to the system to be rendered.

Some points to note:
#1 Get the current view, projection and world matrices and multiply them together.
i.e.
Matrix modelViewProj = matBox * camera.MatView * camera.MatProj;

#2 Calculate the correct Inverse Transpose matrix to be given to the shader.
i.e.
Matrix modelViewIT = matBox * camera.MatView * camera.MatProj;
modelViewIT = Matrix.Invert(modelViewIT);
modelViewIT = Matrix.TransposeMatrix(modelViewIT);

#3 Also it's very important that you calculate the tangent and binormals for the object you are rendering as it uses those components to do the rounded bumps on the surface of the objects.
You will need to create vertex declaration for your object to hold this information.
i.e.
C#
VertexElement[] elements = new VertexElement[]{new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0),new VertexElement(0, 12, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Normal, 0),new VertexElement(0, 24, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0),new VertexElement(0, 36, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Tangent, 0),new VertexElement(0, 48, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.BiNormal, 0),VertexElement.VertexDeclarationEnd,};VertexDeclaration decl = new VertexDeclaration(renderer.Device, elements);

c++
D3DVERTEXELEMENT9 elements[] ={{ 0, sizeof( float ) * 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },{ 0, sizeof( float ) * 3, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },{ 0, sizeof( float ) * 6, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },{ 0, sizeof( float ) * 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0 },{ 0, sizeof( float ) * 15, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0 },D3DDECL_END()};


You can then use the clone function that is supplied with the D3DX to include the new declaration to the mesh.
C#
Mesh tempMesh = box.Clone(MeshFlags.Managed, elements, renderer.Device);box.Dispose();

c++
LPD3DXMESH temp;if ( FAILED( pMesh->CloneMesh( D3DXMESH_MANAGED, elements, pDevice, &temp ) ) ){pMesh = NULL;return;}


Then you can use the ComputeTangentFrame method to calculate the needed components
C#
box.ComputeTangentFrame(0);
c++
D3DXComputeTangentFrame(pMesh, 0);

I think your problem will most likely lie in on of 2 places, it's either your matrices that you send to the shader or you object doesn't have the correct normals.

I hope this helps.
Take care.
ramy
ramy
that is wat im exactly doing, i rechecked all of wat u mentioned above.

but i need to ask on two things:

the "matBox" is the matrix, that has the translations and rotations and everything concerning the box right??

and the "MatView" is the current view of the camera, right?

and in the vertex declaration why do u have :

new VertexElement(0, 24, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0),

it should be Float2 not Float3, right?
Armadon
Armadon
Quote:

the "matBox" is the matrix, that has the translations and rotations and everything concerning the box right??

Correct. The world transformation matrix that is associated with my box.

Quote:

and the "MatView" is the current view of the camera, right?

Correct again.

Quote:

new VertexElement(0, 24, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0),

it should be Float2 not Float3, right?

Yep, Although I just use Float3 for readability.

You could download this demo I wrote if you are unclear of some things. You can use the camera system I've built into it to move around or recompile the code and check how everything is put together and translate the object etc...

I hope this helps.
Take care.
ramy
ramy
i downloaded ur code, thats where im working off :D

i would like to take ur opinion in soemthing: here is the matrix information that i pass to the shader: notice im using ur shader:

private void SetShader(Matrix mat)        {            Matrix modelViewProj = mat *                m_Device.DEVICE.Transform.View *                m_Device.DEVICE.Transform.Projection;            Matrix modelViewProjIT = mat *                m_Device.DEVICE.Transform.View *                m_Device.DEVICE.Transform.Projection;            //modelViewProj = Matrix.TransposeMatrix(modelViewProj);            m_BumpShader.SetValue("ModelViewProj", modelViewProj);            modelViewProjIT = Matrix.Invert(modelViewProjIT);            modelViewProjIT = Matrix.TransposeMatrix(modelViewProjIT);            m_BumpShader.SetValue("ModelViewIT", modelViewProjIT);            m_BumpShader.SetValue("ModelWorld", mat);            m_BumpShader.SetValue("lightPos", new Vector4(ngFpsCamera.Position.X,                ngFpsCamera.Position.Y,                ngFpsCamera.Position.Z, 0));            m_Device.DEVICE.VertexDeclaration = m_ShaderDeclare;        }


and in my render function i do the follwoing:

if (m_bBumpMap)            {                SetShader(Matrix.Scaling(100, 100, 100) * Matrix.Translation(m_vPosition.vector3) * Matrix.Translation(-m_vCenter.vector3) * m_mRotation.matrix);                m_BumpShader.Technique = "bump";                m_BumpShader.Begin(FX.None);                m_BumpShader.BeginPass(0);                for (int i = 0; i < m_Material.Length; i++)                {                    m_BumpShader.SetValue("decaltexture", m_Texture);                    m_BumpShader.SetValue("bumpTexture", m_BumpTexture);                    m_Mesh.DrawSubset(i);                }                m_BumpShader.EndPass();                m_BumpShader.End();            }


note i changed the texture names in the shader code.

i personally think thats right, but apparently its not working correctly as to wat im seeing on the scene.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.