Sign in to follow this  

normal mapping issue

This topic is 2560 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi everyone.

I'm working on a simple shader to make a normal mapping effect to use with the graphics engine I'm currently on.

This shader computes lighting that comes from a single point light (with att and a single diffuse color). The material is composed of a diffuse texture, a specular map and a normal map (the famous "blue map").

The shader seems top work, but only approximately.

I got an issue with the specular lighting that behaves in a verry weired way.

So I wish to know if my theory of the normal mapping is correct :

- In VShader, send as output the transformed position, the local position, the tangent, binormal and normal values, and the texture coordinates
- In PShader, create a vector from local pos to local light pos, transform it using TBN (from values we get of the VShader) and normalize it. Idem for the vector from local pos to camera pos. Then, compute Halfway vector by adding the two first vectors and then normalize. Sample normal map using texture coordinate off from the rasterizer (normalizing is not necessaray?). Compute lighting using sampled normal and transformed/normalized vectors (with lit function).

Compute color using diffuse and specular map, and draw pixel.

To get the normal from the normal map, we have to do like this :
(Tex2D(map_normal, In.uv) - 0.5f) * 2.0f

Is that all right? I send you the shader when I come back home this evening (I'm GMT+1 here, so in the afternoon for US people)

Thanks in advance.

@xi@g@me

Share this post


Link to post
Share on other sites
I'm back ^^

Here's my vertex shader code :

// uniform variables
float4x4 mat_worldViewProj; // world * view * projection matrix



// vertex program code
// in :
// vertex position @ POSITION0 (local)
// vertex tangent @ TANGENT0 (local)
// vertex binormal @ BINORMAL0 (local)
// vertex normal @ NORMAL0 (local)
// vertex uv @ TEXCOORD0
// out :
// vertex position @ POSITION0 (screen)
// vertex position @ POSITION1 (local)
// vertex tangent @ TANGENT0 (local)
// vertex binormal @ BINORMAL0 (local)
// vertex normal @ NORMAL0 (local)
// vertex uv @ TEXCOORD0
struct VPIn
{
float4 position : POSITION0;
float4 tangent : TANGENT0;
float4 binormal : BINORMAL0;
float4 normal : NORMAL0;
float2 uv : TEXCOORD0;
};
struct VPOut
{
float4 position : POSITION0;
float4 localPos : POSITION1;
float4 tangent : TANGENT0;
float4 binormal : BINORMAL0;
float4 normal : NORMAL0;
float2 uv : TEXCOORD0;
};

void main(in VPIn In, out VPOut Out)
{
// what's in goes out, + transformed pos
Out.position = mul(In.position, mat_worldViewProj);
Out.localPos = In.position;
Out.tangent = In.tangent;
Out.binormal = In.binormal;
Out.normal = In.normal;
Out.uv = In.uv;
}



And my fragment shader code :

// uniform variables

// positions
float4 pos_camera; // camera position (local)
float4 pos_light; // light position (local)

// light and material
float4 light_color; // light color (diffuse & specular)
float4 light_attenuation; // Att0, Att1, Att2, no_Use
float4 scene_ambient = float4(0.05f, 0.05f, 0.05f, 0.05f); // ambient light
float4x4 material_colors; // material (diffuse, ambient, specular, emissive)
float material_power; // specular power level

// textures
sampler2D map_diffuse; // diffuse map
sampler2D map_specular; // specular map
sampler2D map_normal; // normal map



// fragment program code
// in :
// local position @ POSITION1
// local tangent @ TANGENT0
// local binormal @ BINORMAL0
// local normal @ NORMAL0
// uv @ TEXCOORD0
// out :
// color @ COLOR0 (final color)
struct FPIn
{
float4 position : POSITION1;
float4 tangent : TANGENT0;
float4 binormal : BINORMAL0;
float4 normal : NORMAL0;
float2 uv : TEXCOORD0;
};
struct FPOut
{
float4 color : COLOR0;
};

void main(in FPIn In, out FPOut Out)
{
// locals
float4x4 TBN; // TBN transformation matrix
float4 VC; // vertex to camera vector (tangent space)
float4 VL; // vertex to light vector (tangent space)
float4 H; // halfway vector (tangent space)
float4 lighting; // lighting computation result
float VLSqDist; // square distance between Vertex and Light
float VLDist; // distance between Vertex and Light
float attenuation; // attenuation value
float4 mappedNormal; // normal to use for lighting computation

// locals initialization
TBN = float4x4(In.tangent.x, In.binormal.x, In.normal.x, 0.0f,
In.tangent.y, In.binormal.y, In.normal.y, 0.0f,
In.tangent.z, In.binormal.z, In.normal.z, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
VC = normalize(mul(pos_camera - In.position, TBN));
VL = normalize(mul(pos_light - In.position, TBN));
H = normalize(VC + VL);
mappedNormal = (tex2D(map_normal, In.uv) - 0.5f) * 2.0f;

// compute lighting
lighting = lit(dot(mappedNormal, VL), dot(mappedNormal, H), material_power);

// compute distance
VLSqDist = dot(pos_light - In.position, pos_light - In.position);
VLDist = sqrt(VLSqDist);
attenuation = clamp(1.0f - (light_attenuation.x + (VLDist * light_attenuation.y) + (VLSqDist * light_attenuation.z)), 0.0f, 1.0f);

Out.color = saturate(lighting.y * material_colors._11_12_13_14 *light_color * attenuation * tex2D(map_diffuse, In.uv) +
lighting.z * material_colors._31_32_33_34 * light_color * attenuation * tex2D(map_specular, In.uv) +
material_colors._21_22_23_24 * scene_ambient +
material_colors._41_42_43_44);

}



Do someone has an idea?

EDIT : I forgot one point : I'm working with D3D9 and HLSL ^^ (Left Handed)

[Edited by - @xi@g@me on December 3, 2010 1:27:57 PM]

Share this post


Link to post
Share on other sites
You have to tell us what the problem is if you expect help.

I got an issue with the specular lighting that behaves in a verry weired way.


Well, to solve the problem, you just do it in a not weird way --problem solved!

Share this post


Link to post
Share on other sites
It's a bit hard to explain.

Let's say that the specular lighting computing seems not to be correct.
Without using the normal map, it works perfectly. But If I use the normal map, it does not work as it should do.

The normal map in itself is correct (generated by a piece of software with a correct preview).

Also, if I normalize the value I get from the normal map, I have absolutely no specular (the normal map is bound to contain allready normalizd normals, isn't it?)

Share this post


Link to post
Share on other sites

This topic is 2560 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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