3D游戏引擎系列七.docx
《3D游戏引擎系列七.docx》由会员分享,可在线阅读,更多相关《3D游戏引擎系列七.docx(17页珍藏版)》请在冰豆网上搜索。
3D游戏引擎系列七
JimBlinn在1978发表了一篇名为:
“SimulationofWrinkledSurfaces”,提出了BumpMapping这个东东。
BumpMapping通过一张HeightMap记录各象素点的高度信息,有了高度信息,就可以计算HeightMap中当前象素与周围象素的高度差,这个高度差就代表了各象素的坡度,用这个坡度信息去绕动法向量,得到最终法向量,用于光照计算。
在前面的博客中也有介绍过高光法线时介绍过TBN,在这里利用TBN渲染Bumpmapping实现原理。
GPU渲染属于可编程流水线,在使用Shader编程时首先要明白其实现原理,我们可以通过可编程流水线了解一下其原理:
上图中显示了TBNMatrix,T表示的是切向量,B表示次法线向量,N表示的是法线向量,这个也是求BumpMapping必须要计算得到的,TBNMatrix可以将其放到GPU中计算得到的。
下面我们就一步步给读者介绍其实现,只用文字很难描述清楚,还是通过图看的比较明白。
为了帮助读者理解Tangent空间向量,先给读者看一下场景中的四边形,纹理图片是要贴到四边形上的,如下图所示的效果:
图中显示的是纹理坐标的关系,左下角是(0,0),右上角是(1,1)。
现在,我们需要找到两个顶点的切线。
“S切线”点的方向的纹理坐标,“T切线”点的方向的纹理坐标。
这两个切线和法线是一个顶点的“基础”。
它们定义了一个坐标空间-“切向量空间”。
s切线,t切线和法线分别是用x,y,z轴表示的,TBN矩阵是从物体空间转换到切线空间,矩阵的表示如下所示:
(SxSySz)
(TxTyTz)
(NxNyNz)
S也是切线空间中的一种,我们也可以将其表示为Binormal,现在的主要问题是求解S,T,N向量。
先抛开GPU编程,先用C++代码实现一遍,首先定义一个类用于存储TBN,类的存储代码如下所示:
[cpp]viewplaincopy
classTORUS_VERTEX
{
public:
VECTOR3Dposition;
floats,t;
VECTOR3DsTangent,tTangent;
VECTOR3Dnormal;
VECTOR3DtangentSpaceLight;
};
结构体定义好了后,接下来,我们假设在场景中放置一个圆环,这个圆环有48个点组成,用于存储顶点和索引链表,代码类完整定义如下所示:
#ifndefTORUS_H
#defineTORUS_H
classTORUS
TORUS();
~TORUS();
boolInitTorus();
intnumVertices;
intnumIndices;
unsignedint*indices;
TORUS_VERTEX*vertices;
constinttorusPrecision=48;
#endif
现在开始计算圆环的顶点位置,法线,切向量空间,首先我们把圆环在XY平面上的示例图展示如下:
接下来在圆环上的材质实现法线和切向量空间的代码如下所示:
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
for(inti=0;i{vertices[i].position=VECTOR3D(1.5f,0.0f,0.0f).GetRotatedZ(i*360.0f/torusPrecision)+VECTOR3D(4.0f,0.0f,0.0f);vertices[i].s=0.0f;vertices[i].t=(float)i/torusPrecision;vertices[i].sTangent.Set(0.0f,0.0f,-1.0f);vertices[i].tTangent=VECTOR3D(0.0f,-1.0f,0.0f).GetRotatedZ(i*360.0f/torusPrecision);vertices[i].normal=vertices[i].tTangent.CrossProduct(vertices[i].sTangent);}图中实现的是静止不动的圆环,利用for循环实现了TBN向量,转动后的效果计算也是类似的,下面把完整的代码给读者展现一下:[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片#include#include#include#include"Maths/Maths.h"#include"TORUS.h"TORUS::TORUS(){InitTorus();}TORUS::~TORUS(){if(indices)delete[]indices;indices=NULL;if(vertices)delete[]vertices;vertices=NULL;}boolTORUS::InitTorus(){numVertices=(torusPrecision+1)*(torusPrecision+1);numIndices=2*torusPrecision*torusPrecision*3;vertices=newTORUS_VERTEX[numVertices];if(!vertices){printf("Unabletoallocatememoryfortorusvertices\n");returnfalse;}indices=newunsignedint[numIndices];if(!indices){printf("Unabletoallocatememoryfortorusindices\n");returnfalse;}//calculatethefirstring-innerradius4,outerradius1.5for(inti=0;i{vertices[i].position=VECTOR3D(1.5f,0.0f,0.0f).GetRotatedZ(i*360.0f/torusPrecision)+VECTOR3D(4.0f,0.0f,0.0f);vertices[i].s=0.0f;vertices[i].t=(float)i/torusPrecision;vertices[i].sTangent.Set(0.0f,0.0f,-1.0f);vertices[i].tTangent=VECTOR3D(0.0f,-1.0f,0.0f).GetRotatedZ(i*360.0f/torusPrecision);vertices[i].normal=vertices[i].tTangent.CrossProduct(vertices[i].sTangent);}//rotatethistogetotherringsfor(intring=1;ring{for(inti=0;i{vertices[ring*(torusPrecision+1)+i].position=vertices[i].position.GetRotatedY(ring*360.0f/torusPrecision);vertices[ring*(torusPrecision+1)+i].s=2.0f*ring/torusPrecision;vertices[ring*(torusPrecision+1)+i].t=vertices[i].t;vertices[ring*(torusPrecision+1)+i].sTangent=vertices[i].sTangent.GetRotatedY(ring*360.0f/torusPrecision);vertices[ring*(torusPrecision+1)+i].tTangent=vertices[i].tTangent.GetRotatedY(ring*360.0f/torusPrecision);vertices[ring*(torusPrecision+1)+i].normal=vertices[i].normal.GetRotatedY(ring*360.0f/torusPrecision);}}//calculatetheindicesfor(intring=0;ring{for(inti=0;i{indices[((ring*torusPrecision+i)*2)*3+0]=ring*(torusPrecision+1)+i;indices[((ring*torusPrecision+i)*2)*3+1]=(ring+1)*(torusPrecision+1)+i;indices[((ring*torusPrecision+i)*2)*3+2]=ring*(torusPrecision+1)+i+1;indices[((ring*torusPrecision+i)*2+1)*3+0]=ring*(torusPrecision+1)+i+1;indices[((ring*torusPrecision+i)*2+1)*3+1]=(ring+1)*(torusPrecision+1)+i;indices[((ring*torusPrecision+i)*2+1)*3+2]=(ring+1)*(torusPrecision+1)+i+1;}}returntrue;}以上代码实现的圆环效果是在CPU中运行得到的,它渲染的凹凸效果如下所示:CPU上的效率没有GPU运行效率高,还是建议读者在GPU中实现出来,最后把在GPU中实现的Shader代码给读者展示一下:[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片//矩阵float4x4g_matWorld:World;float4x4g_matWorldView:WorldView;float4x4g_matWorldViewProj:WorldViewProj;float4x4g_matInverWorldView:InverseWorldView;//灯光float4g_LightPositionViewSpace;floatg_OneOverSqrLightRadius;float4g_EyePosition;//材质floatg_MaterialAmbient;floatg_MaterialDiffuse;floatg_MaterialSpecular;floatg_MaterialEmissive;floatg_MaterialShininess;//纹理图片textureg_texEnvMap;textureg_texNormalMap;textureg_texHeightMap;floatg_fReflectivity=0.5f;floatg_fScale=0.04f;//[0,0.05]staticfloatg_fBias=g_fScale*0.5f;//---------------------------------------------------------------//Sampler//---------------------------------------------------------------samplerg_EnvMapSampler=sampler_state{Texture=;MinFilter=Linear;MagFilter=Linear;MipFilter=Linear;};samplerg_NormalMapSampler=sampler_state{Texture=(g_texNormalMap);MinFilter=Linear;MagFilter=Linear;MipFilter=Linear;};samplerg_HeightMapSampler=sampler_state{Texture=(g_texHeightMap);MinFilter=Linear;MagFilter=Linear;MipFilter=Linear;};//---------------------------------------------------------------//Utilities//---------------------------------------------------------------halfCalAttenuation(half3lightVec){returnsaturate(1-dot(lightVec,lightVec)*g_OneOverSqrLightRadius);}float3x3CalInvertMatrix3X3(float3x3M){floatdet=dot(cross(M[0],M[1]),M[2]);float3x3T=transpose(M);returnfloat3x3(cross(T[1],T[2]),cross(T[2],T[0]),cross(T[0],T[1]))/det;}//计算TBN矩阵float3x3CalTangentFrame(float3N){float3binormal;float3tangent;float3c1=cross(N,float3(0.0,0.0,1.0));float3c2=cross(N,float3(0.0,1.0,0.0));if(length(c1)>length(c2)){tangent=c1;}else{tangent=c2;}tangent=normalize(tangent);binormal=cross(N,tangent);binormal=normalize(binormal);returnfloat3x3(tangent,binormal,N);}float3CalReflect(float4position,float3normal){float3Normal=mul(normalize(normal),g_matWorld);float3PosWorld=mul(ition,g_matWorld);float3ViewDir=normalize(PosWorld-g_EyePosition.xyz);//returnrefract(ViewDir,Normal,.99);returnreflect(ViewDir,Normal);}//---------------------------------------------------------------//vertex&pixelshader//---------------------------------------------------------------structVS_OUTPUT_ENV{float4position:POSITION;float3texRefCoord:TEXCOORD0;};VS_OUTPUT_ENVVS_EnvMapping(float4position:POSITION,float3normal:NORMAL){VS_OUTPUT_ENVOUT=(VS_OUTPUT_ENV)0;OUT.position=mul(position,g_matWorldViewProj);OUT.texRefCoord=CalReflect(position,normal);returnOUT;}float4PS_EnvMapping(float3tex:TEXCOORD0):COLOR0{returng_fReflectivity*texCUBE(g_EnvMapSampler,tex);}//---------------------------------------------------------------structVS_OUTPUT{float4position:POSITION;float3normal:TEXCOORD0;float2texCoord:TEXCOORD1;float3worldViewPos:TEXCOORD2;float3texRefCoord:TEXCOORD3;};VS_OUTPUTVS_NormalMapping(float4pos:POSITION,float3normal:NORMAL,float2texCoord:TEXCOORD0){VS_OUTPUToutData=(VS_OUTPUT)0;outData.position=mul(pos,g_matWorldViewProj);outData.normal=normalize(mul(normal,(float3x3)g_matWorldView));outData.texCoord=texCoord;outData.worldViewPos=mul(pos,g_matWorldView).xyz;outData.texRefCoord=CalReflect(pos,normal);returnoutData;}float4PS_Phong(VS_OUTPUTinData):COLOR0{half3lightVec=g_LightPositionViewSpace-inData.worldViewPos;half3eyeVec=-inData.worldViewPos;half3normal=normalize(inData.normal);half3lightDir=normalize(lightVec);half3eyeDir=normalize(eyeVec);half3halfDir=normalize(eyeDir+lightDir);half3light=lit(dot(lightDir,normal),dot(halfDir,normal),g_MaterialShininess);halfatten=CalAttenuation(lightVec);float4Id=light.y*g_MaterialDiffuse;float4Is=light.z*g_MaterialSpecular;float4envColor=g_fReflectivity*texCUBE(g_EnvMapSampler,inData.texRefCoord);float4Ia=envColor*g_MaterialAmbient;return(Ia+Id+Is)*atten*envColor;}float4PS_NormalMapping(VS_OUTPUTinData):COLOR0{half3lightVec=g_LightPositionViewSpace-inData.worldViewPos;half3eyeVec=-inData.worldViewPos;//getthenormalmnormalmaphalf3normal=normalize(tex2D(g_NormalMapSampler,inData.texCoord).xyz*2.0-1.0);//transformthevectorfromworldspacetotangentspacefloat
vertices[i].position=VECTOR3D(1.5f,0.0f,0.0f).GetRotatedZ(i*360.0f/torusPrecision)+VECTOR3D(4.0f,0.0f,0.0f);
vertices[i].s=0.0f;
vertices[i].t=(float)i/torusPrecision;
vertices[i].sTangent.Set(0.0f,0.0f,-1.0f);
vertices[i].tTangent=VECTOR3D(0.0f,-1.0f,0.0f).GetRotatedZ(i*360.0f/torusPrecision);
vertices[i].normal=vertices[i].tTangent.CrossProduct(vertices[i].sTangent);
}
图中实现的是静止不动的圆环,利用for循环实现了TBN向量,转动后的效果计算也是类似的,下面把完整的代码给读者展现一下:
#include
#include"Maths/Maths.h"
#include"TORUS.h"
TORUS:
:
TORUS()
InitTorus();
~TORUS()
if(indices)
delete[]indices;
indices=NULL;
if(vertices)
delete[]vertices;
vertices=NULL;
boolTORUS:
InitTorus()
numVertices=(torusPrecision+1)*(torusPrecision+1);
numIndices=2*torusPrecision*torusPrecision*3;
vertices=newTORUS_VERTEX[numVertices];
if(!
vertices)
printf("Unabletoallocatememoryfortorusvertices\n");
returnfalse;
indices=newunsignedint[numIndices];
indices)
printf("Unabletoallocatememoryfortorusindices\n");
//calculatethefirstring-innerradius4,outerradius1.5
for(inti=0;i{vertices[i].position=VECTOR3D(1.5f,0.0f,0.0f).GetRotatedZ(i*360.0f/torusPrecision)+VECTOR3D(4.0f,0.0f,0.0f);vertices[i].s=0.0f;vertices[i].t=(float)i/torusPrecision;vertices[i].sTangent.Set(0.0f,0.0f,-1.0f);vertices[i].tTangent=VECTOR3D(0.0f,-1.0f,0.0f).GetRotatedZ(i*360.0f/torusPrecision);vertices[i].normal=vertices[i].tTangent.CrossProduct(vertices[i].sTangent);}//rotatethistogetotherringsfor(intring=1;ring{for(inti=0;i{vertices[ring*(torusPrecision+1)+i].position=vertices[i].position.GetRotatedY(ring*360.0f/torusPrecision);vertices[ring*(torusPrecision+1)+i].s=2.0f*ring/torusPrecision;vertices[ring*(torusPrecision+1)+i].t=vertices[i].t;vertices[ring*(torusPrecision+1)+i].sTangent=vertices[i].sTangent.GetRotatedY(ring*360.0f/torusPrecision);vertices[ring*(torusPrecision+1)+i].tTangent=vertices[i].tTangent.GetRotatedY(ring*360.0f/torusPrecision);vertices[ring*(torusPrecision+1)+i].normal=vertices[i].normal.GetRotatedY(ring*360.0f/torusPrecision);}}//calculatetheindicesfor(intring=0;ring{for(inti=0;i{indices[((ring*torusPrecision+i)*2)*3+0]=ring*(torusPrecision+1)+i;indices[((ring*torusPrecision+i)*2)*3+1]=(ring+1)*(torusPrecision+1)+i;indices[((ring*torusPrecision+i)*2)*3+2]=ring*(torusPrecision+1)+i+1;indices[((ring*torusPrecision+i)*2+1)*3+0]=ring*(torusPrecision+1)+i+1;indices[((ring*torusPrecision+i)*2+1)*3+1]=(ring+1)*(torusPrecision+1)+i;indices[((ring*torusPrecision+i)*2+1)*3+2]=(ring+1)*(torusPrecision+1)+i+1;}}returntrue;}以上代码实现的圆环效果是在CPU中运行得到的,它渲染的凹凸效果如下所示:CPU上的效率没有GPU运行效率高,还是建议读者在GPU中实现出来,最后把在GPU中实现的Shader代码给读者展示一下:[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片//矩阵float4x4g_matWorld:World;float4x4g_matWorldView:WorldView;float4x4g_matWorldViewProj:WorldViewProj;float4x4g_matInverWorldView:InverseWorldView;//灯光float4g_LightPositionViewSpace;floatg_OneOverSqrLightRadius;float4g_EyePosition;//材质floatg_MaterialAmbient;floatg_MaterialDiffuse;floatg_MaterialSpecular;floatg_MaterialEmissive;floatg_MaterialShininess;//纹理图片textureg_texEnvMap;textureg_texNormalMap;textureg_texHeightMap;floatg_fReflectivity=0.5f;floatg_fScale=0.04f;//[0,0.05]staticfloatg_fBias=g_fScale*0.5f;//---------------------------------------------------------------//Sampler//---------------------------------------------------------------samplerg_EnvMapSampler=sampler_state{Texture=;MinFilter=Linear;MagFilter=Linear;MipFilter=Linear;};samplerg_NormalMapSampler=sampler_state{Texture=(g_texNormalMap);MinFilter=Linear;MagFilter=Linear;MipFilter=Linear;};samplerg_HeightMapSampler=sampler_state{Texture=(g_texHeightMap);MinFilter=Linear;MagFilter=Linear;MipFilter=Linear;};//---------------------------------------------------------------//Utilities//---------------------------------------------------------------halfCalAttenuation(half3lightVec){returnsaturate(1-dot(lightVec,lightVec)*g_OneOverSqrLightRadius);}float3x3CalInvertMatrix3X3(float3x3M){floatdet=dot(cross(M[0],M[1]),M[2]);float3x3T=transpose(M);returnfloat3x3(cross(T[1],T[2]),cross(T[2],T[0]),cross(T[0],T[1]))/det;}//计算TBN矩阵float3x3CalTangentFrame(float3N){float3binormal;float3tangent;float3c1=cross(N,float3(0.0,0.0,1.0));float3c2=cross(N,float3(0.0,1.0,0.0));if(length(c1)>length(c2)){tangent=c1;}else{tangent=c2;}tangent=normalize(tangent);binormal=cross(N,tangent);binormal=normalize(binormal);returnfloat3x3(tangent,binormal,N);}float3CalReflect(float4position,float3normal){float3Normal=mul(normalize(normal),g_matWorld);float3PosWorld=mul(ition,g_matWorld);float3ViewDir=normalize(PosWorld-g_EyePosition.xyz);//returnrefract(ViewDir,Normal,.99);returnreflect(ViewDir,Normal);}//---------------------------------------------------------------//vertex&pixelshader//---------------------------------------------------------------structVS_OUTPUT_ENV{float4position:POSITION;float3texRefCoord:TEXCOORD0;};VS_OUTPUT_ENVVS_EnvMapping(float4position:POSITION,float3normal:NORMAL){VS_OUTPUT_ENVOUT=(VS_OUTPUT_ENV)0;OUT.position=mul(position,g_matWorldViewProj);OUT.texRefCoord=CalReflect(position,normal);returnOUT;}float4PS_EnvMapping(float3tex:TEXCOORD0):COLOR0{returng_fReflectivity*texCUBE(g_EnvMapSampler,tex);}//---------------------------------------------------------------structVS_OUTPUT{float4position:POSITION;float3normal:TEXCOORD0;float2texCoord:TEXCOORD1;float3worldViewPos:TEXCOORD2;float3texRefCoord:TEXCOORD3;};VS_OUTPUTVS_NormalMapping(float4pos:POSITION,float3normal:NORMAL,float2texCoord:TEXCOORD0){VS_OUTPUToutData=(VS_OUTPUT)0;outData.position=mul(pos,g_matWorldViewProj);outData.normal=normalize(mul(normal,(float3x3)g_matWorldView));outData.texCoord=texCoord;outData.worldViewPos=mul(pos,g_matWorldView).xyz;outData.texRefCoord=CalReflect(pos,normal);returnoutData;}float4PS_Phong(VS_OUTPUTinData):COLOR0{half3lightVec=g_LightPositionViewSpace-inData.worldViewPos;half3eyeVec=-inData.worldViewPos;half3normal=normalize(inData.normal);half3lightDir=normalize(lightVec);half3eyeDir=normalize(eyeVec);half3halfDir=normalize(eyeDir+lightDir);half3light=lit(dot(lightDir,normal),dot(halfDir,normal),g_MaterialShininess);halfatten=CalAttenuation(lightVec);float4Id=light.y*g_MaterialDiffuse;float4Is=light.z*g_MaterialSpecular;float4envColor=g_fReflectivity*texCUBE(g_EnvMapSampler,inData.texRefCoord);float4Ia=envColor*g_MaterialAmbient;return(Ia+Id+Is)*atten*envColor;}float4PS_NormalMapping(VS_OUTPUTinData):COLOR0{half3lightVec=g_LightPositionViewSpace-inData.worldViewPos;half3eyeVec=-inData.worldViewPos;//getthenormalmnormalmaphalf3normal=normalize(tex2D(g_NormalMapSampler,inData.texCoord).xyz*2.0-1.0);//transformthevectorfromworldspacetotangentspacefloat
vertices[i].position=VECTOR3D(1.5f,0.0f,0.0f).GetRotatedZ(i*360.0f/torusPrecision)+
VECTOR3D(4.0f,0.0f,0.0f);
vertices[i].normal=vertices[i].tTangent.
CrossProduct(vertices[i].sTangent);
//rotatethistogetotherrings
for(intring=1;ring{for(inti=0;i{vertices[ring*(torusPrecision+1)+i].position=vertices[i].position.GetRotatedY(ring*360.0f/torusPrecision);vertices[ring*(torusPrecision+1)+i].s=2.0f*ring/torusPrecision;vertices[ring*(torusPrecision+1)+i].t=vertices[i].t;vertices[ring*(torusPrecision+1)+i].sTangent=vertices[i].sTangent.GetRotatedY(ring*360.0f/torusPrecision);vertices[ring*(torusPrecision+1)+i].tTangent=vertices[i].tTangent.GetRotatedY(ring*360.0f/torusPrecision);vertices[ring*(torusPrecision+1)+i].normal=vertices[i].normal.GetRotatedY(ring*360.0f/torusPrecision);}}//calculatetheindicesfor(intring=0;ring{for(inti=0;i{indices[((ring*torusPrecision+i)*2)*3+0]=ring*(torusPrecision+1)+i;indices[((ring*torusPrecision+i)*2)*3+1]=(ring+1)*(torusPrecision+1)+i;indices[((ring*torusPrecision+i)*2)*3+2]=ring*(torusPrecision+1)+i+1;indices[((ring*torusPrecision+i)*2+1)*3+0]=ring*(torusPrecision+1)+i+1;indices[((ring*torusPrecision+i)*2+1)*3+1]=(ring+1)*(torusPrecision+1)+i;indices[((ring*torusPrecision+i)*2+1)*3+2]=(ring+1)*(torusPrecision+1)+i+1;}}returntrue;}以上代码实现的圆环效果是在CPU中运行得到的,它渲染的凹凸效果如下所示:CPU上的效率没有GPU运行效率高,还是建议读者在GPU中实现出来,最后把在GPU中实现的Shader代码给读者展示一下:[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片//矩阵float4x4g_matWorld:World;float4x4g_matWorldView:WorldView;float4x4g_matWorldViewProj:WorldViewProj;float4x4g_matInverWorldView:InverseWorldView;//灯光float4g_LightPositionViewSpace;floatg_OneOverSqrLightRadius;float4g_EyePosition;//材质floatg_MaterialAmbient;floatg_MaterialDiffuse;floatg_MaterialSpecular;floatg_MaterialEmissive;floatg_MaterialShininess;//纹理图片textureg_texEnvMap;textureg_texNormalMap;textureg_texHeightMap;floatg_fReflectivity=0.5f;floatg_fScale=0.04f;//[0,0.05]staticfloatg_fBias=g_fScale*0.5f;//---------------------------------------------------------------//Sampler//---------------------------------------------------------------samplerg_EnvMapSampler=sampler_state{Texture=;MinFilter=Linear;MagFilter=Linear;MipFilter=Linear;};samplerg_NormalMapSampler=sampler_state{Texture=(g_texNormalMap);MinFilter=Linear;MagFilter=Linear;MipFilter=Linear;};samplerg_HeightMapSampler=sampler_state{Texture=(g_texHeightMap);MinFilter=Linear;MagFilter=Linear;MipFilter=Linear;};//---------------------------------------------------------------//Utilities//---------------------------------------------------------------halfCalAttenuation(half3lightVec){returnsaturate(1-dot(lightVec,lightVec)*g_OneOverSqrLightRadius);}float3x3CalInvertMatrix3X3(float3x3M){floatdet=dot(cross(M[0],M[1]),M[2]);float3x3T=transpose(M);returnfloat3x3(cross(T[1],T[2]),cross(T[2],T[0]),cross(T[0],T[1]))/det;}//计算TBN矩阵float3x3CalTangentFrame(float3N){float3binormal;float3tangent;float3c1=cross(N,float3(0.0,0.0,1.0));float3c2=cross(N,float3(0.0,1.0,0.0));if(length(c1)>length(c2)){tangent=c1;}else{tangent=c2;}tangent=normalize(tangent);binormal=cross(N,tangent);binormal=normalize(binormal);returnfloat3x3(tangent,binormal,N);}float3CalReflect(float4position,float3normal){float3Normal=mul(normalize(normal),g_matWorld);float3PosWorld=mul(ition,g_matWorld);float3ViewDir=normalize(PosWorld-g_EyePosition.xyz);//returnrefract(ViewDir,Normal,.99);returnreflect(ViewDir,Normal);}//---------------------------------------------------------------//vertex&pixelshader//---------------------------------------------------------------structVS_OUTPUT_ENV{float4position:POSITION;float3texRefCoord:TEXCOORD0;};VS_OUTPUT_ENVVS_EnvMapping(float4position:POSITION,float3normal:NORMAL){VS_OUTPUT_ENVOUT=(VS_OUTPUT_ENV)0;OUT.position=mul(position,g_matWorldViewProj);OUT.texRefCoord=CalReflect(position,normal);returnOUT;}float4PS_EnvMapping(float3tex:TEXCOORD0):COLOR0{returng_fReflectivity*texCUBE(g_EnvMapSampler,tex);}//---------------------------------------------------------------structVS_OUTPUT{float4position:POSITION;float3normal:TEXCOORD0;float2texCoord:TEXCOORD1;float3worldViewPos:TEXCOORD2;float3texRefCoord:TEXCOORD3;};VS_OUTPUTVS_NormalMapping(float4pos:POSITION,float3normal:NORMAL,float2texCoord:TEXCOORD0){VS_OUTPUToutData=(VS_OUTPUT)0;outData.position=mul(pos,g_matWorldViewProj);outData.normal=normalize(mul(normal,(float3x3)g_matWorldView));outData.texCoord=texCoord;outData.worldViewPos=mul(pos,g_matWorldView).xyz;outData.texRefCoord=CalReflect(pos,normal);returnoutData;}float4PS_Phong(VS_OUTPUTinData):COLOR0{half3lightVec=g_LightPositionViewSpace-inData.worldViewPos;half3eyeVec=-inData.worldViewPos;half3normal=normalize(inData.normal);half3lightDir=normalize(lightVec);half3eyeDir=normalize(eyeVec);half3halfDir=normalize(eyeDir+lightDir);half3light=lit(dot(lightDir,normal),dot(halfDir,normal),g_MaterialShininess);halfatten=CalAttenuation(lightVec);float4Id=light.y*g_MaterialDiffuse;float4Is=light.z*g_MaterialSpecular;float4envColor=g_fReflectivity*texCUBE(g_EnvMapSampler,inData.texRefCoord);float4Ia=envColor*g_MaterialAmbient;return(Ia+Id+Is)*atten*envColor;}float4PS_NormalMapping(VS_OUTPUTinData):COLOR0{half3lightVec=g_LightPositionViewSpace-inData.worldViewPos;half3eyeVec=-inData.worldViewPos;//getthenormalmnormalmaphalf3normal=normalize(tex2D(g_NormalMapSampler,inData.texCoord).xyz*2.0-1.0);//transformthevectorfromworldspacetotangentspacefloat
for(inti=0;i{vertices[ring*(torusPrecision+1)+i].position=vertices[i].position.GetRotatedY(ring*360.0f/torusPrecision);vertices[ring*(torusPrecision+1)+i].s=2.0f*ring/torusPrecision;vertices[ring*(torusPrecision+1)+i].t=vertices[i].t;vertices[ring*(torusPrecision+1)+i].sTangent=vertices[i].sTangent.GetRotatedY(ring*360.0f/torusPrecision);vertices[ring*(torusPrecision+1)+i].tTangent=vertices[i].tTangent.GetRotatedY(ring*360.0f/torusPrecision);vertices[ring*(torusPrecision+1)+i].normal=vertices[i].normal.GetRotatedY(ring*360.0f/torusPrecision);}}//calculatetheindicesfor(intring=0;ring{for(inti=0;i{indices[((ring*torusPrecision+i)*2)*3+0]=ring*(torusPrecision+1)+i;indices[((ring*torusPrecision+i)*2)*3+1]=(ring+1)*(torusPrecision+1)+i;indices[((ring*torusPrecision+i)*2)*3+2]=ring*(torusPrecision+1)+i+1;indices[((ring*torusPrecision+i)*2+1)*3+0]=ring*(torusPrecision+1)+i+1;indices[((ring*torusPrecision+i)*2+1)*3+1]=(ring+1)*(torusPrecision+1)+i;indices[((ring*torusPrecision+i)*2+1)*3+2]=(ring+1)*(torusPrecision+1)+i+1;}}returntrue;}以上代码实现的圆环效果是在CPU中运行得到的,它渲染的凹凸效果如下所示:CPU上的效率没有GPU运行效率高,还是建议读者在GPU中实现出来,最后把在GPU中实现的Shader代码给读者展示一下:[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片//矩阵float4x4g_matWorld:World;float4x4g_matWorldView:WorldView;float4x4g_matWorldViewProj:WorldViewProj;float4x4g_matInverWorldView:InverseWorldView;//灯光float4g_LightPositionViewSpace;floatg_OneOverSqrLightRadius;float4g_EyePosition;//材质floatg_MaterialAmbient;floatg_MaterialDiffuse;floatg_MaterialSpecular;floatg_MaterialEmissive;floatg_MaterialShininess;//纹理图片textureg_texEnvMap;textureg_texNormalMap;textureg_texHeightMap;floatg_fReflectivity=0.5f;floatg_fScale=0.04f;//[0,0.05]staticfloatg_fBias=g_fScale*0.5f;//---------------------------------------------------------------//Sampler//---------------------------------------------------------------samplerg_EnvMapSampler=sampler_state{Texture=;MinFilter=Linear;MagFilter=Linear;MipFilter=Linear;};samplerg_NormalMapSampler=sampler_state{Texture=(g_texNormalMap);MinFilter=Linear;MagFilter=Linear;MipFilter=Linear;};samplerg_HeightMapSampler=sampler_state{Texture=(g_texHeightMap);MinFilter=Linear;MagFilter=Linear;MipFilter=Linear;};//---------------------------------------------------------------//Utilities//---------------------------------------------------------------halfCalAttenuation(half3lightVec){returnsaturate(1-dot(lightVec,lightVec)*g_OneOverSqrLightRadius);}float3x3CalInvertMatrix3X3(float3x3M){floatdet=dot(cross(M[0],M[1]),M[2]);float3x3T=transpose(M);returnfloat3x3(cross(T[1],T[2]),cross(T[2],T[0]),cross(T[0],T[1]))/det;}//计算TBN矩阵float3x3CalTangentFrame(float3N){float3binormal;float3tangent;float3c1=cross(N,float3(0.0,0.0,1.0));float3c2=cross(N,float3(0.0,1.0,0.0));if(length(c1)>length(c2)){tangent=c1;}else{tangent=c2;}tangent=normalize(tangent);binormal=cross(N,tangent);binormal=normalize(binormal);returnfloat3x3(tangent,binormal,N);}float3CalReflect(float4position,float3normal){float3Normal=mul(normalize(normal),g_matWorld);float3PosWorld=mul(ition,g_matWorld);float3ViewDir=normalize(PosWorld-g_EyePosition.xyz);//returnrefract(ViewDir,Normal,.99);returnreflect(ViewDir,Normal);}//---------------------------------------------------------------//vertex&pixelshader//---------------------------------------------------------------structVS_OUTPUT_ENV{float4position:POSITION;float3texRefCoord:TEXCOORD0;};VS_OUTPUT_ENVVS_EnvMapping(float4position:POSITION,float3normal:NORMAL){VS_OUTPUT_ENVOUT=(VS_OUTPUT_ENV)0;OUT.position=mul(position,g_matWorldViewProj);OUT.texRefCoord=CalReflect(position,normal);returnOUT;}float4PS_EnvMapping(float3tex:TEXCOORD0):COLOR0{returng_fReflectivity*texCUBE(g_EnvMapSampler,tex);}//---------------------------------------------------------------structVS_OUTPUT{float4position:POSITION;float3normal:TEXCOORD0;float2texCoord:TEXCOORD1;float3worldViewPos:TEXCOORD2;float3texRefCoord:TEXCOORD3;};VS_OUTPUTVS_NormalMapping(float4pos:POSITION,float3normal:NORMAL,float2texCoord:TEXCOORD0){VS_OUTPUToutData=(VS_OUTPUT)0;outData.position=mul(pos,g_matWorldViewProj);outData.normal=normalize(mul(normal,(float3x3)g_matWorldView));outData.texCoord=texCoord;outData.worldViewPos=mul(pos,g_matWorldView).xyz;outData.texRefCoord=CalReflect(pos,normal);returnoutData;}float4PS_Phong(VS_OUTPUTinData):COLOR0{half3lightVec=g_LightPositionViewSpace-inData.worldViewPos;half3eyeVec=-inData.worldViewPos;half3normal=normalize(inData.normal);half3lightDir=normalize(lightVec);half3eyeDir=normalize(eyeVec);half3halfDir=normalize(eyeDir+lightDir);half3light=lit(dot(lightDir,normal),dot(halfDir,normal),g_MaterialShininess);halfatten=CalAttenuation(lightVec);float4Id=light.y*g_MaterialDiffuse;float4Is=light.z*g_MaterialSpecular;float4envColor=g_fReflectivity*texCUBE(g_EnvMapSampler,inData.texRefCoord);float4Ia=envColor*g_MaterialAmbient;return(Ia+Id+Is)*atten*envColor;}float4PS_NormalMapping(VS_OUTPUTinData):COLOR0{half3lightVec=g_LightPositionViewSpace-inData.worldViewPos;half3eyeVec=-inData.worldViewPos;//getthenormalmnormalmaphalf3normal=normalize(tex2D(g_NormalMapSampler,inData.texCoord).xyz*2.0-1.0);//transformthevectorfromworldspacetotangentspacefloat
vertices[ring*(torusPrecision+1)+i].position=vertices[i].position.GetRotatedY(ring*360.0f/torusPrecision);
vertices[ring*(torusPrecision+1)+i].s=2.0f*ring/torusPrecision;
vertices[ring*(torusPrecision+1)+i].t=vertices[i].t;
vertices[ring*(torusPrecision+1)+i].sTangent=vertices[i].sTangent.GetRotatedY(ring*360.0f/torusPrecision);
vertices[ring*(torusPrecision+1)+i].tTangent=vertices[i].tTangent.GetRotatedY(ring*360.0f/torusPrecision);
vertices[ring*(torusPrecision+1)+i].normal=vertices[i].normal.GetRotatedY(ring*360.0f/torusPrecision);
//calculatetheindices
for(intring=0;ring{for(inti=0;i{indices[((ring*torusPrecision+i)*2)*3+0]=ring*(torusPrecision+1)+i;indices[((ring*torusPrecision+i)*2)*3+1]=(ring+1)*(torusPrecision+1)+i;indices[((ring*torusPrecision+i)*2)*3+2]=ring*(torusPrecision+1)+i+1;indices[((ring*torusPrecision+i)*2+1)*3+0]=ring*(torusPrecision+1)+i+1;indices[((ring*torusPrecision+i)*2+1)*3+1]=(ring+1)*(torusPrecision+1)+i;indices[((ring*torusPrecision+i)*2+1)*3+2]=(ring+1)*(torusPrecision+1)+i+1;}}returntrue;}以上代码实现的圆环效果是在CPU中运行得到的,它渲染的凹凸效果如下所示:CPU上的效率没有GPU运行效率高,还是建议读者在GPU中实现出来,最后把在GPU中实现的Shader代码给读者展示一下:[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片//矩阵float4x4g_matWorld:World;float4x4g_matWorldView:WorldView;float4x4g_matWorldViewProj:WorldViewProj;float4x4g_matInverWorldView:InverseWorldView;//灯光float4g_LightPositionViewSpace;floatg_OneOverSqrLightRadius;float4g_EyePosition;//材质floatg_MaterialAmbient;floatg_MaterialDiffuse;floatg_MaterialSpecular;floatg_MaterialEmissive;floatg_MaterialShininess;//纹理图片textureg_texEnvMap;textureg_texNormalMap;textureg_texHeightMap;floatg_fReflectivity=0.5f;floatg_fScale=0.04f;//[0,0.05]staticfloatg_fBias=g_fScale*0.5f;//---------------------------------------------------------------//Sampler//---------------------------------------------------------------samplerg_EnvMapSampler=sampler_state{Texture=;MinFilter=Linear;MagFilter=Linear;MipFilter=Linear;};samplerg_NormalMapSampler=sampler_state{Texture=(g_texNormalMap);MinFilter=Linear;MagFilter=Linear;MipFilter=Linear;};samplerg_HeightMapSampler=sampler_state{Texture=(g_texHeightMap);MinFilter=Linear;MagFilter=Linear;MipFilter=Linear;};//---------------------------------------------------------------//Utilities//---------------------------------------------------------------halfCalAttenuation(half3lightVec){returnsaturate(1-dot(lightVec,lightVec)*g_OneOverSqrLightRadius);}float3x3CalInvertMatrix3X3(float3x3M){floatdet=dot(cross(M[0],M[1]),M[2]);float3x3T=transpose(M);returnfloat3x3(cross(T[1],T[2]),cross(T[2],T[0]),cross(T[0],T[1]))/det;}//计算TBN矩阵float3x3CalTangentFrame(float3N){float3binormal;float3tangent;float3c1=cross(N,float3(0.0,0.0,1.0));float3c2=cross(N,float3(0.0,1.0,0.0));if(length(c1)>length(c2)){tangent=c1;}else{tangent=c2;}tangent=normalize(tangent);binormal=cross(N,tangent);binormal=normalize(binormal);returnfloat3x3(tangent,binormal,N);}float3CalReflect(float4position,float3normal){float3Normal=mul(normalize(normal),g_matWorld);float3PosWorld=mul(ition,g_matWorld);float3ViewDir=normalize(PosWorld-g_EyePosition.xyz);//returnrefract(ViewDir,Normal,.99);returnreflect(ViewDir,Normal);}//---------------------------------------------------------------//vertex&pixelshader//---------------------------------------------------------------structVS_OUTPUT_ENV{float4position:POSITION;float3texRefCoord:TEXCOORD0;};VS_OUTPUT_ENVVS_EnvMapping(float4position:POSITION,float3normal:NORMAL){VS_OUTPUT_ENVOUT=(VS_OUTPUT_ENV)0;OUT.position=mul(position,g_matWorldViewProj);OUT.texRefCoord=CalReflect(position,normal);returnOUT;}float4PS_EnvMapping(float3tex:TEXCOORD0):COLOR0{returng_fReflectivity*texCUBE(g_EnvMapSampler,tex);}//---------------------------------------------------------------structVS_OUTPUT{float4position:POSITION;float3normal:TEXCOORD0;float2texCoord:TEXCOORD1;float3worldViewPos:TEXCOORD2;float3texRefCoord:TEXCOORD3;};VS_OUTPUTVS_NormalMapping(float4pos:POSITION,float3normal:NORMAL,float2texCoord:TEXCOORD0){VS_OUTPUToutData=(VS_OUTPUT)0;outData.position=mul(pos,g_matWorldViewProj);outData.normal=normalize(mul(normal,(float3x3)g_matWorldView));outData.texCoord=texCoord;outData.worldViewPos=mul(pos,g_matWorldView).xyz;outData.texRefCoord=CalReflect(pos,normal);returnoutData;}float4PS_Phong(VS_OUTPUTinData):COLOR0{half3lightVec=g_LightPositionViewSpace-inData.worldViewPos;half3eyeVec=-inData.worldViewPos;half3normal=normalize(inData.normal);half3lightDir=normalize(lightVec);half3eyeDir=normalize(eyeVec);half3halfDir=normalize(eyeDir+lightDir);half3light=lit(dot(lightDir,normal),dot(halfDir,normal),g_MaterialShininess);halfatten=CalAttenuation(lightVec);float4Id=light.y*g_MaterialDiffuse;float4Is=light.z*g_MaterialSpecular;float4envColor=g_fReflectivity*texCUBE(g_EnvMapSampler,inData.texRefCoord);float4Ia=envColor*g_MaterialAmbient;return(Ia+Id+Is)*atten*envColor;}float4PS_NormalMapping(VS_OUTPUTinData):COLOR0{half3lightVec=g_LightPositionViewSpace-inData.worldViewPos;half3eyeVec=-inData.worldViewPos;//getthenormalmnormalmaphalf3normal=normalize(tex2D(g_NormalMapSampler,inData.texCoord).xyz*2.0-1.0);//transformthevectorfromworldspacetotangentspacefloat
for(inti=0;i{indices[((ring*torusPrecision+i)*2)*3+0]=ring*(torusPrecision+1)+i;indices[((ring*torusPrecision+i)*2)*3+1]=(ring+1)*(torusPrecision+1)+i;indices[((ring*torusPrecision+i)*2)*3+2]=ring*(torusPrecision+1)+i+1;indices[((ring*torusPrecision+i)*2+1)*3+0]=ring*(torusPrecision+1)+i+1;indices[((ring*torusPrecision+i)*2+1)*3+1]=(ring+1)*(torusPrecision+1)+i;indices[((ring*torusPrecision+i)*2+1)*3+2]=(ring+1)*(torusPrecision+1)+i+1;}}returntrue;}以上代码实现的圆环效果是在CPU中运行得到的,它渲染的凹凸效果如下所示:CPU上的效率没有GPU运行效率高,还是建议读者在GPU中实现出来,最后把在GPU中实现的Shader代码给读者展示一下:[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片//矩阵float4x4g_matWorld:World;float4x4g_matWorldView:WorldView;float4x4g_matWorldViewProj:WorldViewProj;float4x4g_matInverWorldView:InverseWorldView;//灯光float4g_LightPositionViewSpace;floatg_OneOverSqrLightRadius;float4g_EyePosition;//材质floatg_MaterialAmbient;floatg_MaterialDiffuse;floatg_MaterialSpecular;floatg_MaterialEmissive;floatg_MaterialShininess;//纹理图片textureg_texEnvMap;textureg_texNormalMap;textureg_texHeightMap;floatg_fReflectivity=0.5f;floatg_fScale=0.04f;//[0,0.05]staticfloatg_fBias=g_fScale*0.5f;//---------------------------------------------------------------//Sampler//---------------------------------------------------------------samplerg_EnvMapSampler=sampler_state{Texture=;MinFilter=Linear;MagFilter=Linear;MipFilter=Linear;};samplerg_NormalMapSampler=sampler_state{Texture=(g_texNormalMap);MinFilter=Linear;MagFilter=Linear;MipFilter=Linear;};samplerg_HeightMapSampler=sampler_state{Texture=(g_texHeightMap);MinFilter=Linear;MagFilter=Linear;MipFilter=Linear;};//---------------------------------------------------------------//Utilities//---------------------------------------------------------------halfCalAttenuation(half3lightVec){returnsaturate(1-dot(lightVec,lightVec)*g_OneOverSqrLightRadius);}float3x3CalInvertMatrix3X3(float3x3M){floatdet=dot(cross(M[0],M[1]),M[2]);float3x3T=transpose(M);returnfloat3x3(cross(T[1],T[2]),cross(T[2],T[0]),cross(T[0],T[1]))/det;}//计算TBN矩阵float3x3CalTangentFrame(float3N){float3binormal;float3tangent;float3c1=cross(N,float3(0.0,0.0,1.0));float3c2=cross(N,float3(0.0,1.0,0.0));if(length(c1)>length(c2)){tangent=c1;}else{tangent=c2;}tangent=normalize(tangent);binormal=cross(N,tangent);binormal=normalize(binormal);returnfloat3x3(tangent,binormal,N);}float3CalReflect(float4position,float3normal){float3Normal=mul(normalize(normal),g_matWorld);float3PosWorld=mul(ition,g_matWorld);float3ViewDir=normalize(PosWorld-g_EyePosition.xyz);//returnrefract(ViewDir,Normal,.99);returnreflect(ViewDir,Normal);}//---------------------------------------------------------------//vertex&pixelshader//---------------------------------------------------------------structVS_OUTPUT_ENV{float4position:POSITION;float3texRefCoord:TEXCOORD0;};VS_OUTPUT_ENVVS_EnvMapping(float4position:POSITION,float3normal:NORMAL){VS_OUTPUT_ENVOUT=(VS_OUTPUT_ENV)0;OUT.position=mul(position,g_matWorldViewProj);OUT.texRefCoord=CalReflect(position,normal);returnOUT;}float4PS_EnvMapping(float3tex:TEXCOORD0):COLOR0{returng_fReflectivity*texCUBE(g_EnvMapSampler,tex);}//---------------------------------------------------------------structVS_OUTPUT{float4position:POSITION;float3normal:TEXCOORD0;float2texCoord:TEXCOORD1;float3worldViewPos:TEXCOORD2;float3texRefCoord:TEXCOORD3;};VS_OUTPUTVS_NormalMapping(float4pos:POSITION,float3normal:NORMAL,float2texCoord:TEXCOORD0){VS_OUTPUToutData=(VS_OUTPUT)0;outData.position=mul(pos,g_matWorldViewProj);outData.normal=normalize(mul(normal,(float3x3)g_matWorldView));outData.texCoord=texCoord;outData.worldViewPos=mul(pos,g_matWorldView).xyz;outData.texRefCoord=CalReflect(pos,normal);returnoutData;}float4PS_Phong(VS_OUTPUTinData):COLOR0{half3lightVec=g_LightPositionViewSpace-inData.worldViewPos;half3eyeVec=-inData.worldViewPos;half3normal=normalize(inData.normal);half3lightDir=normalize(lightVec);half3eyeDir=normalize(eyeVec);half3halfDir=normalize(eyeDir+lightDir);half3light=lit(dot(lightDir,normal),dot(halfDir,normal),g_MaterialShininess);halfatten=CalAttenuation(lightVec);float4Id=light.y*g_MaterialDiffuse;float4Is=light.z*g_MaterialSpecular;float4envColor=g_fReflectivity*texCUBE(g_EnvMapSampler,inData.texRefCoord);float4Ia=envColor*g_MaterialAmbient;return(Ia+Id+Is)*atten*envColor;}float4PS_NormalMapping(VS_OUTPUTinData):COLOR0{half3lightVec=g_LightPositionViewSpace-inData.worldViewPos;half3eyeVec=-inData.worldViewPos;//getthenormalmnormalmaphalf3normal=normalize(tex2D(g_NormalMapSampler,inData.texCoord).xyz*2.0-1.0);//transformthevectorfromworldspacetotangentspacefloat
indices[((ring*torusPrecision+i)*2)*3+0]=ring*(torusPrecision+1)+i;
indices[((ring*torusPrecision+i)*2)*3+1]=(ring+1)*(torusPrecision+1)+i;
indices[((ring*torusPrecision+i)*2)*3+2]=ring*(torusPrecision+1)+i+1;
indices[((ring*torusPrecision+i)*2+1)*3+0]=ring*(torusPrecision+1)+i+1;
indices[((ring*torusPrecision+i)*2+1)*3+1]=(ring+1)*(torusPrecision+1)+i;
indices[((ring*torusPrecision+i)*2+1)*3+2]=(ring+1)*(torusPrecision+1)+i+1;
returntrue;
以上代码实现的圆环效果是在CPU中运行得到的,它渲染的凹凸效果如下所示:
CPU上的效率没有GPU运行效率高,还是建议读者在GPU中实现出来,最后把在GPU中实现的Shader代码给读者展示一下:
//矩阵
float4x4g_matWorld:
World;
float4x4g_matWorldView:
WorldView;
float4x4g_matWorldViewProj:
WorldViewProj;
float4x4g_matInverWorldView:
InverseWorldView;
//灯光
float4g_LightPositionViewSpace;
floatg_OneOverSqrLightRadius;
float4g_EyePosition;
//材质
floatg_MaterialAmbient;
floatg_MaterialDiffuse;
floatg_MaterialSpecular;
floatg_MaterialEmissive;
floatg_MaterialShininess;
//纹理图片
textureg_texEnvMap;
textureg_texNormalMap;
textureg_texHeightMap;
floatg_fReflectivity=0.5f;
floatg_fScale=0.04f;//[0,0.05]
staticfloatg_fBias=g_fScale*0.5f;
//---------------------------------------------------------------
//Sampler
samplerg_EnvMapSampler=sampler_state
Texture=;
MinFilter=Linear;
MagFilter=Linear;
MipFilter=Linear;
samplerg_NormalMapSampler=sampler_state
Texture=(g_texNormalMap);
samplerg_HeightMapSampler=sampler_state
Texture=(g_texHeightMap);
//Utilities
halfCalAttenuation(half3lightVec)
returnsaturate(1-dot(lightVec,lightVec)*g_OneOverSqrLightRadius);
float3x3CalInvertMatrix3X3(float3x3M)
floatdet=dot(cross(M[0],M[1]),M[2]);
float3x3T=transpose(M);
returnfloat3x3(
cross(T[1],T[2]),
cross(T[2],T[0]),
cross(T[0],T[1]))/det;
//计算TBN矩阵
float3x3CalTangentFrame(float3N)
float3binormal;
float3tangent;
float3c1=cross(N,float3(0.0,0.0,1.0));
float3c2=cross(N,float3(0.0,1.0,0.0));
if(length(c1)>length(c2))
tangent=c1;
else
tangent=c2;
tangent=normalize(tangent);
binormal=cross(N,tangent);
binormal=normalize(binormal);
returnfloat3x3(tangent,binormal,N);
float3CalReflect(float4position,float3normal)
float3Normal=mul(normalize(normal),g_matWorld);
float3PosWorld=mul(ition,g_matWorld);
float3ViewDir=normalize(PosWorld-g_EyePosition.xyz);
//returnrefract(ViewDir,Normal,.99);
returnreflect(ViewDir,Normal);
//vertex&pixelshader
structVS_OUTPUT_ENV
float4position:
POSITION;
float3texRefCoord:
TEXCOORD0;
VS_OUTPUT_ENVVS_EnvMapping(float4position:
POSITION,float3normal:
NORMAL)
VS_OUTPUT_ENVOUT=(VS_OUTPUT_ENV)0;
OUT.position=mul(position,g_matWorldViewProj);
OUT.texRefCoord=CalReflect(position,normal);
returnOUT;
float4PS_EnvMapping(float3tex:
TEXCOORD0):
COLOR0
returng_fReflectivity*texCUBE(g_EnvMapSampler,tex);
structVS_OUTPUT
float3normal:
float2texCoord:
TEXCOORD1;
float3worldViewPos:
TEXCOORD2;
TEXCOORD3;
VS_OUTPUTVS_NormalMapping(float4pos:
NORMAL,float2texCoord:
TEXCOORD0)
VS_OUTPUToutData=(VS_OUTPUT)0;
outData.position=mul(pos,g_matWorldViewProj);
outData.normal=normalize(mul(normal,(float3x3)g_matWorldView));
outData.texCoord=texCoord;
outData.worldViewPos=mul(pos,g_matWorldView).xyz;
outData.texRefCoord=CalReflect(pos,normal);
returnoutData;
float4PS_Phong(VS_OUTPUTinData):
half3lightVec=g_LightPositionViewSpace-inData.worldViewPos;
half3eyeVec=-inData.worldViewPos;
half3normal=normalize(inData.normal);
half3lightDir=normalize(lightVec);
half3eyeDir=normalize(eyeVec);
half3halfDir=normalize(eyeDir+lightDir);
half3light=lit(dot(lightDir,normal),dot(halfDir,normal),g_MaterialShininess);
halfatten=CalAttenuation(lightVec);
float4Id=light.y*g_MaterialDiffuse;
float4Is=light.z*g_MaterialSpecular;
float4envColor=g_fReflectivity*texCUBE(g_EnvMapSampler,inData.texRefCoord);
float4Ia=envColor*g_MaterialAmbient;
return(Ia+Id+Is)*atten*envColor;
float4PS_NormalMapping(VS_OUTPUTinData):
//getthenormalmnormalmap
half3normal=normalize(tex2D(g_NormalMapSampler,inData.texCoord).xyz*2.0-1.0);
//transformthevectorfromworldspacetotangentspace
float
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1