Compressed tangent space vectors

Started by
12 comments, last by realkiran 15 years, 3 months ago
Why crossproduct of (0,1,0) and normal?


Maybe it is possible to compute tangent space in the pixel shader. Like so:

inNormal = normalize(inNormal);
float3 normalSample = tex2D(normalMap, tex0).rgb;
float3 normal = normalSample * 2.0f - 1.0f;

float3 q0 = ddx(pos);
float3 q1 = ddy(pos);
float2 st0 = ddx(tex0);
float2 st1 = ddy(tex0);

float3 T = normalize( q0 * st1.y - q1 * st0.y);
float3 B = normalize(-q0 * st1.x + q1 * st0.x);

float3x3 TBN;
TBN[0] = T;
TBN[1] = B;
TBN[2] =inNormal;

normal = mul(normal, TBN);


I'm wondering, if I can use vertex normal for this approach. I'm computing vertex normal by sampling four neighboring elevations in the vertex texture. And then just doing this:

float3 n;
n.x = h3 - h4;
n.y = h1 - h2;
n.z = g_NormalScale;

return normalize(n);


Do I need to transform the normal and light vector in the vertexshader, which space?
Advertisement
Quote:Original post by Lui
Have you solved it already?

The tangent and binormal can be caluculated like this:
Tangent = cross(float3(0, 1, 0), Normal);Binormal = cross(Normal, Tangent);
Maybe you will need to invert a vector, but that should be it.


This may be incorrect because it makes alot of assumptions. Computing tangents can be a pain, but if you understand exactly what the tangents are, there is a chance you can take some shortcuts (like Lui's code does).

Somehow you know the normal (I'd be really interested to know how you're doing this inside a vertex shader). Assuming your terrain is an x/z plane and you're projecting u,v coordinates with u on the x axis and v on the z axis, you can find the tangent by taking the cross product of the normal and unit z. Similarly you can get the bitangent from the cross product of the normal and unit x.

Ofcourse this is just the concept. You'll have to work out the proper cross product order and possibly some negations based on your exact projection and handedness.
Quote:Original post by realkiran
Somehow you know the normal (I'd be really interested to know how you're doing this inside a vertex shader).

Like I said in the above post. Four neighboring height values can be sampled in the vertex shader and then use this formula:

n = (west-east, 2, south-north);

But I don't know if this normal vector can be used in the above pixel shader code (by using partial derivatives). This is my question in the above post.
Sorry about that, I missed your last post. I don't believe that's an entirely sound way of getting normals but if it seems to work go for it. You don't need to transform both the normal and light vector, just one. Your implementation looks to me like it may work, why don't you try it and let us know?

This topic is closed to new replies.

Advertisement