D3DXComputeTangentFrameEx

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

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 on other sites
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 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 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 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 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?

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 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 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 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 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.

1. 1
2. 2
Rutin
18
3. 3
4. 4
5. 5

• 14
• 12
• 9
• 12
• 37
• Forum Statistics

• Total Topics
631431
• Total Posts
3000039
×