使用HLSL实现法线贴图

	HRESULT hr = S_OK;

	LPD3DXMESH	pMeshSysMem = NULL, pMeshSysMem2 = NULL;

	D3DXLoadMeshFromX(L"sphere.x", D3DXMESH_SYSTEMMEM, pd3dDevice, NULL, NULL, NULL, NULL, &pMeshSysMem);
	
	VertexModel* pV;
	pMeshSysMem->LockVertexBuffer(0,(void**)&pV);
	for(int i = 0;i < pMeshSysMem->GetNumVertices();i++)
	{
		VertexModel p = pV[i];
		LogHelper.Trace("%d\n",i);
// 		LogHelper.Trace("%10.6f\t%10.6f\t%10.6f\n",pV[i].vPos.x,pV[i].vPos.y,pV[i].vPos.z);
// 		LogHelper.Trace("%10.6f\t%10.6f\n",pV[i].vTex.x,pV[i].vTex.y);
// 		LogHelper.Trace("%10.6f\t%10.6f\t%10.6f\n\n",pV[i].vNormal.x,pV[i].vNormal.y,pV[i].vNormal.z);
	}
	pMeshSysMem->UnlockVertexBuffer();

//	D3DFVF_XYZ
//	DWORD fvf = pMeshSysMem->GetFVF();
	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()
	};
	hr = pMeshSysMem->CloneMesh(D3DXMESH_MANAGED, decl, pd3dDevice, &pMeshSysMem2);
	DWORD fvf = pMeshSysMem->GetFVF();

	VertexWithTan* pVT;
	pMeshSysMem2->LockVertexBuffer(0,(void**)&pVT);
	for(int i = 0;i < pMeshSysMem2->GetNumVertices();i++)
	{
		VertexWithTan p = pVT[i];
	}
	pMeshSysMem2->UnlockVertexBuffer();
	// compute the normals
//	D3DXComputeNormals(pMeshSysMem2,NULL);
//	D3DXComputeTangent(pMeshSysMem2,0,0,0,TRUE,NULL);
//	D3DXComputeTangentFrame(pMeshSysMem2, D3DXTANGENT_WRAP_UV);
	D3DXComputeTangentFrameEx(pMeshSysMem, 1, 0, 3, 0, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0,
		D3DXTANGENT_WRAP_UV, NULL, 0, 0, 0,&pMeshSysMem, NULL);

//  这个究竟要设置什么样的组合才可以呢??
//	D3DXComputeTangentFrame(pMeshSysMem2,  D3DXTANGENT_WRAP_UV | D3DXTANGENT_ORTHOGONALIZE_FROM_U | D3DXTANGENT_GENERATE_IN_PLACE);
//  用两种格式的顶点看看里面到底是什么格式的数据
	
	pMeshSysMem2->LockVertexBuffer(0,(void**)&pVT);
	for(int i = 0;i < pMeshSysMem2->GetNumVertices();i++)
	{
		VertexWithTan p = pVT[i];
// 		LogHelper.Trace("%d\n",i);
// 		LogHelper.Trace("%10.6f\t%10.6f\t%10.6f\n",pVT[i].vPos.x,pVT[i].vPos.y,pVT[i].vPos.z);
// 		LogHelper.Trace("%10.6f\t%10.6f\n",pVT[i].vTex.x,pVT[i].vTex.y);
// 		LogHelper.Trace("%10.6f\t%10.6f\t%10.6f\n\n",pVT[i].vNormal.x,pVT[i].vNormal.y,pVT[i].vNormal.z);
	}
	pMeshSysMem2->UnlockVertexBuffer();



	D3DVERTEXELEMENT9 decl2[]=
	{
		// stream, offset, type, method, semantic type (for example normal), ?
		{0, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
		{0, 16, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0},
		{0, 28, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
		{0, 36, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,  0},
		D3DDECL_END()
	};

	hr = pMeshSysMem2->CloneMesh(D3DXMESH_MANAGED, decl2, pd3dDevice, &m_pD3DXMesh);
	fvf = pMeshSysMem->GetFVF();

	// cleanup
	SAFE_RELEASE(pMeshSysMem);
	SAFE_RELEASE(pMeshSysMem2);

	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 );
// 	pd3dDevice->SetRenderState( D3DRS_DITHERENABLE, TRUE );
// 	pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );


	D3DXMatrixPerspectiveFovLH(&g_Projection, 0.05f, 
		640.0f/480.0f, 1.0f, 500.0f);

直接上代码还是
主要问题就是自己填充一个MESH网格,然后计算法线和切线(法线我都自己填充好了),现在有两个问题
1,不知道D3DXComputeTangent如何实现的,
2,不知道用新版本的应该如何传递参数
RENDER函数就是设置寄存器+渲染,掠过了

D3DXComputeNormals(pMeshSysMem,NULL);

D3DXComputeTangent(pMeshSysMem,0,0,0,FALSE,NULL);

SHADER代码很简单,就是根据顶点中的TANGENT值,法线值,计算一个有世界空间变换到切线空间矩阵,然后在这个空间进行光照计算

// 计算矩阵

   float3x3 worldToTangentSpace;
    worldToTangentSpace[0] = mul(Tangent, matWorld);
    worldToTangentSpace[1] = mul(cross(Tangent, Normal), matWorld);
    worldToTangentSpace[2] = mul(Normal, matWorld);

//变换

    Out.Light.xyz = mul(worldToTangentSpace, vecLightDir); // L
    float3 PosWorld = normalize(mul(Pos, matWorld));
    float3 Viewer = vecEye - PosWorld; // V
    Out.View = mul(worldToTangentSpace, Viewer);
    

//光照计算

   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.



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值