• Unity Shader 景深效果


    效果

    原理:

    开启摄像机的深度模式,将深度保存到一张名为_CameraDepthTexture(Unity5.0之后才有)内置的纹理中.

    如果深度在焦点范围内就用原图,否则就用模糊图。

    Shader:

    Shader "DepthOfFiled"
    {
        Properties
        {
            _MainTex ("Texture", 2D) = "white" {}
            _BlurSize ("Blur Size", Float) = 0.1
        }
    
        CGINCLUDE
    
        #include "UnityCG.cginc"
    
        sampler2D _MainTex;  
        sampler2D _BlurTex;  
        sampler2D _CameraDepthTexture;  
        uniform half4 _MainTex_TexelSize;  
        uniform float _BlurSize;
        uniform float _FocusDistance;
        uniform float _FocusRange;
    
    
        static const half weight[4] = {0.0205, 0.0855, 0.232, 0.324};
        static const half4 coordOffset = half4(1.0h,1.0h,-1.0h,-1.0h);
    
        struct v2f_blurSGX
        {
            float4 pos:SV_POSITION;
            half2 uv:TEXCOORD0;
            half4 uvoff[3]:TEXCOORD1;
        };
    
        struct v2f_dof
        {
            float4 pos:SV_POSITION;
            half2 uv:TEXCOORD0;
        };
    
        v2f_blurSGX vert_BlurHorizontal(appdata_img v)
        {
            v2f_blurSGX o;
            o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
            o.uv = v.texcoord.xy;
            half2 offs = _MainTex_TexelSize.xy*half2(1,0)*_BlurSize;
            o.uvoff[0] = v.texcoord.xyxy+offs.xyxy*coordOffset*3;
            o.uvoff[1] = v.texcoord.xyxy+offs.xyxy*coordOffset*2;
            o.uvoff[2] = v.texcoord.xyxy+offs.xyxy*coordOffset;
    
            return o;
        }
    
        v2f_blurSGX vert_BlurVertical(appdata_img v)
        {
            v2f_blurSGX o;
            o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
            o.uv = v.texcoord.xy;
    
            half2 offs = _MainTex_TexelSize.xy*half2(0,1)*_BlurSize;
            o.uvoff[0] = v.texcoord.xyxy+offs.xyxy*coordOffset*3;
            o.uvoff[1] = v.texcoord.xyxy+offs.xyxy*coordOffset*2;
            o.uvoff[2] = v.texcoord.xyxy+offs.xyxy*coordOffset;
    
            return o;
        }
    
        fixed4 frag_Blur(v2f_blurSGX i):SV_Target
        {
            
            fixed4 c = tex2D(_MainTex,i.uv)*weight[3];
            for(int idx=0; idx<3; idx++)
            {
                c+=tex2D(_MainTex,i.uvoff[idx].xy)*weight[idx];
                c+=tex2D(_MainTex,i.uvoff[idx].zw)*weight[idx];
            }
    
            return c;
        }
    
        v2f_dof vert_Dof(appdata_img v)
        {
            v2f_dof o;
            o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
            o.uv = v.texcoord.xy;
    
            return o;
        }
    
        fixed4 frag_Dof(v2f_dof i):SV_Target
        {
            fixed4 c = tex2D(_MainTex,i.uv);
            fixed4 b = tex2D(_BlurTex,i.uv);
    
            float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv);  
            //将深度值转化到01线性空间  
            depth = Linear01Depth(depth); 
    
            return lerp(c,b,saturate(sign(abs(depth-_FocusDistance)-_FocusRange)));
                 
        }
        ENDCG
    
        SubShader
        {
            // No culling or depth
            //Cull Off ZWrite Off 
    
            //Pass 0
            Pass
            {
                ZTest Always
                CGPROGRAM
                #pragma vertex vert_BlurHorizontal
                #pragma fragment frag_Blur
                
    
                ENDCG
            }
    
            //Pass 1 
            Pass
            {
                ZTest Always
                CGPROGRAM
                #pragma vertex vert_BlurVertical
                #pragma fragment frag_Blur
                
    
                ENDCG
            }
    
            //Pass 2
            Pass
            {
                ZTest Off  
                Cull Off  
                ZWrite Off  
                Fog{ Mode Off }  
                ColorMask RGBA
    
                CGPROGRAM
                #pragma vertex vert_Dof
                #pragma fragment frag_Dof
                
    
                ENDCG
            }
    
    
        }
    }

    C#代码

    using UnityEngine;
    using System.Collections;
    
    [ExecuteInEditMode]
    [RequireComponent(typeof(Camera))]
    public class DepthOfFieldPostEffect : MonoBehaviour {
    
        public Material Mat;public float BlurSize =10;
        public int interator = 2;
        [Range(0,1)]
        public float FocusDistance = 0.5f; 
        [Range(0,0.5f)]
        public float FocusRange=0.1f;
    
        void OnEnable()
        {
            GetComponent<Camera> ().depthTextureMode = DepthTextureMode.Depth;
        }
        void OnDisable()
        {
            GetComponent<Camera> ().depthTextureMode = ~DepthTextureMode.Depth;
        }
        // Use this for initialization
        void Start () {
        
        }
        
        // Update is called once per frame
        void Update () {
        
        }
    
        void OnRenderImage(RenderTexture src,RenderTexture dest)
        {
            var w = src.width / 8;
            var h = src.height / 8;
            var tmp1 = RenderTexture.GetTemporary (w, h);
            var tmp2 = RenderTexture.GetTemporary (w, h);
            Mat.SetFloat ("_BlurSize", BlurSize);
            Mat.SetFloat ("_FocusDistance", FocusDistance);
            Mat.SetFloat ("_FocusRange", FocusRange);
    
            Graphics.Blit (src, tmp1);
    
            for (int i = 0; i < interator; i++) {
                Graphics.Blit (tmp1, tmp2, Mat,0);
                Graphics.Blit (tmp2, tmp1, Mat,1);
            }
    
            Mat.SetTexture ("_BlurTex", tmp1);
    
            Graphics.Blit (src, dest,Mat,2);
    
            RenderTexture.ReleaseTemporary (tmp1);
            RenderTexture.ReleaseTemporary (tmp2);
    
        }
    }
  • 相关阅读:
    利用JavaScript数组动态写入HTML数据节点
    个人项目网站,部分截图
    HTML5 JavaScript API
    简述几项关于web应用的开发技术
    最值得学习的编程语言
    使用Ajax与服务器端通信
    Ajax与用户交互的存储格式JSON
    兄弟连教育分享:用CSS实现鼠标悬停提示的方法
    移动端HTML5性能优化
    兄弟连PHP培训教你提升效率的20个要点
  • 原文地址:https://www.cnblogs.com/mrblue/p/7875755.html
Copyright © 2020-2023  润新知