自从实时阴影发展到了shadowmap时代,漏光和 Shadow Acne就形影不离。除非你可以无脑极大提升shadowmap精度 或可以做到很短距离的实时阴影 否则并不好解决这常见问题。如下图
我早年在网易引擎部面试的时候 总监大佬问过我这问题。我当年很得意,告诉他我自创并实现过demo的做法,计算shadowmap 不仅写入深度 也写入 投影表面的世界法线(或投影表面的SV_PrimitiveID 这个更省空间),这样绘制阴影的时候就能根据自己表面的世界法线 是否与投影表面接近来判断 是否自己投影给自己 如果是bias算的大些 否则算的小些。因为既然bias 固定数值都不行,那就实现动态bias,这样逻辑上就成立。大佬冷静的说,shadowmap本身就精度不足 你同尺寸数据也不能提升太多。(实际测试确实提升不太大),他接着小心翼翼地问道:你就不能在屏幕空间想想办法?当年的我除了ssao模仿的实现一次 根本没灵活掌握各种其他SS技巧而且也没经验,于是答不出来。但是看得出他的小心翼翼 仿佛再问一句就会泄露做法一般,我就印象深刻的记下:这个点可能很容易想出来有时间了就去尝试。现在刚好是时候了。
我想到屏幕空间上一个像素可以根据深度图去检查,他往光线方向上短距离内是否有遮挡物,如果有那么应该有阴影。于是我选择把bias调大,如上图左图,然后想办法去把漏的光补上。没有选自阴影出错然后 把阴影消去是因为,投影者不一定就在附近所以不能简单的消去阴影。但是 漏光处如果有投影一定是在附近所以更好查询。先看效果很不错。
这么大的提升 代码量居然只要6句 采样的也是已有的深度图性能基本没问题.代码直接带详细说明。简单测试函数就写在了 LightingMyStandard_GI 内,根据实际项目可放屏幕阴影计算shader,任何地方只要能获取世界坐标就可以
如果虚拟投影物 被遮挡 就算真有遮挡物 阴影为黑色 ,实际项目 最好转到 Linear01Depth(depth) * _ProjectionParams.z 比较真实距离 和 有效范围内才算遮挡
声明:发布此文是出于传递更多知识以供交流学习之目的。若有来源标注错误或侵犯了您的合法权益,请作者持权属证明与我们联系,我们将及时更正、删除,谢谢。
作者:jackie
原文:https://zhuanlan.zhihu.com/p/205855471
More:【微信公众号】 u3dnotes
本文分享自微信公众号 - Unity3D游戏开发精华教程干货(u3dnotes)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。