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 没有这个问题!!!