PPScreenSpaceLensFlare.bsl 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include "$ENGINE$\PPBase.bslinc"
  2. #include "$ENGINE$\ColorSpace.bslinc"
  3. shader PPScreenSpaceLensFlare
  4. {
  5. mixin PPBase;
  6. mixin ColorSpace;
  7. variations
  8. {
  9. // 0 - No halo, 1 - Halo with aspect, 2 - Halo without aspect
  10. HALO_MODE = { 0, 1, 2 };
  11. CHROMATIC_ABERRATION = { true, false };
  12. };
  13. code
  14. {
  15. [internal]
  16. cbuffer Input
  17. {
  18. float gThreshold;
  19. float gGhostSpacing;
  20. uint gGhostCount;
  21. float gHaloRadius;
  22. float gHaloThickness;
  23. float gHaloThreshold;
  24. float gHaloAspectRatio;
  25. float gChromaticAberration;
  26. }
  27. Texture2D gInputTex;
  28. [alias(gInputTex)]
  29. SamplerState gInputSamp;
  30. Texture2D gGradientTex;
  31. [alias(gGradientTex)]
  32. SamplerState gGradientSamp
  33. {
  34. AddressU = CLAMP;
  35. AddressV = CLAMP;
  36. AddressW = CLAMP;
  37. };
  38. float3 sampleSceneColor(float2 uv)
  39. {
  40. #if CHROMATIC_ABERRATION
  41. float2 chromaticOffset = normalize(0.5f - uv) * gChromaticAberration;
  42. return float3(
  43. gInputTex.SampleLevel(gInputSamp, uv + chromaticOffset, 0.0f).r,
  44. gInputTex.SampleLevel(gInputSamp, uv, 0.0f).g,
  45. gInputTex.SampleLevel(gInputSamp, uv - chromaticOffset, 0.0f).b
  46. );
  47. #else
  48. return gInputTex.SampleLevel(gInputSamp, uv, 0.0f).rgb;
  49. #endif
  50. }
  51. float windowCubic(float x, float center, float radius)
  52. {
  53. x = min(abs(x - center) / radius, 1.0f);
  54. return 1.0f - x * x * (3.0f - 2.0f * x);
  55. }
  56. float4 fsmain(VStoFS input) : SV_Target0
  57. {
  58. float4 output = 0;
  59. float2 uv = 1.0f - input.uv0; // Flip UV
  60. float2 ghostVec = (0.5f - uv) * gGhostSpacing;
  61. for (uint i = 0; i < gGhostCount; ++i)
  62. {
  63. float2 ghostUV = frac(uv + ghostVec * i);
  64. float3 sceneColor = sampleSceneColor(ghostUV);
  65. sceneColor = max(sceneColor - gThreshold, 0.0f);
  66. float distanceToCenter = distance(ghostUV, 0.5f);
  67. sceneColor *= gGradientTex.Sample(gGradientSamp, float2(distanceToCenter, 0.5)).rgb;
  68. output += float4(sceneColor, 0.0f);
  69. }
  70. // Halo
  71. #if HALO_MODE != 0
  72. float2 haloVec = 0.5f - uv;
  73. #if HALO_MODE == 2
  74. haloVec = normalize(haloVec);
  75. float haloWeight = distance(uv, 0.5f);
  76. #else
  77. haloVec.x /= gHaloAspectRatio;
  78. haloVec = normalize(haloVec);
  79. haloVec.x *= gHaloAspectRatio;
  80. float2 wuv = (uv - float2(0.5f, 0.0f)) / float2(gHaloAspectRatio, 1.0f) + float2(0.5f, 0.0f);
  81. float haloWeight = distance(wuv, 0.5f);
  82. #endif
  83. haloVec *= gHaloRadius;
  84. haloWeight = windowCubic(haloWeight, gHaloRadius, gHaloThickness);
  85. float3 sceneColor = sampleSceneColor(uv + haloVec);
  86. sceneColor = max(sceneColor - gHaloThreshold, 0.0f);
  87. output += float4(sceneColor * haloWeight, 0.0f);
  88. #endif
  89. return output;
  90. }
  91. };
  92. };