做个记录,不然老忘~
平时做景深模糊效果,全局、高度雾效,屏幕后处理特效等等,需要知道场景中哪个物体离摄像机近,哪个离得更远,那么我们使用相机渲染一张深度图来得到这个信息
C#:
GetComponent<Camera>().depthTextureMode = DepthTextureMode.Depth;
Shader:
float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv); //采样深度图
depth = Linear01Depth(depth);//深度值转为线性01空间
Shader中的ZTest和ZWrite也是会有深度计算,但是我们无法取到,那是ZBuffer,DepthTexture是屏幕空间的纹理,并没有直接关系。
以景深模糊效果为例:
C#模糊后处理:
_Material.SetVector("_offsets", new Vector4(0, samplerScale, 0, 0));
Graphics.Blit(temp1, temp2, _Material, 0);
_Material.SetVector("_offsets", new Vector4(samplerScale, 0, 0, 0));
Graphics.Blit(temp2, temp1, _Material, 0);
Shader中模糊运算:
//顶点着色先uv偏移
o.uv01 = v.texcoord.xyxy + _offsets.xyxy * float4(1, 1, -1, -1);
o.uv23 = v.texcoord.xyxy + _offsets.xyxy * float4(1, 1, -1, -1) * 2.0;
o.uv45 = v.texcoord.xyxy + _offsets.xyxy * float4(1, 1, -1, -1) * 3.0;
//片段中模糊操作
fixed4 color = fixed4(0,0,0,0);
color += 0.40 * tex2D(_MainTex, i.uv);
color += 0.15 * tex2D(_MainTex, i.uv01.xy);
color += 0.15 * tex2D(_MainTex, i.uv01.zw);
color += 0.10 * tex2D(_MainTex, i.uv23.xy);
color += 0.10 * tex2D(_MainTex, i.uv23.zw);
color += 0.05 * tex2D(_MainTex, i.uv45.xy);
color += 0.05 * tex2D(_MainTex, i.uv45.zw);
C#中景深算法:
public float focalDistance = 10.0f;
public float nearBlurScale = 0.0f;
public float farBlurScale = 50.0f;
focalDistance = MainCam.WorldToViewportPoint((focalDistance - MainCam.nearClipPlane) * MainCam.transform.forward + MainCam.transform.position).z / (MainCam.farClipPlane - MainCam.nearClipPlane);
_Material.SetFloat("_focalDistance",focalDistance);
_Material.SetFloat("_nearBlurScale", nearBlurScale);
_Material.SetFloat("_farBlurScale", farBlurScale);
Shader中景深合并算法:
fixed4 final = (depth <= _focalDistance) ? MainTex : lerp(MainTex, BlurTex, clamp((depth - _focalDistance) * _farBlurScale, 0, 1));
final = (depth > _focalDistance) ? final : lerp( MainTex, BlurTex, clamp((_focalDistance - depth) * _nearBlurScale, 0, 1));
blurtex是在模糊操作得来的
其原理是先进行抓屏模糊再根据深度图进行合并
网友评论