first ,i create a mesh ,and fill data of 4 vertex to make a quad(just XYZ and UV),then i calculate Normal and Tangent,after that i copy the mesh to another mesh with FLOAT4 in POSITION.just for shader`s format.Then Render it,but the result is mistake and i found the data in Tangent is zero,why can`t they be calculated??how can i do??thanks very much!!!
Initial Part:
LPD3DXMESH pMeshSysMem = NULL;
D3DVERTEXELEMENT9 decl[]=
{
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
{0, 20, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
{0, 32, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
D3DDECL_END()
};
D3DXCreateMesh(2,4,D3DXMESH_MANAGED,decl,pd3dDevice,&pMeshSysMem);
VertexWithTan* pVT;
pMeshSysMem->LockVertexBuffer(0,(void**)&pVT);
pVT[0].vPos = D3DXVECTOR3(-2.0f,-2.0f,0.0f);
pVT[0].vTex = D3DXVECTOR2(0.0f,1.0f);
pVT[1].vPos = D3DXVECTOR3(-2.0f, 2.0f,0.0f);
pVT[1].vTex = D3DXVECTOR2(0.0f,0.0f);
pVT[2].vPos = D3DXVECTOR3( 2.0f, 2.0f,0.0f);
pVT[2].vTex = D3DXVECTOR2(1.0f,0.0f);
pVT[3].vPos = D3DXVECTOR3( 2.0f,-2.0f,0.0f);
pVT[3].vTex = D3DXVECTOR2(1.0f,1.0f);
pMeshSysMem->UnlockVertexBuffer();
WORD* indi;
pMeshSysMem->LockIndexBuffer(0,(void**)&indi);
indi[0] = 0;indi[1] = 1;indi[2] = 2;
indi[3] = 2;indi[4] = 3;indi[5] = 0;
pMeshSysMem->UnlockIndexBuffer();
DWORD* attr;
pMeshSysMem->LockAttributeBuffer(0,&attr);
for(int i = 0;i < 4;i++)
{
attr = 0;
}
pMeshSysMem->UnlockAttributeBuffer();
pMeshSysMem->LockVertexBuffer(0,(void**)&pVT);
for(int i = 0;i < pMeshSysMem->GetNumVertices();i++)
{
VertexWithTan p = pVT;
}
pMeshSysMem->UnlockVertexBuffer();
D3DXComputeNormals(pMeshSysMem,NULL);
D3DXComputeTangent(pMeshSysMem,0,0,0,TRUE,NULL);
D3DVERTEXELEMENT9 decl2[]=
{
// stream, offset, type, method, semantic type (for example normal), ?
{0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
{0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
{0, 36, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
D3DDECL_END()
};
hr = pMeshSysMem->CloneMesh(D3DXMESH_MANAGED, decl2, pd3dDevice, &m_pD3DXMesh);
D3DXComputeTangent(m_pD3DXMesh,0,0,0,TRUE,NULL);
if( FAILED( hr = D3DXCreateEffectFromFile( pd3dDevice, L"hlsl.fx", NULL, NULL,
D3DXSHADER_DEBUG, NULL, &m_pEffect, NULL ) ) )
return hr;
if(FAILED(D3DXCreateTextureFromFile(pd3dDevice, L"..\\earth.tga",&m_pColorMap)))
return E_FAIL;
if(FAILED(D3DXCreateTextureFromFile(pd3dDevice, L"..\\normal.tga",&m_pBumpMap)))
return E_FAIL;
D3DXMatrixIdentity( &g_World );
pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
D3DXMatrixPerspectiveFovLH(&g_Projection, 0.05f,
640.0f/480.0f, 1.0f, 500.0f);
Render Part
D3DXMatrixIdentity(&g_World);
g_World = g_World * *g_pArc->GetRotationMatrix() * *g_pArc->GetTranslationMatrix();
D3DXVECTOR3 vUpVec(0,1,0);
D3DXVECTOR3 vEyePt(0,0,-80);
D3DXVECTOR3 vLookatPt(0,0,0);
D3DXMatrixLookAtLH(&g_View, &vEyePt, &vLookatPt, &vUpVec);
// set light direction
m_pEffect->SetVector("vecLightDir", &-m_LightDir);
m_pEffect->SetVector("vecEye", &D3DXVECTOR4(vEyePt.x,vEyePt.y,vEyePt.z,0));
D3DXMATRIX mWorldViewProj = g_World * g_View * g_Projection;
m_pEffect->SetMatrix( "matWorldViewProj", &mWorldViewProj );
m_pEffect->SetMatrix( "matWorld", &g_World);
UINT nPasses;
UINT iPass;
pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000,1.0f, 0);
pd3dDevice->BeginScene();
if( m_pEffect != NULL )
{
D3DXHANDLE hTechnique = m_pEffect->GetTechniqueByName( "TShader" );
m_pEffect->SetTechnique( hTechnique );
m_pEffect->SetTexture("ColorMap", m_pColorMap);
m_pEffect->SetTexture("BumpMap", m_pBumpMap);
m_pEffect->Begin( &nPasses, 0 );
for( iPass = 0; iPass < nPasses; iPass ++ )
{
m_pEffect->BeginPass( iPass );
m_pD3DXMesh->DrawSubset( 0 );
m_pEffect->EndPass();
}
m_pEffect->End();
}
pd3dDevice->EndScene();
pd3dDevice->Present(NULL,NULL,NULL,NULL);
Shader:
float4x4 matWorldViewProj;
float4x4 matWorld;
float4 vecLightDir;
float4 vecEye;
texture ColorMap;
sampler ColorMapSampler = sampler_state
{
Texture = <ColorMap>;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
texture BumpMap;
sampler BumpMapSampler = sampler_state
{
Texture = <BumpMap>;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
// -------------------------------------------------------------
// Output channels
// -------------------------------------------------------------
struct VS_OUTPUT
{
float4 Pos : POSITION;
float2 Tex : TEXCOORD0;
float3 Light : TEXCOORD1;
float3 View : TEXCOORD2;
};
// -------------------------------------------------------------
// vertex shader function (input channels)
// -------------------------------------------------------------
VS_OUTPUT VS(float4 Pos : POSITION, float2 Tex : TEXCOORD, float3 Normal : NORMAL, float3 Tangent : TANGENT )
{
VS_OUTPUT Out = (VS_OUTPUT)0;
Out.Pos = mul(Pos, matWorldViewProj); // transform Position
// compute the 3x3 tranform matrix
// to transform from world space to tangent space
float3x3 worldToTangentSpace;
worldToTangentSpace[0] = mul(Tangent, matWorld);
worldToTangentSpace[1] = mul(cross(Tangent, Normal), matWorld);
worldToTangentSpace[2] = mul(Normal, matWorld);
Out.Tex = Tex.xy;
Out.Light.xyz = mul(worldToTangentSpace, vecLightDir); // L
float3 PosWorld = normalize(mul(Pos, matWorld));
float3 Viewer = vecEye - PosWorld; // V
Out.View = mul(worldToTangentSpace, Viewer);
return Out;
}
// -------------------------------------------------------------
// Pixel Shader (input channels):output channel
// -------------------------------------------------------------
float4 PS(float2 Tex: TEXCOORD0, float3 Light : TEXCOORD1, ?float3 View : TEXCOORD2) : COLOR
{
float4 color = tex2D(ColorMapSampler, Tex); // fetch color map
float3 bumpNormal = 2 * (tex2D(BumpMapSampler, Tex) - 0.5); // bump map
float3 LightDir = normalize(Light); // L
float3 ViewDir = normalize(View); // V
float4 diff = saturate(dot(bumpNormal, LightDir)); // diffuse comp.
// float shadow = saturate(4 * diff); // compute self-shadowing term
// ????????????
float3 Reflect = normalize(2 * diff * bumpNormal - LightDir); // R
// gloss map in color.w restricts spec reflection
float4 spec = min(pow(saturate(dot(Reflect, ViewDir)), 3), color.w);
return 0.2 * color + color * diff + spec;
}
// -------------------------------------------------------------
//
// -------------------------------------------------------------
technique TShader
{
pass P0
{
Sampler[0] = (ColorMapSampler);
Sampler[1] = (BumpMapSampler);
// compile shaders
VertexShader = compile vs_1_1 VS();
PixelShader = compile ps_2_0 PS();
}
}