publicclassCamToTexture : MonoBehaviour { private Material mat;
public Shader shader; publicbool useSSR = true; // Start is called before the first frame update voidStart() { GetComponent<Camera>().depthTextureMode = DepthTextureMode.Depth; } public Material material { get { mat = CheckShaderAndCreateMaterial(shader, mat); return mat; } } privatevoidOnRenderImage(RenderTexture src, RenderTexture dest) { if (useSSR) Graphics.Blit(src, dest, material); else Graphics.Blit(src, dest); Shader.SetGlobalMatrix("_NormalWorldToView", GetComponent<Camera>().worldToCameraMatrix.inverse.transpose); } }
在顶点着色器中,首先通过uv坐标计算出裁剪坐标,z坐标设置为远裁剪平面的位置\(1\),再用投影逆变换把每个fragment的view space坐标计算出来(\(P^{-1} \cdot P \cdot V \cdot M \cdot \vec{p}\)),然后同样进行透视除法(逆矩阵同样会对\(w\)分量造成影响,很好理解)
1 2 3 4 5
// uv -> clip space float4 origin = float4(v.uv * 2 - 1, 1, 1); // clip space -> view space origin = mul(unity_CameraInvProjection, origin); o.rayOrigin = origin / origin.w;