Sign in to follow this  
ramy

problem with bump mapping

Recommended Posts

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: [URL=http://img472.imageshack.us/my.php?image=screenshot152135ao.jpg][IMG]http://img472.imageshack.us/img472/3685/screenshot152135ao.th.jpg[/IMG][/URL] and here is the wrong display: [URL=http://img472.imageshack.us/my.php?image=screenshot152165gb.jpg][IMG]http://img472.imageshack.us/img472/2452/screenshot152165gb.th.jpg[/IMG][/URL]

Share this post


Link to post
Share on other sites
You could follow this sample code

float4x4 ModelViewProj : WORLDVIEWPROJ; //our world view projection matrix
float4x4 ModelViewIT : WORLDVIEWIT; //our inverse transpose matrix
float4x4 ModelWorld : WORLD; //our world matrix
float4 lightPos; //our light position in object space

texture texture0; //our texture
texture texture1; //our normal map

sampler2D 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 structure
struct a2v
{
float4 position : POSITION0;
float3 normal : NORMAL;
float2 tex0 : TEXCOORD0;
float3 tangent : TANGENT;
float3 binormal : BINORMAL;
};

//vertex to pixel shader structure
struct v2p
{
float4 position : POSITION0;
float2 tex0 : TEXCOORD0;
float2 tex1 : TEXCOORD1;
float3 lightVec : TEXCOORD2;
float att : TEXCOORD3;
};

//pixel shader to screen
struct p2f
{
float4 color : COLOR0;
};

//VERTEX SHADER
void 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 SHADER
void 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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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[i]);
m_BumpShader.SetValue("bumpTexture", m_BumpTexture[i]);

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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this