Unity - Shader - Projector 高空云层底下透明阴影 - semitransparent shadow


环境

unity : 2020.3.37f1
pipeline : BRP


1 - Semitransparent Shadow - Alpha Test + SoftShadow

这种方式我最早是在 cat like coding 博主的文章看到的,这种方式我自己亲自测试过
缺点:会有阴影抖动严重的现象

(其中的 dithering tex 可以参考我之前写的:Unity - 手动创建 dithering tex 3d

如下GIF
请添加图片描述

就算我故意将 精度拉低(将距离边缘,那么 shadow map 的应用精度就会低一些)

50 shadow distance
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

然后抖动的闪烁一样要不得
请添加图片描述


2 - Projector - Fake Semitransparent Shadow

这种方式

  • 缺点:投影穿透,可以参考我之前写的:Unity - Projector - 实时[假]阴影
  • 优点:可以精准控制像素颜色,alpha,还可以只绘制和 projector box 有碰撞的 mesh(shadow map 的方式会绘制整个灯管角度的 PV 部分的所有 mesh)

自己PS整一个云的剪影图,放到 projector 材质贴图即可
请添加图片描述

还可以修改颜色
在这里插入图片描述

穿透的缺点如下GIF
(就算我使用 表面法线 和 Projector 投影反向 来 dot 判断过滤,一样治标不治本,比如,两个 Cube,一上一下,projector 投影后,就算 clip(dot(N, -ProjectDir))后,两个 Cube 的顶部都同样出现投影,所以需要看你的项目实际情况是否适合)
请添加图片描述


我看到有小伙伴说到贴花,并且说,不会有背面效果,我的文章我有写解决方案的,只不过这种方案还是治标不本的,就算是 URP Decal Projector 也同样如此
在这里插入图片描述

那么我尝试回到这位小伙伴的三个为题:

  • 可以用贴花
  • URP Decal Projector 不会有背面
  • projector 性能不好吧
  1. 可以用贴花

首先我们要理解贴花的原理
就是在某个 project 投影视角下,给在内的网格重新绘制一个与 project 投影器有交集的部分
至于重新绘制有多重方法:
1. 整个网格重绘,将 projector下的屏幕坐标作为UV去采样贴花贴图就完事了,于 projector volume没有交集的部分 mask 掉
2. 甚至可以 rebuild 一个 和 project 投影器有交集的子网格,但是有点费CPU
3. 可以使用 depth buffer, normal buffer 来还原 world position 和 world normal,来控制需要重绘的像素 和 剔除背面
4. 更多的方式可以参看 puppet_mater 大佬的: Unity Shader-Decal贴花(SelfDecal,Alpha Blend,Mesh Decal,Projector,Deferred Decal)

第1种比较简单,易于实现,但是比较费
第2种费CPU,一般不使用,但是对 FS 最友好
第3种,有点 defferd 思想,但是再 forward 也可以拿到这两个 buffer,在比较轻松(低成本,低费)可以拿到这两个 buffer 的话,这种方式的效率是最高的,比如:URP 管线;这种方式也有一个问题:透明对象的没法处理(因为没写深度和normal)

而我使用的是 BRP 管线的 unity 使用的是 第1种

另外说一下,我之前在 2021 使用 URP 管线的时候,Decal 组件直接就叫:URP Decal Projector
在这里插入图片描述

  1. URP Decal Project 不会有背面
    在这里插入图片描述

如上图,我的文章我有提到优化方案的,可能我没有将示例放上来,不便于阅读到,抱歉
那么下面我将示例搬上来瞧瞧
请添加图片描述

注意我之前说的:治标不治本在这里插入图片描述
为了直观理解,我给上示例
请添加图片描述

  1. projector 性能不好吧

这个看具体我们是再什么管线使用什么方式来实现
我现在这里使用的是 BRP 的 projector 算是最简单的一种,也算是比较费的一种,费在哪,费在 DC, SetPassCall,和看不到的 顶点仍然执行了 VS 和 MASK 掉,却在同屏的 FS(没有被 ztest 和 stencil 剔除的Frag)

如果在 URP 下 Decal 性能会好一些


3 - shadow map + projector(解決projector投影穿透的问题,后续我再实现)

今天:2022/11/26 - 16:00 左右,突然想到,可以使用 shadow map + projector 方式来做处理比较完美的 半透明 阴影
原理就是:

  • projector 视角生成 shadow map
  • projector 的投影 shader 可以自己采样 shadow map 做是否在阴影的判断,不在阴影的,才处理 projector 叠加绘制
  • (后续我再实现,现在木有空,-_-~)

总结如果视角比较偏某个角度,利用灯光角度于 projector 同步,选用 projector
alpha test + software 的闪烁我是怎么也接受不了

(期待后续了解有其他的方式来制作,已经在 2022/11/26 - 16:00 左右 想到第3中方式,后续再实现)


Project


References

猜你喜欢

转载自blog.csdn.net/linjf520/article/details/128011840