700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 【Shader】实验02——后处理实现景深效果

【Shader】实验02——后处理实现景深效果

时间:2023-04-30 07:25:48

相关推荐

【Shader】实验02——后处理实现景深效果

景深(Depth Of Field),是指在摄影机镜头或其他成像器前沿能够取得清晰图像的成像所测定的被摄物体前后距离范围。

而景深效果是指在焦距之外的地方都是模糊的,只有焦距的地方清晰。

通过采样摄像机的深度纹理,得到当前屏幕纹理每个点的深度,使用深度值与焦距值得到每个点到焦距的距离,并使用距离来对原图像和高斯模糊处理过的图像进行插值并输出即可。

Shader代码

Shader "MyShaderTest/2_DepthOfField"{Properties {_MainTex ("Base (RGB)", 2D) = "white" {}_BlurMainTex("Bloom (RGB)", 2D) = "black" {}_LuminanceThreshold ("Luminance Threshold", Float) = 0.5_BlurSize ("Blur Size", Float) = 1.0_FocusStart("FocusStart", Float) = 0.4_FocusEnd("FocusEnd", Float) = 0.6}SubShader{ZTest Always Cull Off ZWrite OffCGINCLUDE#include "UnityCG.cginc"sampler2D _MainTex;half4 _MainTex_TexelSize;sampler2D _CameraDepthTexture;sampler2D _BlurMainTex;float _BlurSize;float _FocusStart;float _FocusEnd;struct v2fBlur{float4 pos : SV_POSITION;half2 uv[5] : TEXCOORD0;};//垂直方向(Y轴方向)的高斯模糊v2fBlur vertBlurVertical(appdata_img v){v2fBlur o;o.pos = UnityObjectToClipPos(v.vertex);half2 uv = v.texcoord;o.uv[0] = uv;o.uv[1] = uv + float2(0.0, _MainTex_TexelSize.y * 1.0) * _BlurSize;o.uv[2] = uv - float2(0.0, _MainTex_TexelSize.y * 1.0) * _BlurSize;o.uv[3] = uv + float2(0.0, _MainTex_TexelSize.y * 2.0) * _BlurSize;o.uv[4] = uv - float2(0.0, _MainTex_TexelSize.y * 2.0) * _BlurSize;return o;}//水平方向(X轴方向)的高斯模糊v2fBlur vertBlurHorizontal(appdata_img v){v2fBlur o;o.pos = UnityObjectToClipPos(v.vertex);half2 uv = v.texcoord;o.uv[0] = uv;o.uv[1] = uv + float2(_MainTex_TexelSize.x * 1.0, 0.0) * _BlurSize;o.uv[2] = uv - float2(_MainTex_TexelSize.x * 1.0, 0.0) * _BlurSize;o.uv[3] = uv + float2(_MainTex_TexelSize.x * 2.0, 0.0) * _BlurSize;o.uv[4] = uv - float2(_MainTex_TexelSize.x * 2.0, 0.0) * _BlurSize;return o;}fixed4 fragBlur(v2fBlur i) : SV_Target{float weight[3] = {0.4026,0.2442,0.0545 };fixed3 sum = tex2D(_MainTex, i.uv[0]).rgb * weight[0];for (int it = 1; it < 3; it++){sum += tex2D(_MainTex, i.uv[it * 2 - 1]).rgb * weight[it];sum += tex2D(_MainTex, i.uv[2 * it]).rgb * weight[it];}return fixed4(sum, 1.0);}struct v2f{float4 vertex : SV_POSITION;half2 uv : TEXCOORD0;};v2f vertDepthOfField(appdata_img v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = v.texcoord;return o;}fixed4 fragDepthOfField(v2f i) : SV_Target{float linearDepth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv));float distance = 0; if (linearDepth < _FocusStart){distance = abs(linearDepth - _FocusStart);}else if (linearDepth > _FocusEnd){distance = abs(linearDepth - _FocusEnd);}half4 color = tex2D(_MainTex,i.uv);half4 blurColor = tex2D(_BlurMainTex, i.uv);color = lerp(color, blurColor, distance);return fixed4(color.rgb,1);}ENDCGPass{CGPROGRAM #pragma vertex vertBlurVertical #pragma fragment fragBlurENDCG }Pass{CGPROGRAM #pragma vertex vertBlurHorizontal #pragma fragment fragBlurENDCG }Pass{CGPROGRAM#pragma vertex vertDepthOfField#pragma fragment fragDepthOfFieldENDCG}}FallBack Off}

挂在Camera上的C#脚本

using UnityEngine;[ExecuteInEditMode]public class DepthOfField : PostEffectsBase{public Shader shader;private Material _material = null;public Material Material{get{if(_material == null)_material = CheckShaderAndMaterial(shader,_material);return _material;}}private Camera _camera;public Camera Camera{get{if (_camera == null)_camera = GetComponent<Camera>();return _camera;}}private void OnEnable(){Camera.depthTextureMode |= DepthTextureMode.Depth;}[Range(1f, 4.0f)]public int blurSpread = 2;[Range(0.01f, 1.0f)]public float focusStart = 0.1f;[Range(0.01f, 1.0f)]public float focusEnd = 0.2f;[Range(1, 4)]public int iterations = 2;private void OnRenderImage(RenderTexture source, RenderTexture destination){if (Material != null){int rtW = source.width;int rtH = source.height;Material.SetFloat("_FocusStart", focusStart);Material.SetFloat("_FocusEnd", focusEnd);RenderTexture buffer0 = RenderTexture.GetTemporary(rtW, rtH, 0);buffer0.filterMode = FilterMode.Bilinear;Graphics.Blit(source, buffer0);for (int i = 0; i < iterations; i++){Material.SetFloat("_BlurSize", 1.0f + i * blurSpread);RenderTexture buffer1 = RenderTexture.GetTemporary(rtW, rtH, 0);Graphics.Blit(buffer0, buffer1, Material, 0);RenderTexture.ReleaseTemporary(buffer0);buffer0 = buffer1;buffer1 = RenderTexture.GetTemporary(rtW, rtH, 0);Graphics.Blit(buffer0, buffer1, Material, 1);RenderTexture.ReleaseTemporary(buffer0);buffer0 = buffer1;}Material.SetTexture("_BlurMainTex", buffer0);Graphics.Blit(source, destination,Material,2);RenderTexture.ReleaseTemporary(buffer0);}else{Debug.Log("没有shader,没法干活儿");Graphics.Blit(source, destination);}}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。