Advertisement
Zgragselus

PCSS

Mar 20th, 2024
739
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.45 KB | None | 0 0
  1. static const uint PCSS_SampleCount = 16;
  2. static const float PCSS_SampleRadius = 1.0f;
  3. static float2 PCSS_Samples[PCSS_SampleCount] =
  4. {
  5.     float2(-0.1307115f, 0.1291686f),
  6.     float2(0.6154836f, 0.3147851f),
  7.     float2(-0.4295029f, -0.155486f),
  8.     float2(-0.591889f, 0.6969846f),
  9.     float2(0.2217633f, -0.3848645f),
  10.     float2(-0.2653467f, -0.6504169f),
  11.     float2(-0.1259185f, 0.8731781f),
  12.     float2(0.3423603f, 0.01230872f),
  13.     float2(0.1190722f, 0.4535096f),
  14.     float2(-0.7164063f, 0.1303319f),
  15.     float2(0.6048174f, -0.5608257f),
  16.     float2(0.1267647f, -0.8851751f),
  17.     float2(0.8812442f, -0.224937f),
  18.     float2(0.4235326f, 0.8168082f),
  19.     float2(-0.9404536f, -0.2363012f),
  20.     float2(-0.7055491f, -0.7052079f)
  21. };
  22.  
  23. /*static const uint PCSS_SampleCount = 32;
  24. static const float PCSS_SampleRadius = 1.0f;
  25. static const float2 PCSS_Samples[PCSS_SampleCount] = {
  26.     float2(0.06407013, 0.05409927),
  27.     float2(0.7366577, 0.5789394),
  28.     float2(-0.6270542, -0.5320278),
  29.     float2(-0.4096107, 0.8411095),
  30.     float2(0.6849564, -0.4990818),
  31.     float2(-0.874181, -0.04579735),
  32.     float2(0.9989998, 0.0009880066),
  33.     float2(-0.004920578, -0.9151649),
  34.     float2(0.1805763, 0.9747483),
  35.     float2(-0.2138451, 0.2635818),
  36.     float2(0.109845, 0.3884785),
  37.     float2(0.06876755, -0.3581074),
  38.     float2(0.374073, -0.7661266),
  39.     float2(0.3079132, -0.1216763),
  40.     float2(-0.3794335, -0.8271583),
  41.     float2(-0.203878, -0.07715034),
  42.     float2(0.5912697, 0.1469799),
  43.     float2(-0.88069, 0.3031784),
  44.     float2(0.5040108, 0.8283722),
  45.     float2(-0.5844124, 0.5494877),
  46.     float2(0.6017799, -0.1726654),
  47.     float2(-0.5554981, 0.1559997),
  48.     float2(-0.3016369, -0.3900928),
  49.     float2(-0.5550632, -0.1723762),
  50.     float2(0.925029, 0.2995041),
  51.     float2(-0.2473137, 0.5538505),
  52.     float2(0.9183037, -0.2862392),
  53.     float2(0.2469421, 0.6718712),
  54.     float2(0.3916397, -0.4328209),
  55.     float2(-0.03576927, -0.6220032),
  56.     float2(-0.04661255, 0.7995201),
  57.     float2(0.4402924, 0.3640312),
  58. };*/
  59.  
  60. inline float Random(float2 co)
  61. {
  62.     return frac(sin(dot(co.xy, float2(12.9898, 78.233))) * 43758.5453);
  63. }
  64.  
  65. inline float2 PCSS_Rotate(float2 pos, float2 rotationTrig)
  66. {
  67.     return float2(pos.x * rotationTrig.x - pos.y * rotationTrig.y, pos.y * rotationTrig.x + pos.x * rotationTrig.y);
  68. }
  69.  
  70. inline float2 PCSS_BlockerDistance(Texture2D<float2> tex, SamplerState state, float3 projCoord, float searchUV, float2 rotationTrig)
  71. {
  72.     int blockers = 0;
  73.     float avgBlockerDistance = 0.0f;
  74.     for (int i = 0; i < (int)PCSS_SampleCount; i++)
  75.     {
  76.         float2 offset = PCSS_Samples[i] * searchUV;
  77.         offset = PCSS_Rotate(offset, rotationTrig);
  78.  
  79.         float z = tex.SampleLevel(state, projCoord.xy + offset, 0.0f).x;
  80.         if (z < projCoord.z)
  81.         {
  82.             blockers++;
  83.             avgBlockerDistance += z;
  84.         }
  85.     }
  86.  
  87.     avgBlockerDistance /= blockers;
  88.  
  89.     return float2(avgBlockerDistance, (float)blockers);
  90. }
  91.  
  92. inline float PCSS_PCFFilter(Texture2D<float2> tex, SamplerState state, float3 projCoord, float filterRadiusUV, float penumbra, float2 rotationTrig, float2 grad)
  93. {
  94.     float sum = 0.0f;
  95.     for (int i = 0; i < (int)PCSS_SampleCount; i++)
  96.     {
  97.         float2 offset = PCSS_Samples[i] * filterRadiusUV;
  98.         offset = PCSS_Rotate(offset, rotationTrig);
  99.  
  100.         /*float4 tmp = tex.Gather(state, projCoord.xy + offset);
  101.         tmp.x = tmp.x < projCoord.z ? 0.0f : 1.0f;
  102.         tmp.y = tmp.y < projCoord.z ? 0.0f : 1.0f;
  103.         tmp.z = tmp.z < projCoord.z ? 0.0f : 1.0f;
  104.         tmp.w = tmp.w < projCoord.z ? 0.0f : 1.0f;
  105.         sum += lerp(lerp(tmp.w, tmp.z, grad.x), lerp(tmp.x, tmp.y, grad.x), grad.y);*/
  106.         sum += tex.SampleLevel(state, projCoord.xy + offset, 0.0f).x < projCoord.z ? 0.0f : 1.0f;
  107.     }
  108.     sum /= (float)PCSS_SampleCount;
  109.     return sum;
  110. }
  111.  
  112. inline float ShadowMap_PCSS(Texture2D<float2> tex, SamplerState state, float3 projCoord, float resolution, float pixelSize, float lightSize)
  113. {
  114.     float2 uv = projCoord.xy;
  115.     float depth = projCoord.z;
  116.     float zAwareDepth = depth;
  117.  
  118.     float rotationAngle = Random(projCoord.xy) * 3.1415926;
  119.     float2 rotationTrig = float2(cos(rotationAngle), sin(rotationAngle));
  120.  
  121.     float searchSize = lightSize / resolution * 100.0 * saturate(zAwareDepth - .02) / zAwareDepth;
  122.     float2 blockerInfo = PCSS_BlockerDistance(tex, state, projCoord, searchSize, rotationTrig);
  123.  
  124.     if (blockerInfo.y < 1.0)
  125.     {
  126.         return 1.0f;
  127.     }
  128.     else
  129.     {
  130.         float penumbra = max(zAwareDepth - blockerInfo.x, 0.0);
  131.         float filterRadiusUV = penumbra * lightSize / resolution * 100.0;
  132.  
  133.         float2 grad = frac(projCoord.xy * resolution + 0.5f);
  134.  
  135.         float shadow = PCSS_PCFFilter(tex, state, projCoord, filterRadiusUV, penumbra, rotationTrig, grad);
  136.  
  137.         return shadow;
  138.     }
  139. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement