PostEffectsBase.cs
using UnityEngine; using System.Collections; [ExecuteInEditMode] [RequireComponent (typeof(Camera))] public class PostEffectsBase : MonoBehaviour { // Called when start protected void CheckResources() { bool isSupported = CheckSupport(); if (isSupported == false) { NotSupported(); } } // Called in CheckResources to check support on this platform protected bool CheckSupport() { if (SystemInfo.supportsImageEffects == false || SystemInfo.supportsRenderTextures == false) { Debug.LogWarning("This platform does not support image effects or render textures."); return false; } return true; } // Called when the platform doesn't support this effect protected void NotSupported() { enabled = false; } protected void Start() { CheckResources(); } // Called when need to create the material used by this effect protected Material CheckShaderAndCreateMaterial(Shader shader, Material material) { if (shader == null) { return null; } if (shader.isSupported && material && material.shader == shader) return material; if (!shader.isSupported) { return null; } else { material = new Material(shader); material.hideFlags = HideFlags.DontSave; if (material) return material; else return null; } } }
MotionBlurWithDepthTexture.cs
using UnityEngine; using System.Collections; public class MotionBlurWithDepthTexture : PostEffectsBase { public Shader motionBlurShader; private Material motionBlurMaterial = null; public Material material { get { motionBlurMaterial = CheckShaderAndCreateMaterial(motionBlurShader, motionBlurMaterial); return motionBlurMaterial; } } private Camera myCamera; public Camera camera { get { if (myCamera == null) { myCamera = GetComponent<Camera>(); } return myCamera; } } [Range(0.0f, 1.0f)] public float blurSize = 0.5f; private Matrix4x4 previousViewProjectionMatrix; void OnEnable() { camera.depthTextureMode |= DepthTextureMode.Depth; previousViewProjectionMatrix = camera.projectionMatrix * camera.worldToCameraMatrix; } void OnRenderImage (RenderTexture src, RenderTexture dest) { if (material != null) { material.SetFloat("_BlurSize", blurSize); material.SetMatrix("_PreviousViewProjectionMatrix", previousViewProjectionMatrix); Matrix4x4 currentViewProjectionMatrix = camera.projectionMatrix * camera.worldToCameraMatrix; Matrix4x4 currentViewProjectionInverseMatrix = currentViewProjectionMatrix.inverse; material.SetMatrix("_CurrentViewProjectionInverseMatrix", currentViewProjectionInverseMatrix); previousViewProjectionMatrix = currentViewProjectionMatrix; Graphics.Blit (src, dest, material); } else { Graphics.Blit(src, dest); } } }
内置渲染管线
Shader "SunY/C13-MotionBlurWithDepthTexture" { Properties { _MainTex("Main Tex", 2D) = "white"{} _BlurSize("Blur Size", float) = 1.0 } SubShader { CGINCLUDE #include "UnityCG.cginc" sampler2D _MainTex; float4 _MainTex_TexelSize; sampler2D _CameraDepthTexture; float4x4 _CurrentViewProjectionInverseMatrix; float4x4 _PreviousViewProjectionMatrix; half _BlurSize; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; float2 uv_depth : TEXCOORD1; }; v2f vert(appdata_img v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord; o.uv_depth = v.texcoord; #if UNITY_UV_STARTS_AT_TOP if(_MainTex_TexelSize.y < 0) o.uv_depth.y = 1 - o.uv_depth.y; #endif return o; } fixed4 frag(v2f i) : SV_Target { float d = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv_depth); float4 H = float4(i.uv.x * 2 - 1, i.uv.y * 2 - 1, d * 2 - 1, 1); float4 D = mul(_CurrentViewProjectionInverseMatrix, H); float4 worldPos = D / D.w; float4 currentPos = H; float4 previousPos = mul(_PreviousViewProjectionMatrix, worldPos); previousPos /= previousPos.w; float2 velocity = (currentPos.xy - previousPos.xy) / 2.0; float2 uv = i.uv; float4 c = tex2D(_MainTex, uv); uv += velocity * _BlurSize; for(int it = 1; it < 3; it++, uv += velocity * _BlurSize) { float4 currentColor = tex2D(_MainTex, uv); c += currentColor; } c /= 3; return fixed4(c.rgb, 1); } ENDCG Pass { ZTest Always ZWrite Off Cull Off CGPROGRAM #pragma vertex vert #pragma fragment frag ENDCG } } FallBack Off }
浙公网安备 33010602011771号