URP | Deacl 贴花效果

效果
贴花效果

实现原理
前计算出裁剪空间位置信息,转换到世界空间
计算世界空间的位置信息。 做一个透视除法,转换到物体空间。
在物体空间内部,计算出场景物体相交的物体。
在物体空间内部,输入纹理平铺到世界空间什么方向(Z)。
Shader Graphs实现
使用深度计算出相交

计算出显示,显示范围有多大

计算纹理UV

代码实现
准备基础Shader
顶点着色器
片元结构体 增加我们需要的属性
输出
sstexcoord 屏幕UV
cam2vertexRayOS 相机空间的射线
cameraPosOS 相机空间下模型顶点位置
获取深度图

顶点着色器阶段
计算出屏幕UV[0-1]
计算相机空间下的模型顶点坐标
注意:相机空间转换到模型空间下,使用了V的逆矩阵和M的逆矩阵进行计算,但是它是向量,所以得忽略掉平移矩阵,故float4(posVS.xyz,0)后面得取0,而不是1。
扩展 空间转换方式
我们取到的模型空间下的射线,它是模型的顶点从模型坐标系转到相机坐标系下,然后忽略了平移矩阵后,又从相机坐标系转回模型坐标系。那有没有这种可能,只计算模型坐标系转到相机坐标系的平移矩阵,不用费力绕了一大圈又计算回来?我们可以自行推导该想法的正确性。
先说明下这里需要使用的矩阵。

然后我们的射线Ray和模型顶点坐标POS的计算式如下

这里看似可以直接把对应的矩阵直接消掉
片元着色器
前获取屏幕深度
cam2vertexRayOS 检测射线,需要透视除法。
在计算出 贴花空间的坐标= 模型空间的相机坐标+模型空间的射线 * 屏幕深度
效果

移动物体,我们可以看到UV在变化。

本质是和模型坐标系一致,不过它是沿着屏幕深度进行贴合采样。
我们在看一下,发现这个uv和我们贴图UV是不一致的,那怎么解决这个问题。

效果

我们目前看到,UV平铺出去了,所以,我们需要裁减一下。
创建一个Mask 裁减掉不需要的
效果

然后放到立体的侧面的时候,会出现拉伸这不是我们想要的。

那我们在做一个限制
效果

整理
我们是在alpha处理调整
整理到alpha
我们现在看效果是错误的,又回到

我们需要给alpha做一个剔除

完成

因为我们是加到场景需要增加 一个是场景雾效,一个是漫反射颜色。
全代码
总结
主要难点在空间空间转换阶段,容易出现错误,

第二部分,采样UV不是 xy 是xz

第三部分,计算遮罩

资料参考
URP下屏幕空间贴花(ScreenSpaceDecal)学习笔记 | 烟雨迷离半世殇的成长之路 (lfzxb.top)