C#代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class JingShen : MonoBehaviour {
public Material mat;
[Range(0f, 100f)]
public float focalDistance = 10;//焦点距离
[Range(0, 100)]
public float nearBlurScale = 0;//近距离模糊缩放
[Range(0,1000f)]
public float farBlurScale = 50;//远距离模糊缩放
public int downSample = 1;//分辨率降低值
public int sampleScale = 1;//采样半径
private void OnEnable()
{
GetComponent().depthTextureMode |= DepthTextureMode.Depth;//开启深度
}
private void OnDisable()
{
GetComponent().depthTextureMode &= ~DepthTextureMode.Depth;//关闭深度
}
private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
Mathf.Clamp(focalDistance, transform.GetComponent().nearClipPlane, transform.GetComponent().farClipPlane);//限制焦点距离在摄像机最近裁剪面和最远裁剪面
RenderTexture temp1 = RenderTexture.GetTemporary(source.width >> downSample, source.height >> downSample, 0, source.format);//降低分辨率
RenderTexture temp2 = RenderTexture.GetTemporary(source.width >> downSample, source.height >> downSample, 0, source.format);
Graphics.Blit(source, temp1);
mat.SetVector("_offset", new Vector4(0, sampleScale, 0, 0));//垂直取值
Graphics.Blit(temp1, temp2, mat,0);
mat.SetVector("_offset", new Vector4(sampleScale, 0, 0, 0));//水平取值
Graphics.Blit(temp2, temp1, mat,0);
mat.SetTexture("_BlurTex", temp1);
mat.SetFloat("_focalDistance", FocalDistance(focalDistance));
mat.SetFloat("_nearBlurScale", nearBlurScale);
mat.SetFloat("_farBlurScale", farBlurScale);
Graphics.Blit(source, destination, mat, 1);
RenderTexture.ReleaseTemporary(temp1);
RenderTexture.ReleaseTemporary(temp2);
}
float FocalDistance(float distance)
{
//深度转换,把世界空间的深度先转换成摄像机空间的深度,再把摄像机的z值转换成0至1的范围值
return transform.GetComponent().WorldToViewportPoint((distance - transform.GetComponent().nearClipPlane) * transform.forward + transform.position).z / (transform.GetComponent().farClipPlane - transform.GetComponent().nearClipPlane);
}
}
shader代码:
Shader "Unlit/Test"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_BlurTex("BlurTex",2D)="white"{}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
//高斯模糊
ZTest Off
cull Off
ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata{
float4 vertex:POSITION;
float2 uv:TEXCOORD0;
};
struct v2f
{
float4 pos:SV_POSITION;
float2 uv:TEXCOORD0;
float4 uv01:TEXCOORD1;
float4 uv23:TEXCOORD2;
float4 uv45:TEXCOORD3;
};
sampler2D _MainTex;
float4 _MainTex_TexelSize;
float4 _offset;
v2f vert(appdata v)
{
v2f o;
_offset*=_MainTex_TexelSize.xyxy;
o.pos=UnityObjectToClipPos(v.vertex);
o.uv=v.vertex.xy;
o.uv01=v.vertex.xyxy+_offset.xyxy*float4(1,1,-1,-1);
o.uv23=v.vertex.xyxy+_offset.xyxy*float4(1,1,-1,-1)*2;
o.uv45=v.vertex.xyxy+_offset.xyxy*float4(1,1,-1,-1)*3;
return o;
}
fixed4 frag(v2f i):SV_Target
{
fixed4 col=0.4*tex2D(_MainTex,i.uv);
col+=0.15*tex2D(_MainTex,i.uv01.xy);
col+=0.15*tex2D(_MainTex,i.uv01.zw);
col+=0.10*tex2D(_MainTex,i.uv23.xy);
col+=0.10*tex2D(_MainTex,i.uv23.zw);
col+=0.05*tex2D(_MainTex,i.uv45.xy);
col+=0.05*tex2D(_MainTex,i.uv45.zw);
return col;
}
ENDCG
}
Pass
{
//景深
ZTest Off
Cull Off
ZWrite Off
ColorMask RGBA
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_TexelSize;
sampler2D _CameraDepthTexture;
sampler2D _BlurTex;
float _focalDistance;
float _nearBlurScale;
float _farBlurScale;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.vertex.xy;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
fixed4 blur=tex2D(_BlurTex,i.uv);
float depth=SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv);
depth=Linear01Depth(depth);
float focalTest=clamp(sign(depth-_focalDistance),0,1);
fixed4 final=(1-focalTest)*col+focalTest*lerp(col,blur,clamp((depth-_focalDistance)*_farBlurScale,0,1));
final=(focalTest)*final+(1-focalTest)*lerp(col,blur,clamp((_focalDistance-depth)*_nearBlurScale,0,1));
return final;
}
ENDCG
}
}
}