Unity shader学习之屏幕后期处理效果之高度雾,重建world pos方法1

要想通过屏幕后期处理效果实现高度雾,就得知道屏幕中每个像素在世界空间中的坐标。

其中一种方法是:

打开深度纹理,通过uv坐标和深度计算出屏幕中每个像素在NDC中的坐标,再通过世界坐标到投影空间的转换矩阵的逆矩阵来变换,即可得到其在世界空间中的坐标。

但此种方法需要在 fragment shader 中进行矩阵乘法计算,而这通常会影响游戏性能。

转载请注明出处:https://www.cnblogs.com/jietian331/p/9441440.html

c#代码:

using UnityEngine;

[RequireComponent(typeof(Camera))]
public abstract class PostEffectRenderer : GameBehaviour
{
    [SerializeField]
    Material m_material;

    Camera m_camera;


    protected abstract string ShaderName { get; }

    protected Material Mat
    {
        get
        {
            if (!m_material)
            {
                Shader shader = Shader.Find(ShaderName);
                if (shader != null && shader.isSupported)
                    m_material = new Material(shader);
                else
                    NotSupport();
            }
            return m_material;
        }
    }

    protected Camera SelfCamera
    {
        get
        {
            if (!m_camera)
                m_camera = GetComponent<Camera>();
            return m_camera;
        }
    }


    void Start()
    {
        if (!SystemInfo.supportsImageEffects)
            NotSupport();
    }

    protected virtual void OnRenderImage(RenderTexture src, RenderTexture dest)
    {
        Graphics.Blit(src, dest, Mat);
    }

    protected void NotSupport()
    {
        Debug.LogError(string.Format("{0} not support!", this.GetType().Name));
        enabled = false;
    }

}
基类
 1 using UnityEngine;
 2 
 3 public class HighFog : PostEffectRenderer
 4 {
 5     [SerializeField]
 6     Color m_fogColor = Color.white;
 7     [Range(0f, 1f)]
 8     [SerializeField]
 9     float m_fogDensity = 1;
10     [SerializeField]
11     float m_fogPosY = 0.1f;
12     [SerializeField]
13     float m_fogDisappearHeight = 10;
14 
15 
16     protected override string ShaderName
17     {
18         get { return "Custom/Study/High Fog"; }
19     }
20 
21     void OnEnable()
22     {
23         base.SelfCamera.depthTextureMode = DepthTextureMode.Depth;
24     }
25 
26     void OnDisable()
27     {
28         base.SelfCamera.depthTextureMode = DepthTextureMode.None;
29     }
30 
31     protected override void OnRenderImage(RenderTexture src, RenderTexture dest)
32     {
33         var projMatrix = GL.GetGPUProjectionMatrix(base.SelfCamera.projectionMatrix, false);
34         var m = projMatrix * base.SelfCamera.worldToCameraMatrix;
35         base.Mat.SetMatrix("_ViewportToWorldMatrix", m.inverse);
36         base.Mat.SetColor("_FogColor", m_fogColor);
37         base.Mat.SetFloat("_FogDensity", m_fogDensity);
38         base.Mat.SetFloat("_FogPosY", m_fogPosY);
39         base.Mat.SetFloat("_FogDisappearHeight", m_fogDisappearHeight);
40         base.OnRenderImage(src, dest);
41     }
42 }
子类

shader:

 1 Shader "Custom/Study/High Fog"
 2 {
 3     Properties
 4     {
 5         _MainTex ("Texture", 2D) = "white" {}
 6     }
 7 
 8     SubShader
 9     {
10         Pass
11         {
12             ZTest Always
13             ZWrite Off
14             Cull Off
15 
16             CGPROGRAM
17             #pragma vertex vert
18             #pragma fragment frag
19             
20             #include "UnityCG.cginc"
21 
22             struct appdata
23             {
24                 float4 vertex : POSITION;
25                 float2 uv : TEXCOORD0;
26             };
27 
28             struct v2f
29             {
30                 float2 uv : TEXCOORD0;
31                 float4 vertex : SV_POSITION;
32             };
33 
34             sampler2D _MainTex;
35             sampler2D _CameraDepthTexture;
36             uniform float4x4 _ViewportToWorldMatrix;
37             uniform float4 _FogColor;
38             uniform float _FogDensity;
39             uniform float _FogPosY;
40             uniform float _FogDisappearHeight;
41 
42             v2f vert (appdata v)
43             {
44                 v2f o;
45                 o.vertex = UnityObjectToClipPos(v.vertex);
46                 o.uv = v.uv;
47                 return o;
48             }
49             
50             fixed4 frag (v2f i) : SV_Target
51             {
52                 fixed4 col = tex2D(_MainTex, i.uv);
53                 
54                 float d = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv);
55                 float4 H = float4(i.uv.x * 2 - 1, i.uv.y * 2 - 1, d, 1);
56                 float4 D = mul(_ViewportToWorldMatrix, H);
57                 float4 worldPos = D / D.w;
58 
59                 float fogWeight;
60                 if(worldPos.y < _FogPosY)
61                 {
62                     fogWeight = 1;
63                 }
64                 else if(worldPos.y > _FogPosY + _FogDisappearHeight)
65                 {
66                     fogWeight = 0;
67                 }
68                 else
69                 {
70                     fogWeight = 1 - (worldPos.y - _FogPosY) / _FogDisappearHeight;
71                 }
72 
73                 return lerp(col, _FogColor, fogWeight * _FogDensity);
74             }
75 
76             ENDCG
77         }
78     }
79 
80     Fallback Off
81 }
View Code

效果如下图:

 

posted @ 2018-08-08 10:52  孤独の巡礼  阅读(2266)  评论(0编辑  收藏  举报