准备工作
使用Amplify Shader Editor自带的模型和贴图搭建了一个简单的场景:
搭建的简单场景
把周围的面片设置为静态对象,然后在场景中添加反射探针,为后边制作的玻璃提供反射。
反射探针烘焙出来的环境反射
实现逻辑
获取模型在屏幕上的坐标,然后通过法线贴图与屏幕坐标相加得出新的采样坐标,使用新的采样坐标对渲染的屏幕图像进行纹理采样,以实现折射效果。
换句话说,就是把渲染的图像通过一张法线贴图进行扭曲之后再显示出来。
shader设置
玻璃材质更适合使用Specular工作流,所以shader的Light Model设置为 Standard Specular。
因为最终显示的是扭曲之后的渲染图像,并不是真正的透明折射效果,所以shader的Render Type仍然是Opaque。
而我们想等场景里所有不透明的物体都渲染完了之后再渲染这此物体,确保截取的渲染图像里包含场景中完整的不透明物体,所以把shader的Render Queue设置为Transparent。
进入正题
创建一个名为Specular的颜色属性,和一个名为Smoothness的属性,分别连到shader对应的输入通道
保存之后的材质效果:
使用Grab Screen Position获取屏幕坐标,然后使用Component Mask缩小维度,只保留X和Y,然后链接到Grab Screen Color节点,对截取屏幕渲染的图像进行采样,然后链接给Albedo通道。
到此为止,我们实现了把截图的屏幕图像再显示出来的效果:
使用Texture Object加载一张法线贴图,然后被两个Texture Sample引用(多次引用同一张贴图,而不是使用两张贴图,更节省性能)。
Map1与屏幕坐标相加,得到的结果重新对屏幕图像进行采样,从而对图像产生扭曲。添加一个名为Distortion的属性(除以一个数值是为了缩小数值范围,我这里缩小了100倍),连到Map1的Scale,从而控制扭曲的强度。
Map2输入到shader的Normal通道,添加一个名为Bumpiness的属性,连到Map2的Scale,控制法线的强度。
屏幕渲染图像链接到Albedo之前再乘以一个颜色属性,方便对色彩进行控制。
效果演示
按照如下材质面板的设置,最终效果就是题图的样子了
Inspect最终效果
玻璃扭曲动态展示效果:
扭曲动态效果