Jump to content
  • Advertisement
Sign in to follow this  
scope

D3DXComputeTangentFrameEx

This topic is 2953 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

It's a well documented function but i couldn't really find a answer to this:

Is there a problem when UV's are mirrored?

I'm implementing bump mapping and it seems like the normals are wrong where textures are mirrored. But mirroring is such a common thing that it got me wondering if it's really related to D3DXComputeTangentFrameEx.

Share this post


Link to post
Share on other sites
Advertisement
well here's my code for the call to D3DXComputeTangentFrameEx

i'm using FVF since i was using FVF all over my project and didn't feel like rewriting everything


if(FVF & D3DFVF_NORMAL)
{

FVF |= D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE3(1) | D3DFVF_TEXCOORDSIZE3(2);

LPD3DXMESH tmp_mesh;
dxmesh->CloneMeshFVF(meshDesc.options, FVF, device, &tmp_mesh);
dxmesh->Release();
dxmesh = tmp_mesh;

DWORD *ad1 = new DWORD[dxmesh->GetNumFaces() * sizeof(DWORD) * 3];
dxmesh->GenerateAdjacency(1e-6f, ad1);

D3DXComputeNormals(dxmesh, ad1);

D3DXComputeTangentFrameEx
(
dxmesh,
D3DDECLUSAGE_TEXCOORD, 0,
D3DDECLUSAGE_TEXCOORD, 1,
D3DDECLUSAGE_TEXCOORD, 2,
D3DDECLUSAGE_NORMAL, 0,
D3DXTANGENT_GENERATE_IN_PLACE,
ad1, 0.01f, 0.25f, 0.01f,
NULL, NULL
);

delete [] ad1;

}




i'm quite sure that this isn't the problem though.

here's a screenshot that shows the whole issue:



maybe it's completely unrelated to mirroring, it was just a wild guess.

[Edited by - scope on August 25, 2010 12:25:15 AM]

Share this post


Link to post
Share on other sites
I recently had the same problem, which may be what you are experiencing (or not)...

I could not get D3DXComputeTangentFrameEx to properly calculate the bi-normal, so I got around it using the cross product in my pixel shader, for example.

normalize(cross(-In.Tngt,In.Nrml));

The tangent is pre-converted to tangent space in the vertex shader, the actual calculations are done in the pixel shader since it's for per-pixel lighting.

Anyways, maybe that will help.

Share this post


Link to post
Share on other sites
Hi LancerSolurus,

Thanks for your reply. I've switched to a similar solution just a few minutes ago (wasn't expecting anymore responses). I'm using the tangent computation from this site now http://www.dhpoware.com/demos/d3d9NormalMapping.html, which basically does what you proposed.

That and it seems that i got my multiplications in the wrong order(?)

i was using

normal = normalize(mul(MatTBN, normal));

but it seems to be ok with

normal = normalize(mul(normal, MatTBN));

is this correct for transforming the normal to worldspace?

sorry about struggling with ancient technologies :)

Share this post


Link to post
Share on other sites
Without seeing your code it looks like you are transforming into tangent space (MatTBN). This is the proper space to calculate your bump mapping, you can do per-pixel bump mapping in this space.

You will also need to convert your light's position into tangent space, how you do that is as follows (I do not use light direction since a light position makes more sense to me)

tbn[0]=In.Tngt;
tbn[1]=normalize(cross(-In.Tngt,In.Nrml)); // calc bi-normal
tbn[2]=In.Nrml;
itbn=transpose(tbn);
lt=mul(lp,itbn);

lp is the lights position (float3)

then you need to get the dot product that you can multiply against the texture color

ld=(saturate(dot(nclr,lt)));
ldn=LtDiffuse*ld;

nclr is the sampled texel from the normal map
LtDiffuse is the light's diffuse color
You may want to normalize before getting the dot product, I had no problem using the light's pos as it was

Anyways, if there are better HLSL programmers whom see an error, please point it out.

Hope that helps, HLSL drives me crazy sometimes as well :P

Share this post


Link to post
Share on other sites
I'm using deferred rendering so i have to transform the normals to world space before i render them i think (my lights are in world space as well).

I think theres still something wrong but i'm not really able to put my finger on it at the moment.

Well, here's a screeny of my new normal buffer. I just noticed that it looks almost the same when i output the vertex normals so it might actually be correct now after all.



edit: shouldn't those wall normals be plain-colored?

Here's my shader code:

vertex shader



VS_outputMain vs_Main(VS_input input)
{
VS_outputMain output;

output.Position = mul(float4(input.pos.xyz, 1.0f), MatWVP);
output.UV = input.UV;

output.normal = normalize(mul(input.normal, (float3x3)MatWorld));
output.tangent = normalize(mul(input.tangent.xyz, (float3x3)MatWorld));
output.binormal = cross(output.normal, output.tangent) * input.tangent.w; // same results with your version and d3dxcomputetangentframeex

output.depth = mul(float4(input.pos.xyz, 1.0f), MatWorldView);

return output;
}






PS_outputCombined ps_Main(in VS_outputMain input)
{
PS_outputCombined output = (PS_outputCombined)0;

const float3x3 MatTex = float3x3(input.tangent, input.binormal, input.normal);

float3 normal = normalize(2.0f * tex2D(textureNormals, cachePos2).xyz - 1.0f);


normal = normalize(mul(normal, MatTex));

output.Color0 = float4(normal, length(input.depth));

return output;
}


Share this post


Link to post
Share on other sites
this is weird to me:

all floors look plain-colored but walls look kind of interpolated



i'm using D3DXComputeNormals to compute the normals

Share this post


Link to post
Share on other sites
Well from what I can see I would suggest rendering it. Your pic actually looks right.

BTW, if you want to let me test your mesh with my shader, send me a pm.

Share this post


Link to post
Share on other sites
D3DXComputeTangentFrameEx Does not handle mirror UV tangent basis, what you need to do is duplicate vertices on the seams with the proper tangent direction, NvMeshMender handle this issue very well, also cylindrical wrapper. After mender the mesh it will have more vertices, but does not generate more faces, you can map your prev index buffer with a new one provided by NvMeshMender.

Share this post


Link to post
Share on other sites
Quote:
Original post by _Camus_
D3DXComputeTangentFrameEx Does not handle mirror UV tangent basis, what you need to do is duplicate vertices on the seams with the proper tangent direction, NvMeshMender handle this issue very well, also cylindrical wrapper. After mender the mesh it will have more vertices, but does not generate more faces, you can map your prev index buffer with a new one provided by NvMeshMender.


Thanks for clarification. I'll take a look at NvMeshMender since i still recieve crazy errors on many meshes. Seems like 3ds Max + Panda Exporter creates problematic meshes. Couldn't get D3DXWeldVertices and D3DXCleanMesh to fix it without messing up the UVs to save my life.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!