Advertisement
noradninja

Crepuscupular Rays Shader

Nov 30th, 2022 (edited)
1,107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.47 KB | None | 0 0
  1. // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
  2.  
  3.  
  4. Shader "Lighting/Crepuscular Rays" {
  5.    
  6.     Properties{
  7.         _MainTex("Base (RGB)", 2D) = "white" {}
  8.         _BlurTex("BlurTex (RGB)", 2D) = "white" {}
  9.         _NumSamples("Number of Samples", Range(0, 1024)) = 128
  10.         _Density("Density", Range(0, 1)) = 1.0
  11.         _Weight("Weight", Range(0, 2)) = 1.0
  12.         _Decay("Decay", Range(0, 1)) = 1.0
  13.         _Exposure("Exposure", Range(0, 1)) = 1.0
  14.         _Contrast("Contrast", Range(1, 5)) = 1.0
  15.         _PerpendicularFalloff("Perpendicular Falloff Rate", Range(0.01, 1)) = 1.0
  16.         _CosAngle("Angle", Float) = 1
  17.         [IntRange] _StencilRef ("Stencil Ref", Range(0,255)) = 0
  18.         _TintColor ("Tint Color", Color) = (.5, .5, .5, .5)
  19.     }
  20.         CGINCLUDE
  21.         #include "UnityCG.cginc"
  22.         #pragma target 2.0
  23.  
  24.         uniform sampler2D_half _MainTex;
  25.         uniform sampler2D_half _BlurTex;
  26.         uniform sampler2D _CameraDepthTexture;
  27.         half3 _LightPos;
  28.         half _NumSamples;
  29.         half _Density;
  30.         half _Weight;
  31.         half _Decay;
  32.         half _Exposure;
  33.         half _Contrast;
  34.         uniform half4 _Parameter;
  35.         uniform half4 _MainTex_TexelSize;
  36.         half4 _MainTex_ST;
  37.         half _LightY;
  38.         half _CosAngle;
  39.         half4 _TintColor;
  40.         half _PerpendicularFalloff;
  41.        
  42.  
  43.        
  44.         struct appdata
  45.         {
  46.             float4 pos : POSITION;
  47.             float2 uv : TEXCOORD0;
  48.         };
  49.  
  50.         struct v2f
  51.         {
  52.             float4 pos : SV_POSITION;
  53.             float2 uv  : TEXCOORD0;
  54.         };
  55.  
  56.         struct v2f_withBlurCoordsSGX
  57.         {
  58.             float4 pos : SV_POSITION;
  59.             half2 uv : TEXCOORD0;
  60.             half4 offs[3] : TEXCOORD1;
  61.         };
  62.  
  63.         static const half curve[7] = { 0.0205, 0.0855, 0.232, 0.324, 0.232, 0.0855, 0.0205 };  // gauss'ish blur weights
  64.        
  65.  
  66.  
  67. ////////////// accumulator for rays  /////////////////
  68.         v2f vert( appdata v )
  69.             {
  70.                 v2f o;
  71.                 o.pos = UnityObjectToClipPos (v.pos);
  72.                 o.uv = v.uv;
  73.                 return o;
  74.             }
  75.            
  76.            
  77.         half4 frag(v2f i) : COLOR
  78.             {
  79.                 // Calculate vector from pixel to light source in screen space.
  80.                 half4 light = half4(_LightPos.xyz,1);
  81.                 half2 deltaTexCoord = (0,0);
  82.                 half normalizedLightY = normalize(light.y);
  83.  
  84.                 // get our y vector direction, and swap the direction the coordinates are plotted based on that
  85.                 // so that it looks correct regardless of current camera rotation
  86.                 if (light.y < 0.5h){
  87.                     deltaTexCoord = (i.uv + light.xy);
  88.                
  89.                 }
  90.                
  91.                 if (light.y > 0.5h){
  92.                     deltaTexCoord = (i.uv - light.xy);
  93.                 }
  94.                
  95.                 // Divide by number of samples and scale by control factor.
  96.                 deltaTexCoord *= 1.0h / _NumSamples * _Density;
  97.                 // Store initial sample.
  98.                 half2 uv = i.uv;
  99.                 half3 color = tex2D(_MainTex, uv);
  100.                 // Set up illumination decay factor.
  101.                 half illuminationDecay = 1.0h;
  102.                 // Evaluate summation from Equation 3 NUM_SAMPLES iterations.
  103.                 for (int i = 0; i < _NumSamples; i++)
  104.                 {
  105.                     // Step sample location along ray.
  106.                     uv -= deltaTexCoord;
  107.                     // Retrieve sample at new location.
  108.                     half3 sample = tex2D(_MainTex, uv);
  109.                     // Apply sample attenuation scale/decay factors.
  110.                     sample *= illuminationDecay * (_Weight/ _NumSamples*4);
  111.                     sample *= 2;
  112.                    
  113.                     // Accumulate combined color.
  114.                     color += sample;
  115.                     // Update exponential decay factor.
  116.                     illuminationDecay *= _Decay;
  117.                 }
  118.                 //drop color- uncomment line below for greyscale output for rays
  119.                 //color = (color.r + color.g + color.b)/3;
  120.                 // Output final color with a further scale control factor.
  121.                 color *= normalizedLightY;
  122.                 return (max(half4(color * _Exposure, 1), 0.15h));
  123.             }
  124. /////////////// SGX Horizontal Blur /////////////////////////////      
  125.         v2f_withBlurCoordsSGX vertBlurHorizontalSGX (appdata_img v)
  126.             {
  127.                 v2f_withBlurCoordsSGX o;
  128.                 o.pos = UnityObjectToClipPos(v.vertex);
  129.                
  130.                 o.uv = UnityStereoScreenSpaceUVAdjust(v.texcoord.xy, _MainTex_ST);
  131.  
  132.                 half offsetMagnitude = _MainTex_TexelSize.x * _Parameter.x;
  133.                 o.offs[0] = UnityStereoScreenSpaceUVAdjust(v.texcoord.xyxy + offsetMagnitude * half4(-3.0h, 0.0h, 3.0h, 0.0h), _MainTex_ST);
  134.                 o.offs[1] = UnityStereoScreenSpaceUVAdjust(v.texcoord.xyxy + offsetMagnitude * half4(-2.0h, 0.0h, 2.0h, 0.0h), _MainTex_ST);
  135.                 o.offs[2] = UnityStereoScreenSpaceUVAdjust(v.texcoord.xyxy + offsetMagnitude * half4(-1.0h, 0.0h, 1.0h, 0.0h), _MainTex_ST);
  136.  
  137.                 return o;
  138.             }
  139. /////////////// SGX Vertical Blur /////////////////////////////    
  140.         v2f_withBlurCoordsSGX vertBlurVerticalSGX (appdata_img v)
  141.             {
  142.                 v2f_withBlurCoordsSGX o;
  143.                 o.pos = UnityObjectToClipPos(v.vertex);
  144.                
  145.                 o.uv = half4(UnityStereoScreenSpaceUVAdjust(v.texcoord.xy, _MainTex_ST),1,1);
  146.  
  147.                 half offsetMagnitude = _MainTex_TexelSize.y * _Parameter.x;
  148.                 o.offs[0] = UnityStereoScreenSpaceUVAdjust(v.texcoord.xyxy + offsetMagnitude * half4(0.0h, -3.0h, 0.0h, 3.0h), _MainTex_ST);
  149.                 o.offs[1] = UnityStereoScreenSpaceUVAdjust(v.texcoord.xyxy + offsetMagnitude * half4(0.0h, -2.0h, 0.0h, 2.0h), _MainTex_ST);
  150.                 o.offs[2] = UnityStereoScreenSpaceUVAdjust(v.texcoord.xyxy + offsetMagnitude * half4(0.0h, -1.0h, 0.0h, 1.0h), _MainTex_ST);
  151.  
  152.                 return o;
  153.             }
  154. ///////////// SGX Frag  //////////////////////////////////////
  155.         half4 fragBlurSGX ( v2f_withBlurCoordsSGX i ) : SV_Target
  156.             {
  157.                 half2 uv = i.uv.xy;
  158.                
  159.                 half4 color = tex2D(_MainTex, i.uv) * curve[3];
  160.                
  161.                 for( int l = 0; l < 3; l++ )  
  162.                 {  
  163.                     half4 tapA = tex2D(_MainTex, i.offs[l].xy);
  164.                     half4 tapB = tex2D(_MainTex, i.offs[l].zw);
  165.                     color += (tapA + tapB) * curve[l];
  166.                 }
  167.                 return color;
  168.             }
  169. /////////////// Composition /////////////////////////////
  170.         v2f vertFinal(appdata i)
  171.             {
  172.                 v2f o = (v2f)0;
  173.                 UNITY_INITIALIZE_OUTPUT(v2f, o);
  174.                 o.pos = UnityObjectToClipPos(i.pos);
  175.                 o.uv = (i.uv);
  176.                 return o;
  177.             }
  178.            
  179.         half4 fragFinal(v2f i) : SV_Target
  180.             {
  181.                 half4 light = half4(_LightPos.xyz,1);
  182.                 half normalizedLightY = half((light.y + 1)/2);
  183.                 _CosAngle = 1- abs(cos(light.z));
  184.                 fixed4 col = tex2D(_MainTex, i.uv);
  185.                 fixed4 sample = tex2D(_BlurTex, i.uv);
  186.                 fixed contrast = _Contrast;
  187.                 sample = sample.r + sample.g + sample.b;
  188.                 sample /= 2.0h;
  189.                 fixed4 finalSample = (((col) + (sample * 0.4h)) - 0.5h) * contrast + 0.445h; //final sampled color
  190.                 fixed4 finalColor = (col + (col * 0.04h) - 0.01h); //final modulated base color
  191.                 fixed4 blitColor;
  192.                 //this is where we lerp the opacity of the effect as the cosine angle chages- this is to get around the fact that as the cosine of the angle between the camera and light vector becomes perpendicular, the offset trends to infinity, which creates a single frame all white 'flash'
  193.                 blitColor = lerp (finalSample, finalColor, 1-(_CosAngle / (_PerpendicularFalloff / 10) ) );
  194.                 return blitColor;
  195.             }
  196.        
  197.         ENDCG
  198.     ////// Passes /////////////////////////////////////////////////////
  199.     SubShader {
  200.         ZTest Always
  201.         Cull Off
  202.         //0- calculate low resolution rays
  203.        
  204.         Pass {
  205.                 CGPROGRAM
  206.                 #pragma vertex vert
  207.                 #pragma fragment frag
  208.                 #pragma fragmentoption ARB_precision_hint_fastest
  209.                 ENDCG
  210.             }
  211.             //2- vertical blur
  212.         Pass {
  213.                 CGPROGRAM
  214.                 #pragma vertex vertBlurVerticalSGX
  215.                 #pragma fragment fragBlurSGX
  216.                 #pragma fragmentoption ARB_precision_hint_fastest
  217.                 ENDCG
  218.             }  
  219.            
  220.         //3- horizontal Blur
  221.         Pass {     
  222.                 CGPROGRAM  
  223.                 #pragma vertex vertBlurHorizontalSGX
  224.                 #pragma fragment fragBlurSGX
  225.                 #pragma fragmentoption ARB_precision_hint_fastest
  226.                 ENDCG
  227.             }
  228.         Pass //4- composition
  229.         {
  230.             CGPROGRAM
  231.             #pragma vertex vertFinal
  232.             #pragma fragment fragFinal
  233.             #pragma fragmentoption ARB_precision_hint_fastest
  234.             ENDCG
  235.         }
  236.     }
  237. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement