I'm trying to calculate the lighting in the tangent space. But I'm still getting abnormal results. I was modifying the demo code of the book and I am amused if there is any problem with the transformation matrix that I created.

I'm having trouble solving a problem in *Introduction to programming 3D games with DirectX 11*. I tried to use the TBN matrix

*Tx, Ty, Tz, *

Bx, by, Bz,

Nx, Ny, Nz

according to the book provided, but I found that the light vector was erroneously transformed into tangent space and now I have no idea how to debug this shader.

Here is my Pixel Shader:

```
float4 PS1 (VertexOut pin,
uniform int gLightCount,
uniform bool gUseTexure,
bool uniform gAlphaClip,
uniform bool gFogEnabled,
uniform bool gReflectionEnabled): SV_Target {
// Normal interpolation can abnormalize it, so normalize it.
pin.NormalW = normalize (pin.NormalW);
pin.TangentW = normalize (pin.TangentW);
// The vector toEye is used in lighting.
float3 toEye = gEyePosW - pin.PosW;
// Caches the distance to the eye from this surface point.
float distToEye = length (toEye);
// Calculate normalMapSample
float3 normalMapSample =
normalize (SampledNormal2Normal (gNormalMap.Sample (samLinear, pin.Tex) .rgb));
// normalize to Eye
toEye = normalize (toEye);
// Default to the multiplicative identity.
float4 texColor = float4 (1, 1, 1, 1);
yes (gUseTexure)
{
// Show the texture.
texColor = gDiffuseMap.Sample (samLinear, pin.Tex);
yes (gAlphaClip)
{
// Discard pixel if texture is alpha < 0.1. Note that we do this
// test as soon as possible so that we can potentially exit the shader
// early, thereby skipping the rest of the shader code.
clip(texColor.a - 0.1f);
}
}
//
// Lighting.
//
float4 litColor = texColor;
if (gLightCount > 0)
{
// Start with a sum of zero.
float4 ambient = float4 (0.0f, 0.0f, 0.0f, 0.0f);
diffused float4 = float4 (0.0f, 0.0f, 0.0f, 0.0f);
float4 spec = float4 (0.0f, 0.0f, 0.0f, 0.0f);
// Add the contribution of light from each light source.
[unroll]
for (int i = 0; i <gLightCount; ++ i)
{
float4 A, D, S;
ComputeDirectionalLightInTangent (gMaterial, gDirLights[i],
normalMapSample, World2TangentSpace (pin.NormalW, pin.TangentW, gTexTransform), toEye,
A, D, S);
environment + = A;
diffuse + = D;
spec + = S;
}
litColor = texColor * (ambient + diffuse) + spec;
if (gReflectionEnabled)
{
float3 incident = -toEye;
float3 reflectionVector = reflect (incident, normalMapSample);
float4 reflectionColor = gCubeMap.Sample (samLinear, reflectionVector);
litColor + = gMaterial.Reflect * reflectionColor;
}
}
//
// fogging
//
yes (gFogEnabled)
{
float fogLerp = saturate ((distToEye - gFogStart) / gFogRange);
// Mix the color of the fog and the color on.
litColor = lerp (litColor, gFogColor, fogLerp);
}
// Common to take alpha of diffuse material and texture.
litColor.a = gMaterial.Diffuse.a * texColor.a;
return litColor;
}
```

And here are the functions. *SampledNormal2Normal*, *World2TangentSpace* Y *ComputeDirectionalLightInTangent*:

```
float3 SampledNormal2Normal (float3 sampledNormal)
{
float3 normalT = 2.0f * sampledNormal - 1.0f;
return normalT;
}
float3x3 World2TangentSpace (float3 unitNormalW, float3 tangentW, float4x4 texTransform)
{
// Build orthonormal bases.
float3 N = unitNormalW;
float3 T = normalize (tangentW - point (tangentW, N) * N);
float3 B = cross (N, T);
float3x3 TBN = float3x3 (T, B, N);
/ * float3x3 invTBN = float3x3 (T.x, T.y, T.z, B.x, B.y, B.z, N.x, N.y, N.z);
returns invTBN; * /
float3 T_ = T - point (N, T) * N;
float3 B_ = B - point (N, B) * N - (point (T_, B) * T_) / point (T_, T_);
float3x3 invT_B_N = float3x3 (T_.x, T_.y, T_.z, B_.x, B_.y, B_.z, N.x, N.y, N.z);
returns invT_B_N;
}
void ComputeDirectionalLightInTangent (Material mat, DirectionalLight L,
float3 normalT, float3x3 toTS, float3 toEye,
outside float4 environment,
outside float4 diffuse,
outside float4 spec)
{
// Initialize outputs.
environment = float4 (0.0f, 0.0f, 0.0f, 0.0f);
diffuse = float4 (0.0f, 0.0f, 0.0f, 0.0f);
spec = float4 (0.0f, 0.0f, 0.0f, 0.0f);
// The light vector points in the opposite direction to the direction in which the light rays travel.
float3 lightVec = -L.Direction;
lightVec = mul (lightVec, toTS);
lightVec = normalize (lightVec);
// toEye to Tangent Space
toEye = mul (toEye, toTS);
toEye = normalize (toEye);
// Add environmental term.
ambient = mat.Ambient * L.Ambient;
// Add fuzzy and specular term, provided the surface is in
// The line of light site.
float diffuseFactor = dot (lightVec, normalT);
// Flatten to avoid dynamic branching.
[flatten]
if (diffuseFactor> 0.0f)
{
float3 v = mirror (-lightVec, normalT);
float specFactor = pow (max (point (v, toEye), 0.0f), mat.Specular.w);
diffuse = diffuse Factor * mat.Diffuse * L.Diffuse;
spec = specFactor * mat.Specular * L.Specular;
}
}
```

The result I got seems to be much darker in most places and too bright in several highlighted areas. I wonder if someone can help me with my code or give me advice on how to debug a hlsl shader. Thank you!