PPEyeAdaptationBasic.bsl 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #include "$ENGINE$\PPBase.bslinc"
  2. #include "$ENGINE$\PPEyeAdaptationCommon.bslinc"
  3. technique PPEyeAdaptationBasic
  4. {
  5. mixin PPBase;
  6. mixin PPEyeAdaptationParams;
  7. code
  8. {
  9. [internal]
  10. cbuffer Input
  11. {
  12. int2 gInputTexSize;
  13. }
  14. Texture2D gCurFrameTex;
  15. Texture2D gPrevFrameTex;
  16. /**
  17. * Returns the value in range [0,1] on the triangle function with slope @p slope.
  18. * @p t must be in range [0,1].
  19. */
  20. float triangleFunc(float t, float slope)
  21. {
  22. return max(1.0f - 2.0f * slope * abs(t - 0.5f), 0.0f);
  23. }
  24. /**
  25. * Calculates the average value of all pixels in the input texture. The pixels are
  26. * weighted using a triangle filter using @p slope as the line slope. @p slope of 0
  27. * means all pixels will be uniformly weighted.
  28. */
  29. float calcWeightedAverageAlpha(Texture2D input, int2 inputSize, float slope)
  30. {
  31. float2 invSize = 1.0f / inputSize;
  32. float sum = 0.0f;
  33. float weightSum = 0.0f;
  34. for (uint i = 0; i < inputSize.x; ++i)
  35. {
  36. float weightX = triangleFunc(i * invSize.x, slope);
  37. for (uint j = 0; j < inputSize.y; ++j)
  38. {
  39. float weightY = triangleFunc(j * invSize.y, slope);
  40. float weight = max(weightX * weightY, 0.05f);
  41. float value = input.Load(int3(i, j, 0)).a;
  42. sum += value * weight;
  43. weightSum += weight;
  44. }
  45. }
  46. return sum / weightSum;
  47. }
  48. float4 fsmain(VStoFS input) : SV_Target0
  49. {
  50. float slope = 0.0f; // TODO - Allow custom slope?
  51. float avgLuminance = calcWeightedAverageAlpha(gCurFrameTex, gInputTexSize, slope);
  52. // Scale back into normal range (was log2 encoded and scale into [0, 1] range)
  53. avgLuminance = exp2((avgLuminance - gEyeAdaptationParams[0].y) / gEyeAdaptationParams[0].x);
  54. avgLuminance /= 0.16f;
  55. // Clamp to valid range
  56. avgLuminance = clamp(avgLuminance, gEyeAdaptationParams[1].x, gEyeAdaptationParams[1].y);
  57. float exposureScale = gEyeAdaptationParams[2].x;
  58. float oldExposure = gPrevFrameTex.Load(int3(0, 0, 0)).x;
  59. float oldLuminance = exposureScale / oldExposure; // Assuming same exposure scale as last frame
  60. float frameDelta = gEyeAdaptationParams[2].y;
  61. float smoothAdaptation = smoothEyeAdaptation(oldLuminance, avgLuminance, frameDelta);
  62. return exposureScale / smoothAdaptation; // Returns exposure
  63. }
  64. };
  65. };