Unity - Shader - Projector 高空云层底下透明阴影 - semitransparent shadow
Posted Jave.Lin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity - Shader - Projector 高空云层底下透明阴影 - semitransparent shadow相关的知识,希望对你有一定的参考价值。
文章目录
- 环境
- 1 - Semitransparent Shadow - Alpha Test + SoftShadow
- 2 - Projector - Fake Semitransparent Shadow
- 3 - shadow map + projector(解決projector投影穿透的问题,后续我再实现)
- Project
- References
环境
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 性能不好吧
- 可以用贴花
首先我们要理解贴花的原理
就是在某个 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
- URP Decal Project 不会有背面
如上图,我的文章我有提到优化方案的,可能我没有将示例放上来,不便于阅读到,抱歉
那么下面我将示例搬上来瞧瞧
注意我之前说的:治标不治本
为了直观理解,我给上示例
- 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
- U3D_2020.3.37f1_BRP_TestingSemitransparentShadow_AlphaTest
- U3D_2020.3.37f1_ShadowProjector_实现高空云层投影
- U3D_2020.3.37f1_ShadowProjector_with_CullingBackface_实现高空云层投影
References
unity shader有啥用
Shader就是在GPU上运行的程序叫做着色器程序(一般的程序在CPU上执行指令)。Unity Shader使用的是NVIDIA公司的Cg标准语言,可以处理顶点着色、像素着色任务。Unity中的游戏对象只要是可视的,就一定会调用shader渲染,最简单的shader就是diffuse类型,就是你给对象涂个什么颜色,这个对象在白光下就是什么颜色。
一般来讲游戏中的 材质=shader+贴图和其它数据,要想表现特殊的材质,比如镜面反射、水面、塑料等,就需要编程shader(Unity中有一些默认的shader)。 参考技术A Unity所有的渲染工作都离不开shader
以上是关于Unity - Shader - Projector 高空云层底下透明阴影 - semitransparent shadow的主要内容,如果未能解决你的问题,请参考以下文章