PPCreateTonemapLUT.bsl 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #include "$ENGINE$\VolumeRenderBase.bslinc"
  2. #include "$ENGINE$\PPTonemapCommon.bslinc"
  3. #include "$ENGINE$\PPWhiteBalance.bslinc"
  4. Parameters =
  5. {
  6. };
  7. Technique
  8. : inherits("VolumeRenderBase")
  9. : inherits("PPTonemapCommon")
  10. : inherits("PPWhiteBalance") =
  11. {
  12. Language = "HLSL11";
  13. Pass =
  14. {
  15. DepthWrite = false;
  16. DepthRead = false;
  17. Fragment =
  18. {
  19. cbuffer Input
  20. {
  21. // [0]: x - shoulder strength, y - linear strength, z - linear angle, w - toe strength
  22. // [1]: x - toe numerator, y - toe denominator, z - linear white point, w - unused
  23. float4 gTonemapParams[2];
  24. float gGammaAdjustment;
  25. // 0 - sRGB, 1 - Rec.709, 2 - 2.2 gamma
  26. uint gGammaCorrectionType;
  27. float3 gSaturation;
  28. float3 gContrast;
  29. float3 gGain;
  30. float3 gOffset;
  31. };
  32. /**
  33. * Filmic curve used for tonemapping.
  34. *
  35. * @param linearColor Linear color.
  36. * @return Transformed color.
  37. */
  38. float3 FilmicCurve(float3 color)
  39. {
  40. // Formula from John Hable's Uncharted 2 presentation
  41. float3 a = color * (gTonemapParams[0].x * color + gTonemapParams[0].y * gTonemapParams[0].z);
  42. float b = gTonemapParams[0].w * gTonemapParams[1].x;
  43. float3 c = color * (gTonemapParams[0].x * color + gTonemapParams[0].y);
  44. float d = gTonemapParams[0].w * gTonemapParams[1].y;
  45. return (a + b)/(c + d) - gTonemapParams[1].x / gTonemapParams[1].y;
  46. }
  47. /**
  48. * Applies filmic curve tonemapping to the provided color.
  49. *
  50. * @param linearColor Linear color in ACEScg color space.
  51. * @return Tonemapped color in ACEScg color space.
  52. */
  53. float3 FilmicTonemapping(float3 color)
  54. {
  55. return FilmicCurve(color) / FilmicCurve(gTonemapParams[1].z);
  56. }
  57. /**
  58. * Applies color grading to the provided color.
  59. *
  60. * @param linearColor Linear color in ACEScg color space.
  61. * @return Graded color in ACEScg color space.
  62. */
  63. float3 ColorGrading(float3 color)
  64. {
  65. const float3 RGBToY = float3(0.2722287168f, 0.6740817658f, 0.0536895174f);
  66. float luminance = dot(color, RGBToY);
  67. color = max(0, lerp(luminance.xxx, color, gSaturation));
  68. color = pow(color * (1.0f / 0.18f), gContrast) * 0.18f;
  69. color = color * gGain + gOffset;
  70. return color;
  71. }
  72. float4 main(GStoFS input) : SV_Target0
  73. {
  74. // Constants
  75. const float3x3 sRGBToACES2065Matrix = mul(XYZToACES2065Matrix, mul(D65ToD60Matrix, sRGBToXYZMatrix));
  76. const float3x3 sRGBToACEScgMatrix = mul(XYZToACEScgMatrix, mul(D65ToD60Matrix, sRGBToXYZMatrix));
  77. const float3x3 ACEScgTosRGBMatrix = mul(XYZTosRGBMatrix, mul(D60ToD65Matrix, ACEScgToXYZMatrix));
  78. // By default pixel centers will be sampled, but we want to encode the entire range, so
  79. // offset the sampling by half a pixel, and extend the entire range by one pixel.
  80. float2 uv = input.uv0 - (0.5f / LUT_SIZE);
  81. float3 logColor = float3(uv * LUT_SIZE / (float)(LUT_SIZE - 1), input.layerIdx / (float)(LUT_SIZE - 1));
  82. float3 linearColor = LogToLinearColor(logColor);
  83. linearColor = WhiteBalance(linearColor);
  84. linearColor = mul(sRGBToACEScgMatrix, linearColor);
  85. linearColor = ColorGrading(linearColor);
  86. // Note: Improve this so it's closer to the ACES curve?
  87. linearColor = FilmicTonemapping(linearColor);
  88. // TODO - Does the white point provided in filmic curve conflict with the white balancing?
  89. linearColor = mul(ACEScgTosRGBMatrix, linearColor);
  90. // Transform to gamma space
  91. float3 gammaColor = pow(linearColor, gGammaAdjustment); // User adjustment, usually 1.0f
  92. if(gGammaCorrectionType == 0)
  93. gammaColor = LinearToGammasRGB(gammaColor);
  94. else if(gGammaCorrectionType == 1)
  95. gammaColor = LinearToGammaRec709(gammaColor);
  96. else
  97. gammaColor = pow(gammaColor, 1.0f/2.2f);
  98. // TODO - Divide by 1.05f here and then re-apply it when decoding from the texture?
  99. return float4(gammaColor, 0.0f);
  100. }
  101. };
  102. };
  103. };
  104. Technique
  105. : inherits("VolumeRenderBase")
  106. : inherits("PPTonemapCommon")
  107. : inherits("PPWhiteBalance") =
  108. {
  109. Language = "GLSL";
  110. Pass =
  111. {
  112. Fragment =
  113. {
  114. // TODO
  115. };
  116. };
  117. };