首页 > 技术文章 > Unity shader学习之屏幕后期处理效果之高度雾,重建world pos方法2

jietian331 2018-08-08 15:56 原文

这里使用一种更高效地从深度纹理中重建世界坐标的方法。

首先计算摄像机的视锥体的四条射线向量进行线性插值,插值后的值便是该像素在世界空间坐标下到摄像机的方向。

然后通过与深度值相乘即可得到摄像机位置到该像素的向量,加上摄像机的位置则是该像素在世界空间中的位置。

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

c#代码:

 1 using UnityEngine;
 2 
 3 public class HighFog2 : PostEffectRenderer
 4 {
 5     [SerializeField]
 6     Color m_fogColor = Color.white;
 7     [Range(0f, 1f)]
 8     [SerializeField]
 9     float m_fogDensity = 0.9f;
10     [SerializeField]
11     float m_fogPosY = 0.1f;
12     [SerializeField]
13     float m_fogDisappearHeight = 8;
14 
15 
16     protected override string ShaderName
17     {
18         get { return "Custom/Study/HighFog2"; }
19     }
20 
21     protected override void OnRenderImage(RenderTexture src, RenderTexture dest)
22     {
23         float fov = base.SelfCamera.fieldOfView;
24         float near = base.SelfCamera.nearClipPlane;
25         Transform camT = base.SelfCamera.transform;
26 
27         float halfFOV = fov * Mathf.PI / 360f;
28         float toTopDis = near * Mathf.Tan(halfFOV);
29         float toRightDis = toTopDis * (Screen.width / Screen.height);
30         Vector3 toTop = camT.up * toTopDis;
31         Vector3 toRight = camT.right * toRightDis;
32         Vector3 toCenter = camT.forward * near;
33         Vector3 topLeft = (toCenter + toTop - toRight) / near;
34         Vector3 topRight = (toCenter + toTop + toRight) / near;
35         Vector3 bottomLeft = (toCenter - toTop - toRight) / near;
36         Vector3 bottomRight = (toCenter - toTop - toRight) / near;
37 
38         Matrix4x4 matrix = Matrix4x4.identity;
39         matrix.SetRow(0, bottomLeft);
40         matrix.SetRow(1, bottomRight);
41         matrix.SetRow(2, topLeft);
42         matrix.SetRow(3, topRight);
43 
44         base.Mat.SetMatrix("_CameraRays", matrix);
45         base.Mat.SetColor("_FogColor", m_fogColor);
46         base.Mat.SetFloat("_FogDensity", m_fogDensity);
47         base.Mat.SetFloat("_FogPosY", m_fogPosY);
48         base.Mat.SetFloat("_FogDisappearHeight", m_fogDisappearHeight);
49         base.OnRenderImage(src, dest);
50     }
51 }
View Code

shader:

  1 Shader "Custom/Study/HighFog2"
  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                 float3 ray : TEXCOORD1;
 33             };
 34 
 35             sampler2D _MainTex;
 36             sampler2D _CameraDepthTexture;
 37             uniform float4x4 _CameraRays;
 38             uniform float4 _FogColor;
 39             uniform float _FogDensity;
 40             uniform float _FogPosY;
 41             uniform float _FogDisappearHeight;
 42 
 43             v2f vert (appdata v)
 44             {
 45                 v2f o;
 46                 o.vertex = UnityObjectToClipPos(v.vertex);
 47                 o.uv = v.uv;
 48 
 49                 int index;
 50                 if(v.vertex.x < 0.5 && v.vertex.y < 0.5)
 51                 {
 52                     index = 0;
 53                 }
 54                 else if(v.vertex.x > 0.5 && v.vertex.y < 0.5)
 55                 {
 56                     index = 1;
 57                 }
 58                 else if(v.vertex.x > 0.5 && v.vertex.y > 0.5)
 59                 {
 60                     index = 2;
 61                 }
 62                 else
 63                 {
 64                     index = 3;
 65                 }
 66                 o.ray = _CameraRays[index].xyz;
 67 
 68                 return o;
 69             }
 70             
 71             fixed4 frag (v2f i) : SV_Target
 72             {
 73                 fixed4 col = tex2D(_MainTex, i.uv);
 74                 
 75                 float d = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv));
 76                 float3 worldPos = _WorldSpaceCameraPos + i.ray * d;
 77 
 78                 float fogWeight;
 79                 if(worldPos.y < _FogPosY)
 80                 {
 81                     fogWeight = 1;
 82                 }
 83                 else if(worldPos.y > _FogPosY + _FogDisappearHeight)
 84                 {
 85                     fogWeight = 0;
 86                 }
 87                 else
 88                 {
 89                     fogWeight = 1 - (worldPos.y - _FogPosY) / _FogDisappearHeight;
 90                 }
 91 
 92                 return lerp(col, _FogColor, fogWeight * _FogDensity);
 93             }
 94 
 95             ENDCG
 96         }
 97     }
 98 
 99     Fallback Off
100 }
View Code

 

效果图如下:

 

推荐阅读