暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

LutBuilderHdr.shader 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. Shader "Hidden/Universal Render Pipeline/LutBuilderHdr"
  2. {
  3. HLSLINCLUDE
  4. #pragma multi_compile_local _ _TONEMAP_ACES _TONEMAP_NEUTRAL
  5. #pragma multi_compile_local_fragment _ HDR_COLORSPACE_CONVERSION
  6. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
  7. #include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
  8. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ACES.hlsl"
  9. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
  10. #if defined(HDR_COLORSPACE_CONVERSION)
  11. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/HDROutput.hlsl"
  12. #endif
  13. float4 _Lut_Params; // x: lut_height, y: 0.5 / lut_width, z: 0.5 / lut_height, w: lut_height / lut_height - 1
  14. float4 _ColorBalance; // xyz: LMS coeffs, w: unused
  15. float4 _ColorFilter; // xyz: color, w: unused
  16. float4 _ChannelMixerRed; // xyz: rgb coeffs, w: unused
  17. float4 _ChannelMixerGreen; // xyz: rgb coeffs, w: unused
  18. float4 _ChannelMixerBlue; // xyz: rgb coeffs, w: unused
  19. float4 _HueSatCon; // x: hue shift, y: saturation, z: contrast, w: unused
  20. float4 _Lift; // xyz: color, w: unused
  21. float4 _Gamma; // xyz: color, w: unused
  22. float4 _Gain; // xyz: color, w: unused
  23. float4 _Shadows; // xyz: color, w: unused
  24. float4 _Midtones; // xyz: color, w: unused
  25. float4 _Highlights; // xyz: color, w: unused
  26. float4 _ShaHiLimits; // xy: shadows min/max, zw: highlight min/max
  27. float4 _SplitShadows; // xyz: color, w: balance
  28. float4 _SplitHighlights; // xyz: color, w: unused
  29. float4 _HDROutputLuminanceParams; // xy: brightness min/max, z: paper white brightness, w: 1.0 / brightness max
  30. float4 _HDROutputGradingParams; // x: eetf/range reduction mode, y: hue shift, zw: unused
  31. TEXTURE2D(_CurveMaster);
  32. TEXTURE2D(_CurveRed);
  33. TEXTURE2D(_CurveGreen);
  34. TEXTURE2D(_CurveBlue);
  35. TEXTURE2D(_CurveHueVsHue);
  36. TEXTURE2D(_CurveHueVsSat);
  37. TEXTURE2D(_CurveSatVsSat);
  38. TEXTURE2D(_CurveLumVsSat);
  39. #define MinNits _HDROutputLuminanceParams.x
  40. #define MaxNits _HDROutputLuminanceParams.y
  41. #define PaperWhite _HDROutputLuminanceParams.z
  42. #define RangeReductionMode (int)_HDROutputGradingParams.x
  43. #define HueShift _HDROutputGradingParams.y
  44. float EvaluateCurve(TEXTURE2D(curve), float t)
  45. {
  46. float x = SAMPLE_TEXTURE2D(curve, sampler_LinearClamp, float2(t, 0.0)).x;
  47. return saturate(x);
  48. }
  49. float3 RotateToColorGradeOutputSpace(float3 gradedColor)
  50. {
  51. #ifdef _TONEMAP_ACES
  52. // In ACES workflow we return graded color in ACEScg, we move to ACES (AP0) later on
  53. return gradedColor;
  54. #elif defined(HDR_COLORSPACE_CONVERSION) // HDR but not ACES workflow
  55. // If we are doing HDR we expect grading to finish at Rec2020. Any supplemental rotation is done inside the various options.
  56. return RotateRec709ToRec2020(gradedColor);
  57. #else // Nor ACES or HDR
  58. // We already graded in sRGB
  59. return gradedColor;
  60. #endif
  61. }
  62. // Note: when the ACES tonemapper is selected the grading steps will be done using ACES spaces
  63. float3 ColorGrade(float3 colorLutSpace)
  64. {
  65. // Switch back to linear
  66. float3 colorLinear = LogCToLinear(colorLutSpace);
  67. // White balance in LMS space
  68. float3 colorLMS = LinearToLMS(colorLinear);
  69. colorLMS *= _ColorBalance.xyz;
  70. colorLinear = LMSToLinear(colorLMS);
  71. // Do contrast in log after white balance
  72. #if _TONEMAP_ACES
  73. float3 colorLog = ACES_to_ACEScc(unity_to_ACES(colorLinear));
  74. #else
  75. float3 colorLog = LinearToLogC(colorLinear);
  76. #endif
  77. colorLog = (colorLog - ACEScc_MIDGRAY) * _HueSatCon.z + ACEScc_MIDGRAY;
  78. #if _TONEMAP_ACES
  79. colorLinear = ACES_to_ACEScg(ACEScc_to_ACES(colorLog));
  80. #else
  81. colorLinear = LogCToLinear(colorLog);
  82. #endif
  83. // Color filter is just an unclipped multiplier
  84. colorLinear *= _ColorFilter.xyz;
  85. // Do NOT feed negative values to the following color ops
  86. colorLinear = max(0.0, colorLinear);
  87. // Split toning
  88. // As counter-intuitive as it is, to make split-toning work the same way it does in Adobe
  89. // products we have to do all the maths in gamma-space...
  90. float balance = _SplitShadows.w;
  91. float3 colorGamma = PositivePow(colorLinear, 1.0 / 2.2);
  92. float luma = saturate(GetLuminance(saturate(colorGamma)) + balance);
  93. float3 splitShadows = lerp((0.5).xxx, _SplitShadows.xyz, 1.0 - luma);
  94. float3 splitHighlights = lerp((0.5).xxx, _SplitHighlights.xyz, luma);
  95. colorGamma = SoftLight(colorGamma, splitShadows);
  96. colorGamma = SoftLight(colorGamma, splitHighlights);
  97. colorLinear = PositivePow(colorGamma, 2.2);
  98. // Channel mixing (Adobe style)
  99. colorLinear = float3(
  100. dot(colorLinear, _ChannelMixerRed.xyz),
  101. dot(colorLinear, _ChannelMixerGreen.xyz),
  102. dot(colorLinear, _ChannelMixerBlue.xyz)
  103. );
  104. // Shadows, midtones, highlights
  105. luma = GetLuminance(colorLinear);
  106. float shadowsFactor = 1.0 - smoothstep(_ShaHiLimits.x, _ShaHiLimits.y, luma);
  107. float highlightsFactor = smoothstep(_ShaHiLimits.z, _ShaHiLimits.w, luma);
  108. float midtonesFactor = 1.0 - shadowsFactor - highlightsFactor;
  109. colorLinear = colorLinear * _Shadows.xyz * shadowsFactor
  110. + colorLinear * _Midtones.xyz * midtonesFactor
  111. + colorLinear * _Highlights.xyz * highlightsFactor;
  112. // Lift, gamma, gain
  113. colorLinear = colorLinear * _Gain.xyz + _Lift.xyz;
  114. colorLinear = sign(colorLinear) * pow(abs(colorLinear), _Gamma.xyz);
  115. // HSV operations
  116. float satMult;
  117. float3 hsv = RgbToHsv(colorLinear);
  118. {
  119. // Hue Vs Sat
  120. satMult = EvaluateCurve(_CurveHueVsSat, hsv.x) * 2.0;
  121. // Sat Vs Sat
  122. satMult *= EvaluateCurve(_CurveSatVsSat, hsv.y) * 2.0;
  123. // Lum Vs Sat
  124. satMult *= EvaluateCurve(_CurveLumVsSat, Luminance(colorLinear)) * 2.0;
  125. // Hue Shift & Hue Vs Hue
  126. float hue = hsv.x + _HueSatCon.x;
  127. float offset = EvaluateCurve(_CurveHueVsHue, hue) - 0.5;
  128. hue += offset;
  129. hsv.x = RotateHue(hue, 0.0, 1.0);
  130. }
  131. colorLinear = HsvToRgb(hsv);
  132. // Global saturation
  133. luma = GetLuminance(colorLinear);
  134. colorLinear = luma.xxx + (_HueSatCon.yyy * satMult) * (colorLinear - luma.xxx);
  135. // YRGB curves
  136. // Conceptually these need to be in range [0;1] and from an artist-workflow perspective
  137. // it's easier to deal with
  138. colorLinear = FastTonemap(colorLinear);
  139. {
  140. const float kHalfPixel = (1.0 / 128.0) / 2.0;
  141. float3 c = colorLinear;
  142. // Y (master)
  143. c += kHalfPixel.xxx;
  144. float mr = EvaluateCurve(_CurveMaster, c.r);
  145. float mg = EvaluateCurve(_CurveMaster, c.g);
  146. float mb = EvaluateCurve(_CurveMaster, c.b);
  147. c = float3(mr, mg, mb);
  148. // RGB
  149. c += kHalfPixel.xxx;
  150. float r = EvaluateCurve(_CurveRed, c.r);
  151. float g = EvaluateCurve(_CurveGreen, c.g);
  152. float b = EvaluateCurve(_CurveBlue, c.b);
  153. colorLinear = float3(r, g, b);
  154. }
  155. colorLinear = FastTonemapInvert(colorLinear);
  156. colorLinear = max(0.0, colorLinear);
  157. return RotateToColorGradeOutputSpace(colorLinear);
  158. }
  159. float3 Tonemap(float3 colorLinear)
  160. {
  161. #if _TONEMAP_NEUTRAL
  162. {
  163. colorLinear = NeutralTonemap(colorLinear);
  164. }
  165. #elif _TONEMAP_ACES
  166. {
  167. // Note: input is actually ACEScg (AP1 w/ linear encoding)
  168. float3 aces = ACEScg_to_ACES(colorLinear);
  169. colorLinear = AcesTonemap(aces);
  170. }
  171. #endif
  172. return colorLinear;
  173. }
  174. float3 ProcessColorForHDR(float3 colorLinear)
  175. {
  176. #ifdef HDR_COLORSPACE_CONVERSION
  177. #ifdef _TONEMAP_ACES
  178. float3 aces = ACEScg_to_ACES(colorLinear);
  179. return HDRMappingACES(aces.rgb, PaperWhite, MinNits, MaxNits, RangeReductionMode, true);
  180. #elif _TONEMAP_NEUTRAL
  181. return HDRMappingFromRec2020(colorLinear.rgb, PaperWhite, MinNits, MaxNits, RangeReductionMode, HueShift, true);
  182. #else
  183. // Grading finished in Rec2020, converting to the expected color space and [0, 10k] nits range
  184. return RotateRec2020ToOutputSpace(colorLinear) * PaperWhite;
  185. #endif
  186. #endif
  187. return colorLinear;
  188. }
  189. float4 FragLutBuilderHdr(Varyings input) : SV_Target
  190. {
  191. // Lut space
  192. // We use Alexa LogC (El 1000) to store the LUT as it provides a good enough range
  193. // (~58.85666) and is good enough to be stored in fp16 without losing precision in the
  194. // darks
  195. float3 colorLutSpace = GetLutStripValue(input.texcoord, _Lut_Params);
  196. // Color grade & tonemap
  197. float3 gradedColor = ColorGrade(colorLutSpace);
  198. #ifdef HDR_COLORSPACE_CONVERSION
  199. gradedColor = ProcessColorForHDR(gradedColor);
  200. #else
  201. gradedColor = Tonemap(gradedColor);
  202. #endif
  203. return float4(gradedColor, 1.0);
  204. }
  205. ENDHLSL
  206. SubShader
  207. {
  208. Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
  209. LOD 100
  210. ZTest Always ZWrite Off Cull Off
  211. Pass
  212. {
  213. Name "LutBuilderHdr"
  214. HLSLPROGRAM
  215. #pragma vertex Vert
  216. #pragma fragment FragLutBuilderHdr
  217. ENDHLSL
  218. }
  219. }
  220. }