home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 18759 / ROE.7z / QSSHADER_QSShadow.h < prev    next >
Encoding:
C/C++ Source or Header  |  2020-09-17  |  10.3 KB  |  397 lines

  1. #ifndef QSSHADER_QSShadow_H
  2. #define QSSHADER_QSShadow_H
  3. #include "FunctionLib.h"
  4. #include "DepthUtil.h"
  5. #include "QSScreenSpaceDepth.h"
  6.  
  7. //cascaded shadow map
  8. #if CSM_4
  9.     #define CSM_INUSE_NUM 4
  10. #else
  11.     #define CSM_INUSE_NUM 3
  12. #endif
  13.  
  14. float4x4 ViewToLightSpace0;
  15. float4x4 ViewToLightSpace1;
  16. float4x4 ViewToLightSpace2;
  17. float4x4 ViewToLightSpace3;
  18. float4x4 ViewToLightSpace4;
  19.  
  20. float4 CascadedInfo;     //for pcf solution ----x:ShadowMapWidth, y:param/ShadowMapWidth, z:cascade 0 far, w:cascade 1 far
  21.                          //for evsm solution  yzw cascaded 0,1,2 far
  22. float4 VestureSmBias;     //x for bias on vesture shadow depth sampling(0.0f when no smooth transition, 1.0f when smooth transition)
  23.                          //y notify if the unify rt is for 4 or 5 rt merging
  24.                          //z vesture lerp ratio                         
  25. float2 Jittering;        // already done some calculation, refer CPP code.    
  26.              
  27. /*
  28.  *    screen space shadow map
  29.  */
  30.  
  31. sampler2D SSSMSampler;
  32.  
  33. float SampleScreenSpaceShadow(float2 uv)
  34. {    
  35.     return tex2D(SSSMSampler, uv).x;
  36. }
  37.  
  38. /*
  39.  *    local light shadow
  40.  */
  41. float4 ShadowMapIdxMask;
  42. sampler2D LocalLightShadowSampler;
  43. float2 SampleLocalLightShadow(float2 uv)
  44. {    
  45.     return dot(tex2D(LocalLightShadowSampler, uv), ShadowMapIdxMask).xx;
  46. }
  47. sampler2D sLightDepth;
  48. sampler2D sDynamicObjLightDepth;
  49. sampler2D sNoise;
  50. float4x4  cScreenToLight;
  51. float4 cNoiseSB;
  52.  
  53. #define NUM_OFFSETS 4
  54. float4 offsets[NUM_OFFSETS];
  55.  
  56. static const float2 offsets8[8] = {
  57.     float2( -0.16076615, -0.16076620 ),
  58.     float2( -0.52473867, -0.14628546 ),
  59.     float2( -0.80486661,  0.51980901 ),
  60.     float2( -0.14628546,  0.52473867 ),
  61.     float2(  0.91154134, -0.17331968 ),
  62.     float2(  0.44585308, -0.44585305 ),
  63.     float2(  0.51980895,  0.80486661 ),
  64.     float2(  0.17331968, -0.91154134 )
  65. };
  66. float FetchShadow(float4 uv)
  67. {
  68.     return tex2Dproj(sLightDepth, uv).x;
  69. }
  70. float FetchShadow(float2 uv, float2 zw)
  71. {
  72.     float4 lpos = { float3(uv, zw.x) * zw.y, zw.y };
  73.     return tex2Dproj(sLightDepth, lpos).x;
  74. }
  75. float FilterShadow(float4 light_pos, float2 scrPos)
  76. {
  77.     const int c_shadow_res = 1024;
  78.     float2 evenOdd = (scrPos % 2) - 0.5;
  79.  
  80.     float c =  FetchShadow(light_pos);
  81.     /*for (int i = 0; i < 8; i++)
  82.     {
  83.         c += FetchShadow(light_pos + 2.5 * float4(offsets8[i] * evenOdd, 0, 0) / c_shadow_res);
  84.     }
  85.     c /= 8;*/
  86.     return c;
  87. }
  88.  
  89. float FilterShadow(float4 light_pos, float4 rotation)
  90. {
  91.     light_pos.xyz /= light_pos.w;
  92.  
  93.     float c = 0;
  94.  
  95.     float2 uv = light_pos.xy;
  96.  
  97.     HLSL_ISOLATE
  98.     {
  99.         float4 uvs0, uvs1;
  100.         uvs0  = rotation.xyxy * offsets[0] + uv.xyxy;
  101.         uvs0 += rotation.zwzw * offsets[0];
  102.  
  103.         uvs1  = rotation.xyxy * offsets[1] + uv.xyxy;
  104.         uvs1 += rotation.zwzw * offsets[1];
  105.  
  106.         float4 depths;
  107.         depths.x = FetchShadow(uvs0.xy, light_pos.zw).x;
  108.         depths.y = FetchShadow(uvs0.zw, light_pos.zw).x;
  109.         depths.z = FetchShadow(uvs1.xy, light_pos.zw).x;
  110.         depths.w = FetchShadow(uvs1.zw, light_pos.zw).x;
  111.  
  112.         c += dot(depths, 0.125);
  113.     }
  114.  
  115.     HLSL_ISOLATE
  116.     {
  117.         float4 uvs0, uvs1;
  118.         uvs0  = rotation.xyxy * offsets[2] + uv.xyxy;
  119.         uvs0 += rotation.zwzw * offsets[2];
  120.  
  121.         uvs1  = rotation.xyxy * offsets[3] + uv.xyxy;
  122.         uvs1 += rotation.zwzw * offsets[3];    
  123.  
  124.         float4 depths;
  125.         depths.x = FetchShadow(uvs0.xy, light_pos.zw).x;
  126.         depths.y = FetchShadow(uvs0.zw, light_pos.zw).x;
  127.         depths.z = FetchShadow(uvs1.xy, light_pos.zw).x;
  128.         depths.w = FetchShadow(uvs1.zw, light_pos.zw).x;
  129.  
  130.  
  131.         c += dot(depths, 0.125);
  132.     }
  133.  
  134.     return c;
  135. }
  136.  
  137. float SampleShadow(float2 sc_xy, float scene_z, float2 scrPos)
  138. {
  139.     float4 screen_pos = float4(sc_xy, scene_z, 1);
  140.  
  141.     float4 light_pos = mul(screen_pos, cScreenToLight);
  142.  
  143.     return FilterShadow(light_pos, scrPos) /** cShadowFade.x + cShadowFade.y*/;
  144. }
  145.  
  146. float SampleShadowBlur(float4 screen_pos, float4 rotation)
  147. {
  148.     float4 light_pos = mul(screen_pos, cScreenToLight);
  149.     return FilterShadow(light_pos, rotation)/* * cShadowFade.x + cShadowFade.y*/;
  150. }
  151.  
  152. sampler2D LightViewDepthLinear;
  153. sampler2D LightViewDepthPoint;
  154.  
  155. #if ENHANCED_BLUR
  156.  
  157. #define PCF_NUM 12
  158. static const float2 crossPcf[PCF_NUM] = 
  159. {
  160.     float2( -1.0f, -1.0f) * 1,
  161.     float2(  1.0f, -1.0f) * 1,
  162.     float2(  1.0f, 1.0f) * 1,
  163.     float2( -1.0f, 1.0f) * 1,
  164.     float2( -1.0f, -1.0f) * 4,
  165.     float2(  1.0f, -1.0f) * 4,
  166.     float2(  1.0f, 1.0f) * 4,
  167.     float2( -1.0f, 1.0f) * 4,
  168.     float2( -1.0f, -1.0f) * 6,
  169.     float2(  1.0f, -1.0f) * 6,
  170.     float2(  1.0f, 1.0f) * 6,
  171.     float2( -1.0f, 1.0f) * 6,
  172. };
  173.  
  174. #else
  175.  
  176. #define PCF_NUM 4
  177. static const float2 crossPcf[PCF_NUM] = 
  178. {
  179.     float2( -1.0f, -1.0f),
  180.     float2(  1.0f, -1.0f),
  181.     float2(  1.0f, 1.0f),
  182.     float2( -1.0f, 1.0f),
  183. };
  184.  
  185. #endif  //ENHANCED_BLUR
  186.  
  187. float FilterShadow(sampler2D shadowMap, float2 uv, float halfInvSmRes, float bias, float viewZ)
  188. {
  189.     float shadowValue = 0.0f;
  190.  
  191.     for(int i=0; i<PCF_NUM; i++)
  192.     {
  193.         float2 pcfUV = uv + halfInvSmRes*crossPcf[i].xy;
  194.         {
  195.             float4 uvt = float4(pcfUV,viewZ-bias, 1.0f);
  196.             shadowValue+=tex2Dproj(shadowMap, uvt).r;              
  197.         }
  198.     }
  199.  
  200.     return shadowValue/PCF_NUM;
  201. }
  202.  
  203. float RegularHwPcf(sampler2D shadowMap, float2 uv, float halfInvSmRes, float bias, float viewZ,float2 bound, float scale)
  204. {
  205.     float shadowValue = 0.0f;
  206.     float2 halfInvRes = float2(halfInvSmRes*scale, halfInvSmRes);
  207.     uv += halfInvRes;
  208.  
  209.     for(int i=0; i<PCF_NUM; i++)
  210.     {
  211.         float2 pcfUV = uv + halfInvRes*crossPcf[i].xy;
  212.         if(pcfUV.x<bound.x||pcfUV.x>=bound.y||pcfUV.y<0.0f||pcfUV.y>1.0f)
  213.         {
  214.             shadowValue+=1.0f;
  215.         }
  216.         else
  217.         {
  218.             float4 uvt = float4(pcfUV,viewZ-bias, 1.0f);
  219.             shadowValue+=tex2Dproj(shadowMap, uvt).r;              
  220.         }
  221.     }
  222.  
  223.     return shadowValue/PCF_NUM;
  224. }
  225.  
  226. float SingleHwPcf(sampler2D shadowMap, float2 uv, float halfInvSmRes, float bias, float viewZ,float2 bound, float scale)
  227. {
  228.     float shadowValue = 0.0f;
  229.     float2 halfInvRes = float2(halfInvSmRes*scale, halfInvSmRes);
  230.     uv += halfInvRes;
  231.     
  232.     {
  233.         float2 pcfUV = uv;
  234.         if(pcfUV.x<bound.x||pcfUV.x>=bound.y||pcfUV.y<0.0f||pcfUV.y>1.0f)
  235.         {
  236.             shadowValue+=1.0f;
  237.         }
  238.         else
  239.         {
  240.             float4 uvt = float4(pcfUV,viewZ-bias, 1.0f);
  241.             shadowValue+=tex2Dproj(shadowMap, uvt).r;              
  242.         }
  243.     }
  244.  
  245.     return shadowValue;
  246. }
  247.  
  248. float3 ScreenPosToLightViewPos(float4 screenPos, float4x4 viewToLightView)
  249. {    
  250.     float viewSpaceZ = CalcViewZFromDeviceZ(screenPos.z);
  251.     float viewSpaceX = (screenPos.x-0.5f)*viewSpaceZ*ProjParam.x;
  252.     float viewSpaceY = (0.5f-screenPos.y)*viewSpaceZ*ProjParam.y;
  253.     float4 viewPos = float4(viewSpaceX, viewSpaceZ, viewSpaceY, 1.0f);
  254.  
  255.     float4 homoPosLightView = mul(viewPos, viewToLightView);
  256.     homoPosLightView.xyz /= homoPosLightView.w;
  257.     homoPosLightView.xy = homoPosLightView.xy*0.5f+0.5f;
  258.     homoPosLightView.y = 1-homoPosLightView.y;
  259.  
  260.     return homoPosLightView.xyz;
  261. }
  262.  
  263. float SampleShadow(float3 lightViewPos, float halfInvSmRes, float bias, float xBias, float scale)
  264. {
  265.     float result;    
  266.  
  267.     result = RegularHwPcf(LightViewDepthLinear, lightViewPos.xy, halfInvSmRes, bias, lightViewPos.z,float2(xBias, xBias+scale), scale);
  268.  
  269.     //the 4th shadow pass needs darken
  270. #if CSM_INUSE_NUM>3
  271.     if(xBias>=scale*(CSM_INUSE_NUM-1))
  272.     {
  273.         result *= result;        
  274.     }
  275. #endif
  276.     return result;
  277. }
  278.  
  279. bool LightViewCoordValid(float2 v)
  280. {
  281.     return v.x>=0.0f && v.x<=1.0f && v.y>=0.0f && v.y<=1.0f;
  282. }
  283.  
  284. void CalcCascadeUv(float4 screenPos, float3 distBound, float scale, float vestureBias, inout float3 lightViewPos0, inout float3 lightViewPos1, out float xBias, inout float xbias2, inout float lerpRatio)
  285. {    
  286.     //light view pos calc
  287.     float3 lightViewPosSrc[CSM_INUSE_NUM];    
  288.  
  289.     lightViewPosSrc[0] = ScreenPosToLightViewPos(screenPos, ViewToLightSpace0);
  290.     lightViewPosSrc[1] = ScreenPosToLightViewPos(screenPos, ViewToLightSpace1);
  291.     lightViewPosSrc[2] = ScreenPosToLightViewPos(screenPos, ViewToLightSpace2);
  292.     #if CSM_INUSE_NUM>3
  293.         lightViewPosSrc[3] = ScreenPosToLightViewPos(screenPos, ViewToLightSpace3);
  294.     #endif//CSM_INUSE_NUM>3
  295.  
  296.     float scaleSrc[4] = {1.0f,2.0f,0.0f,3.0f+vestureBias};
  297.     float lerpThreshold = 0.09f;
  298.     float epsilon = 0.002f;
  299.     float invEplison = 1.0f-epsilon;
  300.  
  301.     for(int idx=0; idx<CSM_INUSE_NUM; idx++)
  302.     {
  303.         float minDelta = lightViewPosSrc[idx].x-epsilon;
  304.         minDelta = min(minDelta, invEplison-lightViewPosSrc[idx].x);
  305.         minDelta = min(minDelta, lightViewPosSrc[idx].y-epsilon);
  306.         minDelta = min(minDelta, invEplison-lightViewPosSrc[idx].y);
  307.  
  308.         if(minDelta>0.0f)
  309.         {
  310.             xBias = scaleSrc[idx]*scale;
  311.  
  312.             lightViewPos0.yz = lightViewPosSrc[idx].yz;
  313.             lightViewPos0.x = xBias+lightViewPosSrc[idx].x*scale;
  314.  
  315. #if CASCADE_LERP
  316.             if(minDelta<lerpThreshold)
  317.             {
  318.                 lerpRatio = minDelta/lerpThreshold;
  319.  
  320.                 if(idx<CSM_INUSE_NUM-1)
  321.                 {
  322.                     int dstIdx = LightViewCoordValid(lightViewPosSrc[idx+1].xy) ? idx+1 : idx+2;
  323.                     dstIdx = min(dstIdx, CSM_INUSE_NUM-1);
  324.                     xbias2 = scaleSrc[dstIdx]*scale;                    
  325.                     lightViewPos1.yz = lightViewPosSrc[dstIdx].yz;
  326.                     lightViewPos1.x = xbias2+lightViewPosSrc[dstIdx].x*scale;
  327.                 }
  328.                 //give an invalid value, so that we'll have 1.0f shadow
  329.                 else
  330.                 {
  331.                     xbias2 = 2.0f;
  332.                 }
  333.             }
  334. #endif//CASCADE_LERP
  335.  
  336.             return;
  337.         }
  338.     }
  339. }
  340.  
  341. float CascadedShadowMap(float4 screenPos, out float xBias, out float2 smUv)
  342. {
  343.     //const    
  344.     float unifySmRtNum = VestureSmBias.y+CSM_INUSE_NUM;
  345.     float scale = 1.0f/unifySmRtNum;   
  346.  
  347.     float bias = 0; 
  348.  
  349.     float halfInvSmRes = CascadedInfo.x;
  350.     float3 distBound = CascadedInfo.yzw;
  351.     float vestureBias = VestureSmBias.x;
  352.  
  353.     float3 lightViewPos = float3(0.0f,0.0f,0.0f);
  354.     float xbias2=0.0f, lerpRatio=1.0f;
  355.     float3 lightViewPos2 = float3(0.0f,0.0f,0.0f);
  356.  
  357.     CalcCascadeUv(screenPos, distBound, scale, vestureBias, lightViewPos, lightViewPos2, xBias, xbias2, lerpRatio);
  358.  
  359.     smUv = lightViewPos.xy;
  360.  
  361.     float result = SampleShadow(lightViewPos, halfInvSmRes, bias, xBias, scale);
  362.  
  363. #if VESTURE_LERP        
  364.     if(xBias>=scale*(CSM_INUSE_NUM-1))
  365.     {
  366.         float3 dstLightViewPos = ScreenPosToLightViewPos(screenPos, ViewToLightSpace4);
  367.  
  368.         float dstXBias = xBias;
  369.         dstXBias += VestureSmBias.x>0.0f ? -scale : scale;
  370.         dstLightViewPos.x = dstXBias+dstLightViewPos.x*scale;
  371.         float dstResult = SampleShadow(dstLightViewPos, halfInvSmRes, bias, dstXBias, scale);
  372.         result = lerp(result, dstResult, VestureSmBias.z);
  373.     }
  374. #endif
  375.  
  376. #if CASCADE_LERP
  377.     if(lerpRatio<1.0f)
  378.     {
  379.         float lerpDst;
  380.  
  381.         if(xbias2<=1.0f)
  382.         {
  383.             lerpDst = SampleShadow(lightViewPos2, halfInvSmRes, bias, xbias2, scale);
  384.         }
  385.         else
  386.         {
  387.             lerpDst = 1.0f;
  388.         }
  389.         
  390.         result = lerp(lerpDst, result, lerpRatio);
  391.     }
  392. #endif//CASCADE_LERP
  393.  
  394.     return result;
  395. }
  396.  
  397. #endif//QSSHADER_QSShadow_H