【Shader入土】Light光源的Bias

目录

Light.shadowBias

一、shadow acne现象

1、Unity阴影是如何产生的?

2、shadow mapping阴影映射图分辨率比实际游戏分辨率低为啥会导致shadow acne呢?

 二、peter panning现象

如何解决这个Pater Panning现象(物体和阴影分离现象)?


Light.shadowBias

public float shadowBias;

Description

Shadow mapping constant bias. 

Shadow caster surfaces are pushed by this world-space amount away from the light, to help prevent self-shadowing ("shadow acne") artifacts.

人话:阴影映射偏移常量值【我自己理解的翻译】

阴影施法者表面被这个世界空间的量推离光,以帮助防止自阴影(“暗影痤疮”)的手工艺品。(百度翻译)

------------------------------------------------------------------上面这些都不是很重要--------------------------------------------------------------------

参考文章:OpenGL基础之Shadow Mapping - DeepDream - 博客园     

一、shadow acne现象

仔细观察上图,会发现有一些很细小的波纹,是的,不是你眼花,这就是shadow acne现象,下面解释为什么会产生这种问题。

首先这是一个阴影问题,是由于shadow mapping阴影映射图分辨率比实际游戏分辨率低导致的问题。(如下步骤分析)

1、Unity阴影是如何产生的?

1、Unity会将摄像机移动到光源位置,且朝向一致,然后进行渲染一次,以此获取到物体在光源视角下的深度值,得到“阴影映射图”即shadow mapping。

2、摄像机回到原来的位置,进行渲染画面,比如渲染一个片元,将该片元坐标通过空间转换矩阵转到光源视角空间下,再转为裁剪坐标[-1,1]范围内,再映射到[0,1]范围内的坐标范围,我们称之为P坐标吧,用P坐标(x,y)来进行采样shadow mapping,获取光源视角下的该片元位置的深度值ShadowZ(注意不是该片元的深度值),然后P坐标是由该片元坐标转化而来的,其z值本身就是片元深度值Z,然后对比片元深度值Z和ShadowZ,若片元深度值Z大于ShadowZ,说明该片元处于阴影下。

上图中,可理解为是光源视角下的渲染图,很明显球体比底板的深度值更小,至于球体下方的片元肯定是处于阴影之下的。

切回摄像机视角,可以看到球体受光面的背面和其下底板都变暗了。

原因是那部分变暗的片元深度值比shadow mapping的还要大导致的,先将片元坐标转为以光源为坐标点的视角空间下(上面所说的光源视角指这个意思),然后转为[0,1]范围用这个坐标从shadow mapping采样的深度值比自身深度值要小,判定该片元是处于阴影下的。下图来更加明白地解释。

上图是针对B点片元渲染的,A点深度是从shadow mapping根据B点的光源视角空间下的坐标x,y采样获取的,B点深度是B点坐标z值。所以B点深度比A点深度大,因此B点在阴影内。

为什么是用光源视角空间下的B点坐标(x,y)采样shadow mapping呢?

因为shadow mapping就是从光源视角空间下渲染获得的一张纹理图,主要是存储深度值,所以用光源视角空间下的坐标来作为纹理坐标。

至此,你了解到了阴影的大致的产生过程,下面解释shadow acne现象的原因。

2、shadow mapping阴影映射图分辨率比实际游戏分辨率低为啥会导致shadow acne呢?

原因是由于shadow mapping分辨率比实际分辨率低,导致多个邻近的片元采样到的深度值是相同的,但是本应该是不一样的,而它们自身的深度值肯定也不一样,所以就产生了某些问题,还是举例吧。

假如有A,B两个邻近片元,A和B从shadow mapping采样到的深度值是0.5,A的深度值是0.501,B的深度值是0.499,那么A点在阴影下,B点不在阴影下,就出现了一个点是亮的,一个点是暗的,所以波纹效果就这样子出现了。

如上绿色线条即为将整体的片元实际深度值偏移后的结果,确保这些片元是比shadow mapping深度值要小的,才不会出现shadow acne现象。

注意,上面的画图和参考文章中的有所不同,至于为什么参考文章要这样子画图解释,可能那种会比较直观,我这种就是纯讲实际深度的。

 二、peter panning现象

左图是Bias为0的情况,右图是Bias开到了最大的效果,这就是另一个现象,阴影出问题了。

这是因为偏移导致一部分原本应该在阴影内的片元,也被偏移到了阴影之外了,如下图直观表达:

上图水平黑线还是指shadow mapping的深度值,以一片连续的片元而言,其实正常物体的阴影会有一部分消失就是指那些比较靠近物体的阴影,因为比较靠近物体的阴影的地面其深度值越接近于Shadow Mapping的深度值,但那时还是比shadow mapping深度值要大的,还处于阴影之内。而当shadow mapping深度值增大Bias值之后,就会比Shadow Mapping深度值小,而不处于阴影之内了。

随着Bias值逐渐增大,可以看到越靠近物体自身的会先消失,至于为什么是两边角落先消失,是由于长方体角落的Shadow Mapping深度值比中间的要大,这样当角落的shadow mapping深度值逐渐增大时 当长方体角落附近的地板shadow mapping深度值逐渐变小时(2020年10月9日修正),长方体角落会先于长方体中间的深度值大于底板深度值,而让角落下的底板高亮。

如何解决这个Pater Panning现象(物体和阴影分离现象)?

①从问题产生原因来看,就是因为偏移的太大了导致,所以可以减少Bias的值改动,只改到恰好可以解决Shadow Acne问题即可(越小越好)。

②可以增大物体自身的shadow mapping深度值,在生成shadow mapping图时,即摄像机移动到光源,然后渲染物体时,只进行渲染其背面,不渲染正面,因为背面的深度值肯定比正面的要大。(PS:在GAMES202就有提及采用的是正面深度和背面深度的中间深度进行参与阴影计算)  GAMES202-高质量实时渲染_哔哩哔哩_bilibili ​​​​​

 关于第二种方法在OpenGL好像是有,如上我所贴出的参考文章有讲到,而在Unity是如何做到的,目前还没有进行研究(留坑)

2022年1月15日更新:以下是完全错误的!以下是完全错误的!以下是完全错误的!

-------------2020年4月26日21:21:27-------更新-因为我突然意识到好像有点问题,所以改了与上面的话完全是相反的结论。

②可以减小物体自身的shadow mapping深度值,从而拉大底板与物体之前的深度差,在生成shadow mapping时,摄像机移动到光源,然后渲染物体时,只进行渲染正面,而不渲染背面,因为正面深度值更小,但本身就是这样子的。 

③另一些人说可以增大物体的厚度,而且要根据实际情况来增宽哪个轴的厚度。比如下方的图

但是这个现象不是立方体才最明显的,而是平面的阴影会很明显,因为平面的shadow mapping深度肯定比立体的要大的,导致当shadow mapping增大Bias值后,会直接大于大部分的底板深度值。

所以这种情况用立方体来替换平面会更好。

不是更好,而是完全能解决这个问题

④不对这个物体的Shadow mapping深度值进行偏移Bias值,既然是偏移导致的,那么干脆不偏移了,但是没找到有什么方法可以不进行偏移。(目前Unity我测试过好像不行)(留坑)

⑤偏移顶点坐标值来抵消Bias值的影响,但目前来看效果还是不行,有一个渲染上的问题无法解决如下图。

类似透明的部分就是偏移顶点产生的渲染问题,如果能把这个渲染剔除掉就算解决了。

所以目前关于立方体的Pater Panning现象还是没有比较好的方法解决,比较期待的是②方案。

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值