D3DXComputeTangentFrame question...

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

Recommended Posts

Question about this and D3DXComputeNormals for .x file meshes... What does this do to the mesh? The DX help is not very understandable to me. My reason is I need to get my Tangent, BiNormal, and Normal into my vertex shader - I understand that I only need the Tangent and Normal and I can cross product the Binormal from that. But what does it do and what should my struct in my VS shader look like to recieve input? Currently, after calling D3DXComputeTangentFrame with my mesh, I have struct MeshVSInput { float4 Position_XYZV : POSITION; float2 TexCoord_XY : TEXCOORD0; float3 Normal : NORMAL; float3 BiNormal : BINORMAL; float3 Tangent : TANGENT; }; I don't think that this is correct. Do I need to compute Tangent frame and compute normal and therefore what inputas will I need to recieve in my VS shader. Cheers

Share on other sites
I dont have time to go into much detail, but a bit of reference code from my project that I recently completed. It uploads the full tangent/bitangent/normal rather than doing a cross() in the VS - but you should be able to modify it accordingly:

Vertex Declaration:
D3DVERTEXELEMENT9 decl[] = {	{ 0,  0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },	{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0 },	{ 0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,  0 },	{ 0, 36, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0 },	{ 0, 48, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },	D3DDECL_END( )};

Generating the adjacency, the normals and then the tangent frame:
// Create adjacency information for this meshDWORD *pInputAdjacency = new DWORD[ mshGeometry->GetNumFaces() * 3 ];if( FAILED( mshGeometry->GenerateAdjacency( 0.01f, pInputAdjacency ) ) ){	// ...}// D3DXComputeTangentFrameEx() results are not guaranteed unless we have// vertex normals correctly generated.if( FAILED( D3DXComputeNormals( mshGeometry, pInputAdjacency ) ) ){	// ...}// Compute tangents/binormalsif( FAILED( D3DXComputeTangentFrameEx(  mshGeometry, 										D3DDECLUSAGE_TEXCOORD, 0, 										D3DDECLUSAGE_TANGENT,  0, 										D3DDECLUSAGE_BINORMAL, 0, 										D3DDECLUSAGE_NORMAL,   0, 										D3DXTANGENT_GENERATE_IN_PLACE, 										pInputAdjacency, 0.01f, 0.25f, 0.01f, 										NULL, NULL ) ) ){	// ...}

Effect File:
struct VS_INPUT{	float3 Position		: POSITION;	float3 Normal		: NORMAL;	float3 Tangent		: TANGENT;	float3 Binormal		: BINORMAL;	float2 TexCoord		: TEXCOORD;};VS_LIGHTING_OUTPUT vsLight( in VS_INPUT v, uniform bool pointLight ){	// ...}

All works fine for me [smile]

hth
Jack

Share on other sites
Hi, thanks for the help however I'm getting an error using this.

I've basically copied exactly what you suggested, everything seems to work fine except for the D3DXComputeTangentFrameEx:
I get an error on this which is D3DERR_INVALIDCALL, meaning one or more of the paramters to this method are invalid.

I've tried generating Adjecency info using a different method, but that still results in the same error.
I've triedf D3DXComputeTangentFrame(pMesh, NULL). still a fail.

I've read in the DX stuff that this could be that it fails if more vertices need to be created - using D3DXTANGENT_GENERATE_IN_PLACE...

Could this be the problem? If so what do I need to do? make a clone? - I'm not sure how to make the space big enough to store the new vertices.

Cheers

Share on other sites
Quote:
 Original post by FirstDouchaEvereverything seems to work fine except for the D3DXComputeTangentFrameEx:I get an error on this which is D3DERR_INVALIDCALL, meaning one or more of the paramters to this method are invalid.
Make sure you run with the Direct3D Debug runtimes enabled, ideally with maximum output. This should be a basic first thing to check when you get failing D3D/DX functions [smile]. See the link in my signiture for more details if necessary.

I would guess its complaining about "bow ties" or shared vertices in your mesh. It's the most common error I've received! A tangent frame can't be computed for some type of vertices, so if it detects them it fails. You have to use D3DXCleanMesh() with the D3DXCLEAN_BOWTIES.

hth
Jack