屏幕UV
案例
- 左边:模型边缘没有畸变,整个平铺在模型上,不管模型远近,纹理和模型的比例不变
- 右边:彩色玻璃效果。扰动背景的效果。
代码实现
- 给屏幕纹理的TillingAndOffset的功能做一个改进:想用Offset的值变为持续的速度而不是一个平移的常量。
- 观察空间就是以摄像机为基准的空间,xy轴即屏幕横纵坐标,z轴为深度。
- 但如果直接用转换到观察空间的xy轴采样纹理,纹理在模型边缘会产生畸变。
- 如何矫正畸变?
1、顶点在观察空间的xy/z,使每个顶点都使用同一z深度的纹理。
2、要使纹理大小按物体z深度变化、与物体大小相对锁定,取模型原点,在模型空间为(0,0,0)。屏幕UV乘以模型原点在观察空间的z值即可。 - 若想让屏幕纹理支持TillingAndOffset,在顶点shader采样uv = Transform_Tex();即可,但我们不想要普通的TillingAndOffset,而是想要_Screnn_ST的zw值为流动的速度,所以要用另外的方法。
核心代码分析
屏幕扰动
1 案例
- 需要一张RampTex,定义折射程度,这里使用背景纹理。
2 代码实现
- 一个灰度值扰动的弊端:xy都用同一个值做扰动,对角线感强烈。但项目中扰动很费,所以尽量用一个通道。
- 黑盒GrabPass:渲染小人之前把背景存成一张图,渲染小人时再用屏幕坐标UV把这张图贴回去。要在Pass中拿到这张图,声明这张图(名字)即可。
- 顶点shader黑盒:o.grabPos = ComputeGrabScreenPos(o.pos);
- 像素shader黑盒:half3 var_BGTex = tex2Dproj(_BGTex, i.grabPos).rgb;
- 黑盒的内容自己也可以写,但是要做兼容性适配,而且随着版本升级可能会有问题,而unity的黑盒会处理这些问题。
- 扭曲中值是为了使扭曲有正有负。
- 像素shader中,GrabPass.xy乘Opacity是为了使不 透明度和扭曲联动,越透明扭曲越小。(越透明说明模型越不存在,扭曲就越小)
3 核心代码分析
- Unity拿GrabPass是非常费的操作,更建议用ppt中的其它方法去拿到背景纹理。