• 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

    效果如下图:

  • 相关阅读:
    遇到swiper高度问题
    overflow
    transition过渡规定慢速开始,然后变快,然后慢速结束的过渡效果(cubic-bezier(0.25,0.1,0.25,1))。
    【记录一个问题】thinkpad x1笔记本,安装ubuntu 16后,拔掉U盘,总是启动到windows,无法启动到ubuntu
    【记录一个问题】笔记本ThinkPad X1-Extreme安装ubuntu 18后,更新nvidia显卡驱动后出现显示问题,无法再登录
    golang gin框架中实现一个简单的不是特别精确的秒级限流器
    【解决了一个小问题】golang中引用一个路径较长的库,导致goland中出现"module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v2"
    【解决了一个小问题】golang samara的kafka客户端中使用错误版本号导致初始化失败
    【解决了一个小问题】golang xorm中使用where id in (xxx),没办法使用参数替换
    【记录一个问题】golangci-lint.exe中,盘符大写就会执行出错
  • 原文地址:https://www.cnblogs.com/jietian331/p/9441440.html
Copyright © 2020-2023  润新知