3
0

OutputTransform.azsl 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <viewsrg.srgi>
  9. #include <Atom/Features/PostProcessing/FullscreenPixelInfo.azsli>
  10. #include <Atom/Features/PostProcessing/FullscreenVertex.azsli>
  11. #include <Atom/Features/PostProcessing/PostProcessUtil.azsli>
  12. #include <Atom/Features/PostProcessing/Aces.azsli>
  13. ShaderResourceGroup PassSrg : SRG_PerPass_WithFallback
  14. {
  15. Texture2D<float4> m_framebuffer;
  16. Sampler LinearSampler
  17. {
  18. MinFilter = Linear;
  19. MagFilter = Linear;
  20. MipFilter = Linear;
  21. AddressU = Clamp;
  22. AddressV = Clamp;
  23. AddressW = Clamp;
  24. };
  25. // Reference white and black luminance values
  26. float2 m_cinemaLimits;
  27. }
  28. // Option shader variable to select tone mapper feature.
  29. option enum class ToneMapperType {None, Reinhard} o_tonemapperType = ToneMapperType::None;
  30. // Option shader variable to select transfer function.
  31. option enum class TransferFunctionType {None, Gamma22, PerceptualQuantizer} o_transferFunctionType = TransferFunctionType::None;
  32. // Simple reinhard tone mapping algorithm based on below paper.
  33. // http://www.cmap.polytechnique.fr/~peyre/cours/x2005signal/hdr_photographic.pdf
  34. float3 TonemapReinhard(const float3 inputColor)
  35. {
  36. return inputColor / (1.0 + inputColor);
  37. }
  38. float3 NormalizedToCinemaLimits(const float3 inputColor)
  39. {
  40. float3 linearColor;
  41. // Scale from normalized range to the proper range
  42. linearColor.r = LinearCVToY(inputColor.r, PassSrg::m_cinemaLimits.y, PassSrg::m_cinemaLimits.x);
  43. linearColor.g = LinearCVToY(inputColor.g, PassSrg::m_cinemaLimits.y, PassSrg::m_cinemaLimits.x);
  44. linearColor.b = LinearCVToY(inputColor.b, PassSrg::m_cinemaLimits.y, PassSrg::m_cinemaLimits.x);
  45. linearColor = max(linearColor, 0.);
  46. return linearColor;
  47. }
  48. PSOutput MainPS(VSOutput IN)
  49. {
  50. PSOutput OUT;
  51. // Fetch the pixel color from the input texture
  52. float3 color = PassSrg::m_framebuffer.Sample(PassSrg::LinearSampler, IN.m_texCoord).rgb;
  53. // Applying tone mapper.
  54. switch (o_tonemapperType)
  55. {
  56. case ToneMapperType::Reinhard:
  57. color = TonemapReinhard(color);
  58. break;
  59. default:
  60. break;
  61. }
  62. switch (o_transferFunctionType)
  63. {
  64. case TransferFunctionType::Gamma22:
  65. color = pow(color, 1.0 / 2.2);
  66. break;
  67. case TransferFunctionType::PerceptualQuantizer:
  68. if (o_tonemapperType == ToneMapperType::Reinhard)
  69. {
  70. color = NormalizedToCinemaLimits(color);
  71. }
  72. // Encode with PQ transfer function
  73. color = PerceptualQuantizerRevF3(color);
  74. break;
  75. default:
  76. break;
  77. }
  78. OUT.m_color.rgb = color;
  79. OUT.m_color.w = 1;
  80. return OUT;
  81. }