天天看点

shadow map 阴影图算法的思考

       shadow map 以前早就研究过,不过一次不小心把以前做的东西都弄丢了,今天重新做了一下,

加到了系统里,给大家看下效果:)

shadow map 阴影图算法的思考

shadow map算法原理很简单,先简单介绍下算法给新人:

1.以光源所在位置为观察点渲染场景(可以只渲染需要产生阴影的物体)将渲染后的深度值保存深度图(一张事先准备好的纹理)。

在此步需要注意的是 此次渲染用到的模型观视投影矩阵(以后简称mvp)需要保存一下,下一步要用到。

2.正常渲染场景,将顶点坐标乘以步骤一时候的mvp,将坐标变换到以光源为观察点的坐标系里,比较z值和从深度图中读出来的

值得大小判断遮挡,有遮挡的话将输出颜色减弱或者换成别的随笔你了。其中有个地方需要注意,如何从深度图纹理中读数据,

这个我是这么解决的:float2 suv = ((spos.xy/spos.z))//其中spos是变换到光源坐标系下的顶点数据,得到的suv经过处理后可以

当做深度图的纹理坐标值,读取方法为float4 shadow = tex2D(t11,(suv+1.0)*0.5),其中用到一个【-1,1】到【0,1】的变换。

剩下的就是比较了  :

            float sz =  1 - spos.z/(gDepthSize);//将深度值变换到【0,1】区间,gDepthSize是获得深度纹理时渲染场景的最深值  

            //增加阴影

            if((sz < shadow.x))//sz是就是

            {

                color = color*(1 - shadow);

                color.w = 1.0;

                //color = float4(sz,sz,sz,1);

            }

//----------------------------------------------------------------------------------------------------------------------------

关于shadow map 算法的缺点,跟大家讨论一下:

永远的困扰shadow map的失真问题,当光源照射场景稍大的时候失真现象就会很严重,有些改进算法,但都觉得治标不治本。

如果说我整个场景有很多到处跑的人,那他们的阴影效果要怎样做呢???

感觉shadow map用在生成当前角色的阴影挺好,如果是大范围的不大适合。很多静态的物体可以先把阴影事先计算好,用的时候

直接读取,没有必要每帧都重新计算。

//----------------------------------------------------------------------------------------------------------------------------

shadow map 最大的好处是可以处理透明纹理的阴影,以为我的场景的树是用透明纹理画上去的,如果得到的阴影是个矩

形那就很怪了,幸好shadow map 没有这个问题!!!

继续阅读