|
效果可编程流水线内容如下:
//坐标矩阵
float4x4 matWorld;
float4x4 matCameraViewProj;
//float4x4 matshadowWorld;
float4x4 matLightViewProj;
//灯光
float4 vLightDir;
float4 lightAmbient;
float4 lightDiffuse;
float4 lightSpecular;
//阴影颜色
float4 ShadowColor = float4(0.0,0.0,0.0,0.5);
//相机位置
float4 vCameraPos;
//材质
float4 materialAmbient;
float4 materialDiffuse;
float4 materialSpecular;
//纹理
texture CurTexture;
texture ShadowMap;
//纹理采样器
sampler Scene_2D = sampler_state
{
Texture = <CurTexture>;
MinFilter = Point;
MagFilter = LINEAR;
MipFilter = LINEAR;
};
sampler Shadow_2D = sampler_state
{
Texture = <ShadowMap>;
MinFilter = Point;
MagFilter = Point;
MipFilter = Point;
AddressU = Clamp;//夹取寻址
AddressV = Clamp;
};
//////////////////////////////Phong光照
//CPos:当前世界坐标
//CNor:当前世界法线
float4 PhongLight(float4 CPos, float4 CNor) : COLOR
{
float sunshinepower;
sunshinepower = 2.0f;
float4 PosToCamera = normalize(vCameraPos - CPos);
//计算环境光
float4 Ambient = lightAmbient * materialAmbient; //材质可理解为反射系数
//计算漫反射
float DiffuseRatio = saturate(dot(CNor, vLightDir));
float4 Diffuse = lightDiffuse * (materialDiffuse * DiffuseRatio);
//计算镜面反射
float4 Reflect = normalize( 2 * DiffuseRatio * CNor - vLightDir);
float SpecularRatio = pow(saturate(dot(Reflect, PosToCamera)), sunshinepower);
float4 Specular = lightSpecular* (materialSpecular * SpecularRatio);
return (Ambient/* * 0.1*/ + Diffuse + Specular);
}
/////////////////////////////Scene渲染
struct VS_OUTPUT
{
float4 pos : POSITION; //Camera投影后位置
float4 color : COLOR; //
float2 tex : TEXCOORD0; //纹理坐标
float4 CPos : TEXCOORD1; //当前世界位置
float4 LPos : TEXCOORD2; //Light投影后位置
//float4 CameraPos : TEXCOORD3; //camera投影后位置
};
VS_OUTPUT VSScene(float4 pos : POSITION, float4 nor : NORMAL, float2 tex : TEXCOORD0)
{
VS_OUTPUT vout = (VS_OUTPUT)0;
vout.CPos = mul(pos,matWorld);
vout.pos = mul(vout.CPos,matCameraViewProj);
vout.tex = tex;
vout.LPos = mul(vout.CPos,matLightViewProj);
//vout.CameraPos = vout.pos;
float4 CNor = mul(nor,matWorld);
CNor = normalize(CNor);
vout.color = PhongLight(vout.CPos,CNor);
return vout;
}
float4 PSScene(VS_OUTPUT vout) : COLOR
{
//计算纹理颜色
float4 TexColor = tex2D(Scene_2D, vout.tex);//纹理颜色
float ShadowRatio = 0.0; //阴影着色因子
float ColorRatio = 0.0; //光照着色因子
float TexRatio = 0.0; //纹理着色因子
float2 STex = vout.LPos.xy/vout.LPos.w;
STex.x = 0.5 * STex.x + 0.5;
STex.y = 1.0 - ( 0.5 * STex.y + 0.5 );
//计算ShadowRatio
float SDepth = tex2D(Shadow_2D, STex);
float CDepth = vout.LPos.z/vout.LPos.w;
//">"表示处于阴影中
if(CDepth > SDepth+0.00005f)
{
ShadowRatio = 0.5; //自定义
ColorRatio = 0.0;
TexRatio = 1.0 - ShadowRatio;
}
else //处于阴影外
{
ShadowRatio = 0.0;
ColorRatio = 0.3;
TexRatio = 0.7;
}
float4 color = vout.color * ColorRatio + ShadowColor * ShadowRatio + TexColor * TexRatio;
return color;
}
//////////////////////////生成阴影
struct ShadowVS_OUT
{
float4 pos : POSITION;
float2 depth : TEXCOORD0;
};
ShadowVS_OUT VSShadow(float4 pos : POSITION)
{
ShadowVS_OUT sout = (ShadowVS_OUT)0;
float4 cPos = mul(pos, matWorld); //当前世界坐标
sout.pos = mul(cPos, matLightViewProj);
sout.depth.xy = sout.pos.zw;
return sout;
}
float4 PSShadow(ShadowVS_OUT sout):COLOR
{
return sout.depth.x / sout.depth.y;
}
technique SpecularLight
{
pass P0
{
VertexShader = compile vs_2_0 VSShadow();
PixelShader = compile ps_2_0 PSShadow();
}
pass P1
{
VertexShader = compile vs_2_0 VSScene();
PixelShader = compile ps_2_0 PSScene();
}
}
灯光已经实现,现在的问题是阴影ps阶段深度缓冲值一直判定为大于shadowmap里存的值,问题找不到很难受啊,还请大神看看问题所在。
这里用的以下灯光viewprojmat来替代点光源下的视图投影矩阵。
//生成灯光View矩阵
D3DXMatrixIdentity(&m_LightViewMat);
D3DXMatrixIdentity(&m_LightProjMat);
D3DXVECTOR3 vEye(-200.707f, 50.707f, -0.707f);
D3DXVECTOR3 vAt(-200.0f, 50.0f, 0.0f);
D3DXVECTOR3 vUp(0.0f,1.0f, 0.0f);
D3DXMatrixLookAtLH(&m_LightViewMat, &vEye, &vAt, &vUp);
D3DXMatrixOrthoLH(&m_LightProjMat,ShadowMap_SIZE,ShadowMap_SIZE,0.01f,1024.0f);
D3DXMatrixMultiply( &m_LightViewProjMat, &m_LightViewMat, &m_LightProjMat ); |
|