图形学-几何-阴影原理

 

这是游戏“古墓丽影”中人物的阴影,给人一种人物跟地面接触的真实感。

所有着色点的直线光、漫反射和环境光的光栅化计算都是不考虑遮挡的局部关系,而如果要考虑遮挡,从投影的角度计算出阴影,光栅化将非常复杂。

因此我们另辟蹊径,从另一个角度来看待阴影,即:

阴影就是摄像机能看到,但光线看不到的区域

就是说,我们在光源的位置再放一台摄像机,看向场景,这是角度一;从真正的摄像机看向场景,是角度二。

角度一和角度二做一个对比,角度一“看不到”而角度二“看得到”的区域(像素),即认为是阴影。

 

 

 

 

 如何做对比呢?

 

 

 如图所示,从光源的角度看向物体,我们可以得到一张“深度贴图”,记录每个物体的深度值,这张深度图叫做Shading Mapping

 

 

 然后我们再从真正摄像机的角度看向物体,得到的着色点和光源的距离,反对应到Shading Mapping上记录的深度。

 

如果深度不一致则认为被阻挡了,即这个地方(像素)会产生阴影。

 

 

 

 

如图,绿色部分光源和着色点距离=Shading Map上的深度;非绿色部分不等于,可以认为被阻挡了。白色区域即被阻挡又在地面上,则认为是阴影。

基于Shading Map,计算出来着色点要么阻挡要么非阻挡,所有得到的阴影具有两个特征,即:

1.一片阴影看起来都是一样的,没有渐变;

2.边缘很明显。

我们管这种阴影叫做硬阴影

 

 

 左图为塞尔达荒野之息,人物的阴影为硬阴影;有图为马里奥,人物的阴影为软阴影。

 

我们回看这张绿图,为什么被看到的部分仍然会有一些脏脏的黑色?是因为基于Shading Map的硬阴影计算存在几个“硬伤”:

硬伤一.走样问题:

1 基于光栅化,如果Shading Map的精度不够,一个像素表示多个逻辑点,这些到光源的位置实际上会有微小差异,但在Shading Map中却是同样的深度值;

2 浮点数的对比是很困难的。

这就造成了,有些点明明没有被阻挡,却计算出被阻挡了;有些被阻挡了,却计算出没被阻挡。

例如一个点到光源的真实距离是2.0,真实深度也是2.0,按理说是没有被阻挡的。但是由于Shading Map精度不够,这个点所在的像素深度是1.9,小于距离,则被认为值阻挡;即使精度够,两个都是2.0,但在一些CPU上深度的2.0当成了1.99999,又小于距离了。

硬伤二.Shading Map只能做硬阴影。

如果想做软阴影,先理解一下软阴影的原理。

 

上面的是硬阴影,下面的是软阴影。

以日全食为例,太阳是个大光源,月亮是个小阻挡,光线照到地球上,有一小部分完全被月亮阻挡了,看不到任何光线,这块区域称为本影Umbra;有一块比较大的区域,能看到部分的阳光,这块区域称为半影Penumbra

软阴影我们即认为是半影。

posted @ 2022-04-23 17:35  银龙背上的骑士  阅读(521)  评论(0编辑  收藏  举报