赞
踩
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); } } }
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 } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。