当前位置:   article > 正文

通过深度纹理重建像素的世界坐标,生成全局雾效_深度重建世界坐标

深度重建世界坐标

posteffectBase的代码我没有上传 其实就是封装了几个方法 有兴趣自己实现吧重要地方都有注释

有什么问题欢迎评论区提问

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;

public class FogWithDepthTexture : PostEffectsBase
{
    public Shader fogShader;
    private Material fogMaterial=null;
    public Material material {
        get {
            fogMaterial = CheckShaderAndCreateMaterial(fogShader,fogMaterial);
            return fogMaterial;
        }
    }

    private Camera myCamera;
    public Camera camera {
        get {
            if (myCamera == null)
                myCamera = GetComponent<Camera>();
            return myCamera;
        }
    }

    private Transform myCameraTransform;
    public Transform cameraTransform {
        get {
            if (myCameraTransform == null)
                myCameraTransform = camera.transform;
            return myCameraTransform;
        }
    }

    [Range(0.0f,3.0f)]
    public float fogDensity = 1.0f;
    public Color fogColor = Color.white;
    public float fogStart = 0.0f;
    public float fogEnd = 2.0f;

    private void OnEnable()
    {
        camera.depthTextureMode |= DepthTextureMode.Depth;
    }
    private void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        if (material != null) {
            Matrix4x4 frustumCorners = Matrix4x4.identity;

            float fov = camera.fieldOfView;
            float near = camera.nearClipPlane;
            float far = camera.farClipPlane;
            float aspect = camera.aspect;
            //计算近裁平面的高度的一半                        //转弧度
            float halfHeight = near * Mathf.Tan(fov*0.5f*Mathf.Deg2Rad);
            //既有方向又有大小 halfHeight * aspect:一半的宽
            Vector3 toRight = cameraTransform.right * halfHeight * aspect;
            Vector3 toTop = cameraTransform.up * halfHeight;
            //左上角的向量
            Vector3 topLeft = cameraTransform.forward * near + toTop - toRight;
            //摄像机到近裁平面四个点的长度比上近裁距离 是 摄像头距离视锥体内每个点的距离比上每个点的线性深度
            float scale = topLeft.magnitude / near;
            topLeft.Normalize();
            topLeft *=scale;

            Vector3 topRight = cameraTransform.forward * near + toRight + toTop;
            topRight.Normalize();
            topRight *= scale;

            Vector3 bottomLeft = cameraTransform.forward * near + toRight - toTop;
            bottomLeft.Normalize();
            bottomLeft *= scale;

            Vector3 bottomRight = cameraTransform.forward * near + toRight - toTop;
            bottomRight.Normalize();
            bottomRight *= scale;

            frustumCorners.SetRow(0,bottomLeft);
            frustumCorners.SetRow(1,bottomRight);
            frustumCorners.SetRow(2,topLeft);
            frustumCorners.SetRow(3,topRight);

            material.SetMatrix("_FrustumCornersRay",frustumCorners);
            material.SetMatrix("_ViewProjectionInverseMatrix",(camera.projectionMatrix*camera.worldToCameraMatrix).inverse);

            material.SetFloat("_FogDensity",fogDensity);
            material.SetColor("_FogColor",fogColor);
            material.SetFloat("_FogStart",fogStart);
            material.SetFloat("_FogEnd",fogEnd);

            Graphics.Blit(source,destination,material);

        } else {
            Graphics.Blit(source,destination);
        }
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
Shader "Unlit/FogWithDepthTexture"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _FogDensity("Fog Density",Float)=1.0
        _FogColor("Fog Color",Color)=(1,1,1,1)
        _FogStart("Fog Start",Float)=0.0
        _FogEnd("Fog End",Float)=1.0
    }
    SubShader
    {

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"
            
            sampler2D _MainTex;
            float4 _MainTex_TexelSize;
            float _FogDensity;
            float _FogStart;
            float _FogEnd;
            fixed4 _FogColor;
            float4x4 _FrustumCornersRay;
            sampler2D _CameraDepthTexture;

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
                float2 uv_depth:TEXCOORD1;
                float4 interpolatedRay:TEXCOORD2;
            };


            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                UNITY_TRANSFER_FOG(o,o.vertex);
                o.uv_depth=v.uv;
                #if UNITY_UV_STARTS_AT_TOP
                    if(_MainTex_TexelSize.y<0)
                        o.uv_depth.y=1-o.uv_depth;
                #endif

                //判断象限 同一个象限内可以用相同的系数求出距离
                int index=0;
                if(v.uv.x<0.5&&v.uv.y<0.5){
                    index=0;
                }else if(v.uv.x>0.5&&v.uv.y<0.5){
                    index=1;
                }else if(v.uv.x>0.5&&v.uv.y>0.5){
                    index=2;
                }else {
                    index=3;
                }
                //判断不同平台下的的射线
                #if UNITY_UV_STARTS_AT_TOP
                    if(_MainTex_TexelSize.y<0)
                        index=3-index;
                #endif
                o.interpolatedRay=_FrustumCornersRay[index];
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                //得到深度值
                float linearDepth=LinearEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv_depth));

                float3 worldPos=_WorldSpaceCameraPos+linearDepth*i.interpolatedRay.xyz;

                //雾效系数
                float fogdensity=(_FogEnd-worldPos.y)/(_FogEnd-_FogStart);
                fogdensity=saturate(fogdensity*_FogDensity);
                fixed4 col = tex2D(_MainTex, i.uv);
                col.rgb=lerp(col.rgb,_FogColor.rgb,fogdensity);
                UNITY_APPLY_FOG(i.fogCoord, col);
                return col;
            }
            ENDCG
        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/101315
推荐阅读
相关标签
  

闽ICP备14008679号