游戏开发论坛

 找回密码
 立即注册
搜索
查看: 3700|回复: 0

d3d创建平行光阴影 结果不正确 麻烦大神看看哪里不对

[复制链接]

3

主题

7

帖子

12

积分

新手上路

Rank: 1

积分
12
发表于 2012-10-17 11:23:00 | 显示全部楼层 |阅读模式
效果可编程流水线内容如下:
//坐标矩阵
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 );
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-2-27 13:16

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表