本文文件下载

首先看效果图

image

概述

创建一个充当玻璃的Cube(带有MainTex和BumpTex). 用GrabPass绘制当前屏幕的渲染纹理, 在后续Pass中用采样得到的法线对采样坐标进行偏移, 然后再采样渲染纹理, 此为折射. 反射就没什么好说的了, 用反射光线采样Cubemap即可. 上面提到的"采样坐标"实际上是个二维坐标, 即屏幕坐标. (NDC坐标根据分辨率大小生成屏幕坐标).

实现

先看需要的properties

image

前三个没什么好说的. distortion控制折射时图像的扭曲程度(与法线相配合). refraction amount用于控制折射程度. 为1时全折射, 为0时全反射.

GrabPass是一个Pass, 在这个Pass中Unity会为我们生成一张当前屏幕的渲染纹理, 给之后的Pass使用.

GrabPass的使用很简单, 只需要一行代码, 不过, 在本例中, 实现玻璃效果也属于透明效果的一种, 所以最好在Tags中指定为Transparent, 保证其他所有不透明的物体都渲染完毕了. 也即: 其他东西都渲染完了, 然后使用GrabPass生成场景对应的渲染纹理, 用于折射采样.

image

关于这里的RenderType:

image

作者在书中提到, 这里设置这个RenderType是为了在使用着色器替换(Shader Replacement)的时候, 该物体可以在需要的时候被正确渲染. 这通常发生在我们需要得到摄像机的深度和法线纹理时.

接着在后面的Pass中准备好变量

image

顶点着色器和我们前面写的标准着色器差别不大, 多了一个scr_pos, 也就是我们前面提到的用于采样渲染纹理的二维坐标.

image
image

片元着色器, 思路很清晰.

image

关于GrabPass

image

渲染纹理 vs GrabPass

image