Unity Shader after screen effect - camera motion blur (speed map to achieve)

Velocity map is mainly used in order to obtain a texture depth of each pixel of the camera with respect to motion vectors of the previous frame, wherein the method is derived.

Derived as follows:

Release first by the inverse depth texture coordinates of the vertices in the NDC (normalized device coordinates), using VP matrix (perspective projection matrix *) the inverse matrix of inverse transform for each pixel position in world space,

And then using the coordinate of the previous frame forward transform matrix VP world space under a front frame NDC coordinates, to determine the direction of the velocity using the coordinate difference and a previous frame rather NDC frame,

Finally, the direction of the texture sampling rate results and weighted averaging is performed repeatedly drawn, in order to achieve the object with motion blur direction.

 

Based on this principle, the elements need to be prepared are:

1. The camera's depth texture (coordinates are mapped by the NDC to, we need to reverse mapped back NDC)

2. Current VP inverse matrix of the matrix frames

3. VP matrix of the previous frame

 

Camera depth value and depth of the texture acquisition method has written a blog before, specifically refer to:

https://www.cnblogs.com/koshio0219/p/11178215.html

Perspective matrix (V matrix):

MyCamera.worldToCameraMatrix; (that is, to transform the world's space camera space (also known as the perspective of space, space observation))

Projection matrix (P matrix):

MyCamera.projectionMatrix; (camera space is transformed into clip space)

 

Specific mathematical derivation can see this article:

http://feepingcreature.github.io/math.html

 

The following are specific procedures to achieve:

1. This script is mounted on the camera, the parameters for fuzzy control, depth textures ready, transfer matrix:

 1 using UnityEngine;
 2 
 3 public class MotionBlurWithDepthTexCtrl : ScreenEffectBase
 4 {
 5     private const string _BlurSize = "_BlurSize";
 6     private const string _PreViewMatrix = "_PreViewMatrix";
 7     private const string _CurViewInserseMatrix = "_CurViewInserseMatrix";
 8 
 9     [Range(0.0f, 1.0f)]
10      public  a float blurSize = .5f;
 . 11  
12 is      // previous frame VP matrix 
13 is      Private MATRIX4X4 preViewMatrix;
 14  
15      Private Camera myCamera;
 16      public Camera MyCamera
 . 17      {
 18 is          GET 
. 19          {
 20 is              IF ( null == myCamera)
 21 is              {
 22 is                  = GetComponent myCamera <Camera> ();
 23 is              }
 24              return myCamera;
 25          }
26      }
 27  
28      // turn this camera depth mode, and initializes the previous frame VP matrix 
29      Private  void OnEnable ()
 30      {
 31 is          MyCamera.depthTextureMode | = DepthTextureMode.Depth;
 32  
33 is          // principle by the right, the front matrix is P , is behind the V matrix 
34 is          preViewMatrix = MyCamera.projectionMatrix * MyCamera.worldToCameraMatrix;
 35      }
 36  
37 [      // not resume 
38 is      Private  void OnDisable ()
 39      {
 40          MyCamera.depthTextureMode & = ~ DepthTextureMode.Depth;
 41 is     }
 42 is  
43 is      Private  void OnRenderImage (the RenderTexture Source, the RenderTexture Where do you want)
 44 is      {
 45          IF (Material's)
 46 is          {
 47              Material.SetFloat (_BlurSize, blurSize);
 48              // disposed before a matrix of VP 
49              Material.SetMatrix (_PreViewMatrix, preViewMatrix );
 50              // compute the current frame VP matrix, and right by 
51 is              MATRIX4X4 curViewMatrix = MyCamera.projectionMatrix * MyCamera.worldToCameraMatrix;
 52 is              // save up, as computed before the next one 
53 is              preViewMatrix = curViewMatrix;
54              // Set VP matrix inverse matrix of the current frame 
55              Material.SetMatrix (_CurViewInserseMatrix, curViewMatrix.inverse);
 56 is  
57 is              Graphics.Blit (Source, Where do you want, Material's);
 58          }
 59          the else 
60              Graphics.Blit (Source, Where do you want) ;
 61 is  
62 is      }
 63 }

2.Shader script:

 1 Shader "MyUnlit/MotionBlurWithDepthTex"
 2 {
 3     Properties
 4     {
 5         _MainTex ("Texture", 2D) = "white" {}
 6     }
 7     SubShader
 8     {
 9         Pass
10         {
11             ZTest Always Cull Off ZWrite Off
12 
13             CGPROGRAM
14             #pragma vertex vert
15             #pragma fragment frag
16 
. 17              #include " UnityCG.cginc " 
18 is  
. 19              sampler2D _MainTex;
 20 is              half4 _MainTex_TexelSize;
 21 is              Fixed _BlurSize;
 22 is              // declaration texture and depth corresponding to the matrix 
23 is              sampler2D _CameraDepthTexture;
 24              a float4x4 _PreViewMatrix;
 25              a float4x4 _CurViewInserseMatrix;
 26 is  
27              struct AppData
 28              {
 29                  float4 Vertex: the POSITION;
 30                  float2 UV: TEXCOORD0;
 31 is              };
32  
33 is              struct V2f
 34 is              {
 35                  // uv herein while the main memory and the texture uv depth texture uv, xy-based texture, zw is the depth of the texture 
36                  half4 uv: TEXCOORD0;
 37 [                  float4 Vertex: SV_POSITION;
 38 is              };
 39  
40              V2f Vert (AppData V)
 41 is              {
 42 is                  V2f O;
 43 is                  o.vertex = UnityObjectToClipPos (v.vertex);
 44 is                  o.uv.xy = v.uv;
 45                  o.uv.zw = v.uv;
 46 is  
47                  / /Texture texture to be outside of the main differences in treatment platform 
48                  #if UNITY_UV_STARTS_AT_TOP
 49                  IF (_MainTex_TexelSize.y < 0 )
 50                      o.uv.w = . 1 - o.uv.w;        
 51 is                  #endif 
52 is  
53 is                  return O;
 54 is              }
 55  
56 is              fixed4 the frag (V2f I): SV_Target
 57 is              {
 58                  // with depth and texture to obtain a depth value zw 
59                  a float D = SAMPLE_DEPTH_TEXTURE (_CameraDepthTexture, i.uv.zw);
 60                  // reflect retroreflected NDC coordinates from [0, 1] to [-1,1] mapping, z is the depth value of the component itself 
61                 H = float4 float4 (i.uv.x * 2 - . 1 , i.uv.y * 2 - . 1 , D * 2 - . 1 , . 1 );
 62 is                  // inverse conversion and inverse matrix VP divided component w by the world coordinate position, divided by the w why the detailed mathematical derivation see previous link to the article 
63                  float4 D = MUL (_CurViewInserseMatrix, H);
 64-                  float4 worldPos = D / Dw;
 65  
66                  // respectively the previous frame and the current frame of NDC taking the difference coordinate calculation speed direction 
67                  float4 curViewPos = H;
 68                  float4 preViewPos = MUL (_PreViewMatrix, worldPos);
 69                  preViewPos / =preViewPos.w;
 70  
71 is                  // coefficients divided can be adjusted according to their needs 
72                  float2 Velocity = (curViewPos.xy-preViewPos.xy) / 10.0f ;
 73 is  
74                  float2 UV = i.uv.xy;
 75                  // Texture sampling speed weighting, there was calculated the first two frames, a current frame including a total of three values, values in descending order, and to ensure and 1, is not a need for additional divider
 76                  // purpose is to allow prior Yue frame look more light effect gradually disappeared track 
77                  a float velColRate [ . 3 ] = { 0.6 , 0.3 , 0.1 };
 78                  // current sampling result with the largest weight value of 0.6 
79                  fixed4 tex2D COL = (_MainTex, UV) * velColRate [ 0 ];
 80                 + = Velocity * UV _BlurSize;
 81  
82                  for ( int IT = . 1 ; IT < . 3 ; IT ++ )
 83                  {
 84                      // before two sampling results in descending order, 0.3, 0.1 
85                      fixed4 curCol = tex2D (_MainTex, uv.xy) * velColRate [IT];
 86                      // all the results together, to ensure that the weight is. 1 
87                      COL + = curCol;
 88                      // convenient texture offset by the speed, and make fuzzy coefficient control 
89                      UV + = velocity * _BlurSize;
 90                  }
 91 is  
92                  return fixed4(col.rgb,1.0);
93             }
94             ENDCG
95         }
96     }
97     FallBack Off
98 }

Results are as follows:

 

Guess you like

Origin www.cnblogs.com/koshio0219/p/11199547.html