LutBuilderLdr.shader 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. Shader "Hidden/Universal Render Pipeline/LutBuilderLdr"
  2. {
  3. HLSLINCLUDE
  4. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
  5. #include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
  6. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
  7. float4 _Lut_Params; // x: lut_height, y: 0.5 / lut_width, z: 0.5 / lut_height, w: lut_height / lut_height - 1
  8. float4 _ColorBalance; // xyz: LMS coeffs, w: unused
  9. half4 _ColorFilter; // xyz: color, w: unused
  10. half4 _ChannelMixerRed; // xyz: rgb coeffs, w: unused
  11. half4 _ChannelMixerGreen; // xyz: rgb coeffs, w: unused
  12. half4 _ChannelMixerBlue; // xyz: rgb coeffs, w: unused
  13. float4 _HueSatCon; // x: hue shift, y: saturation, z: contrast, w: unused
  14. float4 _Lift; // xyz: color, w: unused
  15. float4 _Gamma; // xyz: color, w: unused
  16. float4 _Gain; // xyz: color, w: unused
  17. float4 _Shadows; // xyz: color, w: unused
  18. float4 _Midtones; // xyz: color, w: unused
  19. float4 _Highlights; // xyz: color, w: unused
  20. float4 _ShaHiLimits; // xy: shadows min/max, zw: highlight min/max
  21. half4 _SplitShadows; // xyz: color, w: balance
  22. half4 _SplitHighlights; // xyz: color, w: unused
  23. TEXTURE2D(_CurveMaster);
  24. TEXTURE2D(_CurveRed);
  25. TEXTURE2D(_CurveGreen);
  26. TEXTURE2D(_CurveBlue);
  27. TEXTURE2D(_CurveHueVsHue);
  28. TEXTURE2D(_CurveHueVsSat);
  29. TEXTURE2D(_CurveSatVsSat);
  30. TEXTURE2D(_CurveLumVsSat);
  31. half EvaluateCurve(TEXTURE2D(curve), float t)
  32. {
  33. half x = SAMPLE_TEXTURE2D(curve, sampler_LinearClamp, float2(t, 0.0)).x;
  34. return saturate(x);
  35. }
  36. half4 Frag(Varyings input) : SV_Target
  37. {
  38. float3 colorLinear = GetLutStripValue(input.uv, _Lut_Params);
  39. // White balance in LMS space
  40. float3 colorLMS = LinearToLMS(colorLinear);
  41. colorLMS *= _ColorBalance.xyz;
  42. colorLinear = LMSToLinear(colorLMS);
  43. // Do contrast in log after white balance
  44. float3 colorLog = LinearToLogC(colorLinear);
  45. colorLog = (colorLog - ACEScc_MIDGRAY) * _HueSatCon.z + ACEScc_MIDGRAY;
  46. colorLinear = LogCToLinear(colorLog);
  47. // Color filter is just an unclipped multiplier
  48. colorLinear *= _ColorFilter.xyz;
  49. // Do NOT feed negative values to the following color ops
  50. colorLinear = max(0.0, colorLinear);
  51. // Split toning
  52. // As counter-intuitive as it is, to make split-toning work the same way it does in Adobe
  53. // products we have to do all the maths in gamma-space...
  54. float balance = _SplitShadows.w;
  55. float3 colorGamma = PositivePow(colorLinear, 1.0 / 2.2);
  56. float luma = saturate(GetLuminance(saturate(colorGamma)) + balance);
  57. float3 splitShadows = lerp((0.5).xxx, _SplitShadows.xyz, 1.0 - luma);
  58. float3 splitHighlights = lerp((0.5).xxx, _SplitHighlights.xyz, luma);
  59. colorGamma = SoftLight(colorGamma, splitShadows);
  60. colorGamma = SoftLight(colorGamma, splitHighlights);
  61. colorLinear = PositivePow(colorGamma, 2.2);
  62. // Channel mixing (Adobe style)
  63. colorLinear = float3(
  64. dot(colorLinear, _ChannelMixerRed.xyz),
  65. dot(colorLinear, _ChannelMixerGreen.xyz),
  66. dot(colorLinear, _ChannelMixerBlue.xyz)
  67. );
  68. // Shadows, midtones, highlights
  69. luma = GetLuminance(colorLinear);
  70. float shadowsFactor = 1.0 - smoothstep(_ShaHiLimits.x, _ShaHiLimits.y, luma);
  71. float highlightsFactor = smoothstep(_ShaHiLimits.z, _ShaHiLimits.w, luma);
  72. float midtonesFactor = 1.0 - shadowsFactor - highlightsFactor;
  73. colorLinear = colorLinear * _Shadows.xyz * shadowsFactor
  74. + colorLinear * _Midtones.xyz * midtonesFactor
  75. + colorLinear * _Highlights.xyz * highlightsFactor;
  76. // Lift, gamma, gain
  77. colorLinear = colorLinear * _Gain.xyz + _Lift.xyz;
  78. colorLinear = sign(colorLinear) * pow(abs(colorLinear), _Gamma.xyz);
  79. // HSV operations
  80. float satMult;
  81. float3 hsv = RgbToHsv(colorLinear);
  82. {
  83. // Hue Vs Sat
  84. satMult = EvaluateCurve(_CurveHueVsSat, hsv.x) * 2.0;
  85. // Sat Vs Sat
  86. satMult *= EvaluateCurve(_CurveSatVsSat, hsv.y) * 2.0;
  87. // Lum Vs Sat
  88. satMult *= EvaluateCurve(_CurveLumVsSat, Luminance(colorLinear)) * 2.0;
  89. // Hue Shift & Hue Vs Hue
  90. float hue = hsv.x + _HueSatCon.x;
  91. float offset = EvaluateCurve(_CurveHueVsHue, hue) - 0.5;
  92. hue += offset;
  93. hsv.x = RotateHue(hue, 0.0, 1.0);
  94. }
  95. colorLinear = HsvToRgb(hsv);
  96. // Global saturation
  97. luma = GetLuminance(colorLinear);
  98. colorLinear = luma.xxx + (_HueSatCon.yyy * satMult) * (colorLinear - luma.xxx);
  99. // YRGB curves
  100. {
  101. const float kHalfPixel = (1.0 / 128.0) / 2.0;
  102. float3 c = colorLinear;
  103. // Y (master)
  104. c += kHalfPixel.xxx;
  105. float mr = EvaluateCurve(_CurveMaster, c.r);
  106. float mg = EvaluateCurve(_CurveMaster, c.g);
  107. float mb = EvaluateCurve(_CurveMaster, c.b);
  108. c = float3(mr, mg, mb);
  109. // RGB
  110. c += kHalfPixel.xxx;
  111. float r = EvaluateCurve(_CurveRed, c.r);
  112. float g = EvaluateCurve(_CurveGreen, c.g);
  113. float b = EvaluateCurve(_CurveBlue, c.b);
  114. colorLinear = float3(r, g, b);
  115. }
  116. return half4(saturate(colorLinear), 1.0);
  117. }
  118. ENDHLSL
  119. SubShader
  120. {
  121. Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
  122. LOD 100
  123. ZTest Always ZWrite Off Cull Off
  124. Pass
  125. {
  126. Name "LutBuilderLdr"
  127. HLSLPROGRAM
  128. #pragma vertex Vert
  129. #pragma fragment Frag
  130. ENDHLSL
  131. }
  132. }
  133. }