Lut2DBaker.shader 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. Shader "Hidden/PostProcessing/Lut2DBaker"
  2. {
  3. HLSLINCLUDE
  4. #pragma target 3.0
  5. #include "../StdLib.hlsl"
  6. #include "../Colors.hlsl"
  7. #include "../ACES.hlsl"
  8. TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
  9. float4 _Lut2D_Params;
  10. float4 _UserLut2D_Params;
  11. float3 _ColorBalance;
  12. float3 _ColorFilter;
  13. float3 _HueSatCon;
  14. float _Brightness; // LDR only
  15. float3 _ChannelMixerRed;
  16. float3 _ChannelMixerGreen;
  17. float3 _ChannelMixerBlue;
  18. float3 _Lift;
  19. float3 _InvGamma;
  20. float3 _Gain;
  21. TEXTURE2D_SAMPLER2D(_Curves, sampler_Curves);
  22. float4 _CustomToneCurve;
  23. float4 _ToeSegmentA;
  24. float4 _ToeSegmentB;
  25. float4 _MidSegmentA;
  26. float4 _MidSegmentB;
  27. float4 _ShoSegmentA;
  28. float4 _ShoSegmentB;
  29. float3 ApplyCommonGradingSteps(float3 colorLinear)
  30. {
  31. colorLinear = WhiteBalance(colorLinear, _ColorBalance);
  32. colorLinear *= _ColorFilter;
  33. colorLinear = ChannelMixer(colorLinear, _ChannelMixerRed, _ChannelMixerGreen, _ChannelMixerBlue);
  34. colorLinear = LiftGammaGainHDR(colorLinear, _Lift, _InvGamma, _Gain);
  35. // Do NOT feed negative values to RgbToHsv or they'll wrap around
  36. colorLinear = max((float3)0.0, colorLinear);
  37. float3 hsv = RgbToHsv(colorLinear);
  38. // Hue Vs Sat
  39. float satMult;
  40. satMult = saturate(SAMPLE_TEXTURE2D_LOD(_Curves, sampler_Curves, float2(hsv.x, 0.25), 0).y) * 2.0;
  41. // Sat Vs Sat
  42. satMult *= saturate(SAMPLE_TEXTURE2D_LOD(_Curves, sampler_Curves, float2(hsv.y, 0.25), 0).z) * 2.0;
  43. // Lum Vs Sat
  44. satMult *= saturate(SAMPLE_TEXTURE2D_LOD(_Curves, sampler_Curves, float2(Luminance(colorLinear), 0.25), 0).w) * 2.0;
  45. // Hue Vs Hue
  46. float hue = hsv.x + _HueSatCon.x;
  47. float offset = saturate(SAMPLE_TEXTURE2D_LOD(_Curves, sampler_Curves, float2(hue, 0.25), 0).x) - 0.5;
  48. hue += offset;
  49. hsv.x = RotateHue(hue, 0.0, 1.0);
  50. colorLinear = HsvToRgb(hsv);
  51. colorLinear = Saturation(colorLinear, _HueSatCon.y * satMult);
  52. return colorLinear;
  53. }
  54. //
  55. // LDR Grading process
  56. //
  57. float3 ColorGradeLDR(float3 colorLinear)
  58. {
  59. // Brightness is a simple linear multiplier. Works better in LDR than using e.v.
  60. colorLinear *= _Brightness;
  61. // Contrast is done in linear, switching to log for that in LDR is pointless and doesn't
  62. // feel as good to tweak
  63. const float kMidGrey = pow(0.5, 2.2);
  64. colorLinear = Contrast(colorLinear, kMidGrey, _HueSatCon.z);
  65. colorLinear = ApplyCommonGradingSteps(colorLinear);
  66. // YRGB only works in LDR for now as we don't do any curve range remapping
  67. colorLinear = YrgbCurve(saturate(colorLinear), TEXTURE2D_PARAM(_Curves, sampler_Curves));
  68. return saturate(colorLinear);
  69. }
  70. float4 FragLDRFromScratch(VaryingsDefault i) : SV_Target
  71. {
  72. float3 colorLinear = GetLutStripValue(i.texcoordStereo, _Lut2D_Params);
  73. float3 graded = ColorGradeLDR(colorLinear);
  74. return float4(graded, 1.0);
  75. }
  76. float4 FragLDR(VaryingsDefault i) : SV_Target
  77. {
  78. // Note: user luts may not have the same size as the internal one
  79. float3 neutralColorLinear = GetLutStripValue(i.texcoordStereo, _Lut2D_Params);
  80. float3 lookup = ApplyLut2D(TEXTURE2D_PARAM(_MainTex, sampler_MainTex), neutralColorLinear, _UserLut2D_Params.xyz);
  81. float3 colorLinear = lerp(neutralColorLinear, lookup, _UserLut2D_Params.w);
  82. float3 graded = ColorGradeLDR(colorLinear);
  83. return float4(graded, 1.0);
  84. }
  85. //
  86. // HDR Grading process
  87. //
  88. float3 LogGradeHDR(float3 colorLog)
  89. {
  90. // HDR contrast feels a lot more natural when done in log rather than doing it in linear
  91. colorLog = Contrast(colorLog, ACEScc_MIDGRAY, _HueSatCon.z);
  92. return colorLog;
  93. }
  94. float3 LinearGradeHDR(float3 colorLinear)
  95. {
  96. colorLinear = ApplyCommonGradingSteps(colorLinear);
  97. return colorLinear;
  98. }
  99. float3 ColorGradeHDR(float3 colorLutSpace)
  100. {
  101. #if TONEMAPPING_ACES
  102. {
  103. float3 colorLinear = LUT_SPACE_DECODE(colorLutSpace);
  104. float3 aces = unity_to_ACES(colorLinear);
  105. // ACEScc (log) space
  106. float3 acescc = ACES_to_ACEScc(aces);
  107. acescc = LogGradeHDR(acescc);
  108. aces = ACEScc_to_ACES(acescc);
  109. // ACEScg (linear) space
  110. float3 acescg = ACES_to_ACEScg(aces);
  111. acescg = LinearGradeHDR(acescg);
  112. // Tonemap ODT(RRT(aces))
  113. aces = ACEScg_to_ACES(acescg);
  114. colorLinear = AcesTonemap(aces);
  115. return colorLinear;
  116. }
  117. #else
  118. {
  119. // colorLutSpace is already in log space
  120. colorLutSpace = LogGradeHDR(colorLutSpace);
  121. // Switch back to linear
  122. float3 colorLinear = LUT_SPACE_DECODE(colorLutSpace);
  123. colorLinear = LinearGradeHDR(colorLinear);
  124. colorLinear = max(0.0, colorLinear);
  125. // Tonemap
  126. #if TONEMAPPING_NEUTRAL
  127. {
  128. colorLinear = NeutralTonemap(colorLinear);
  129. }
  130. #elif TONEMAPPING_CUSTOM
  131. {
  132. colorLinear = CustomTonemap(
  133. colorLinear, _CustomToneCurve.xyz,
  134. _ToeSegmentA, _ToeSegmentB.xy,
  135. _MidSegmentA, _MidSegmentB.xy,
  136. _ShoSegmentA, _ShoSegmentB.xy
  137. );
  138. }
  139. #endif
  140. return colorLinear;
  141. }
  142. #endif
  143. }
  144. float4 FragHDR(VaryingsDefault i) : SV_Target
  145. {
  146. float3 colorLutSpace = GetLutStripValue(i.texcoord, _Lut2D_Params);
  147. float3 graded = ColorGradeHDR(colorLutSpace);
  148. return float4(max(graded, 0.0), 1.0);
  149. }
  150. ENDHLSL
  151. SubShader
  152. {
  153. Cull Off ZWrite Off ZTest Always
  154. Pass
  155. {
  156. HLSLPROGRAM
  157. #pragma vertex VertDefault
  158. #pragma fragment FragLDRFromScratch
  159. ENDHLSL
  160. }
  161. Pass
  162. {
  163. HLSLPROGRAM
  164. #pragma vertex VertDefault
  165. #pragma fragment FragLDR
  166. ENDHLSL
  167. }
  168. Pass
  169. {
  170. HLSLPROGRAM
  171. #pragma vertex VertDefault
  172. #pragma fragment FragHDR
  173. #pragma multi_compile __ TONEMAPPING_ACES TONEMAPPING_NEUTRAL TONEMAPPING_CUSTOM
  174. ENDHLSL
  175. }
  176. }
  177. }