165 lines
6.4 KiB
Plaintext
165 lines
6.4 KiB
Plaintext
Shader "Hidden/Universal Render Pipeline/LutBuilderLdr"
|
|
{
|
|
HLSLINCLUDE
|
|
|
|
#pragma exclude_renderers gles
|
|
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
|
|
|
|
float4 _Lut_Params; // x: lut_height, y: 0.5 / lut_width, z: 0.5 / lut_height, w: lut_height / lut_height - 1
|
|
float4 _ColorBalance; // xyz: LMS coeffs, w: unused
|
|
half4 _ColorFilter; // xyz: color, w: unused
|
|
half4 _ChannelMixerRed; // xyz: rgb coeffs, w: unused
|
|
half4 _ChannelMixerGreen; // xyz: rgb coeffs, w: unused
|
|
half4 _ChannelMixerBlue; // xyz: rgb coeffs, w: unused
|
|
float4 _HueSatCon; // x: hue shift, y: saturation, z: contrast, w: unused
|
|
float4 _Lift; // xyz: color, w: unused
|
|
float4 _Gamma; // xyz: color, w: unused
|
|
float4 _Gain; // xyz: color, w: unused
|
|
float4 _Shadows; // xyz: color, w: unused
|
|
float4 _Midtones; // xyz: color, w: unused
|
|
float4 _Highlights; // xyz: color, w: unused
|
|
float4 _ShaHiLimits; // xy: shadows min/max, zw: highlight min/max
|
|
half4 _SplitShadows; // xyz: color, w: balance
|
|
half4 _SplitHighlights; // xyz: color, w: unused
|
|
|
|
TEXTURE2D(_CurveMaster);
|
|
TEXTURE2D(_CurveRed);
|
|
TEXTURE2D(_CurveGreen);
|
|
TEXTURE2D(_CurveBlue);
|
|
|
|
TEXTURE2D(_CurveHueVsHue);
|
|
TEXTURE2D(_CurveHueVsSat);
|
|
TEXTURE2D(_CurveSatVsSat);
|
|
TEXTURE2D(_CurveLumVsSat);
|
|
|
|
half EvaluateCurve(TEXTURE2D(curve), float t)
|
|
{
|
|
half x = SAMPLE_TEXTURE2D(curve, sampler_LinearClamp, float2(t, 0.0)).x;
|
|
return saturate(x);
|
|
}
|
|
|
|
half4 Frag(Varyings input) : SV_Target
|
|
{
|
|
float3 colorLinear = GetLutStripValue(input.uv, _Lut_Params);
|
|
|
|
// White balance in LMS space
|
|
float3 colorLMS = LinearToLMS(colorLinear);
|
|
colorLMS *= _ColorBalance.xyz;
|
|
colorLinear = LMSToLinear(colorLMS);
|
|
|
|
// Do contrast in log after white balance
|
|
float3 colorLog = LinearToLogC(colorLinear);
|
|
colorLog = (colorLog - ACEScc_MIDGRAY) * _HueSatCon.z + ACEScc_MIDGRAY;
|
|
colorLinear = LogCToLinear(colorLog);
|
|
|
|
// Color filter is just an unclipped multiplier
|
|
colorLinear *= _ColorFilter.xyz;
|
|
|
|
// Do NOT feed negative values to the following color ops
|
|
colorLinear = max(0.0, colorLinear);
|
|
|
|
// Split toning
|
|
// As counter-intuitive as it is, to make split-toning work the same way it does in Adobe
|
|
// products we have to do all the maths in gamma-space...
|
|
float balance = _SplitShadows.w;
|
|
float3 colorGamma = PositivePow(colorLinear, 1.0 / 2.2);
|
|
|
|
float luma = saturate(GetLuminance(saturate(colorGamma)) + balance);
|
|
float3 splitShadows = lerp((0.5).xxx, _SplitShadows.xyz, 1.0 - luma);
|
|
float3 splitHighlights = lerp((0.5).xxx, _SplitHighlights.xyz, luma);
|
|
colorGamma = SoftLight(colorGamma, splitShadows);
|
|
colorGamma = SoftLight(colorGamma, splitHighlights);
|
|
|
|
colorLinear = PositivePow(colorGamma, 2.2);
|
|
|
|
// Channel mixing (Adobe style)
|
|
colorLinear = float3(
|
|
dot(colorLinear, _ChannelMixerRed.xyz),
|
|
dot(colorLinear, _ChannelMixerGreen.xyz),
|
|
dot(colorLinear, _ChannelMixerBlue.xyz)
|
|
);
|
|
|
|
// Shadows, midtones, highlights
|
|
luma = GetLuminance(colorLinear);
|
|
float shadowsFactor = 1.0 - smoothstep(_ShaHiLimits.x, _ShaHiLimits.y, luma);
|
|
float highlightsFactor = smoothstep(_ShaHiLimits.z, _ShaHiLimits.w, luma);
|
|
float midtonesFactor = 1.0 - shadowsFactor - highlightsFactor;
|
|
colorLinear = colorLinear * _Shadows.xyz * shadowsFactor
|
|
+ colorLinear * _Midtones.xyz * midtonesFactor
|
|
+ colorLinear * _Highlights.xyz * highlightsFactor;
|
|
|
|
// Lift, gamma, gain
|
|
colorLinear = colorLinear * _Gain.xyz + _Lift.xyz;
|
|
colorLinear = sign(colorLinear) * pow(abs(colorLinear), _Gamma.xyz);
|
|
|
|
// HSV operations
|
|
float satMult;
|
|
float3 hsv = RgbToHsv(colorLinear);
|
|
{
|
|
// Hue Vs Sat
|
|
satMult = EvaluateCurve(_CurveHueVsSat, hsv.x) * 2.0;
|
|
|
|
// Sat Vs Sat
|
|
satMult *= EvaluateCurve(_CurveSatVsSat, hsv.y) * 2.0;
|
|
|
|
// Lum Vs Sat
|
|
satMult *= EvaluateCurve(_CurveLumVsSat, Luminance(colorLinear)) * 2.0;
|
|
|
|
// Hue Shift & Hue Vs Hue
|
|
float hue = hsv.x + _HueSatCon.x;
|
|
float offset = EvaluateCurve(_CurveHueVsHue, hue) - 0.5;
|
|
hue += offset;
|
|
hsv.x = RotateHue(hue, 0.0, 1.0);
|
|
}
|
|
colorLinear = HsvToRgb(hsv);
|
|
|
|
// Global saturation
|
|
luma = GetLuminance(colorLinear);
|
|
colorLinear = luma.xxx + (_HueSatCon.yyy * satMult) * (colorLinear - luma.xxx);
|
|
|
|
// YRGB curves
|
|
{
|
|
const float kHalfPixel = (1.0 / 128.0) / 2.0;
|
|
float3 c = colorLinear;
|
|
|
|
// Y (master)
|
|
c += kHalfPixel.xxx;
|
|
float mr = EvaluateCurve(_CurveMaster, c.r);
|
|
float mg = EvaluateCurve(_CurveMaster, c.g);
|
|
float mb = EvaluateCurve(_CurveMaster, c.b);
|
|
c = float3(mr, mg, mb);
|
|
|
|
// RGB
|
|
c += kHalfPixel.xxx;
|
|
float r = EvaluateCurve(_CurveRed, c.r);
|
|
float g = EvaluateCurve(_CurveGreen, c.g);
|
|
float b = EvaluateCurve(_CurveBlue, c.b);
|
|
colorLinear = float3(r, g, b);
|
|
}
|
|
|
|
return half4(saturate(colorLinear), 1.0);
|
|
}
|
|
|
|
ENDHLSL
|
|
|
|
SubShader
|
|
{
|
|
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
|
|
LOD 100
|
|
ZTest Always ZWrite Off Cull Off
|
|
|
|
Pass
|
|
{
|
|
Name "LutBuilderLdr"
|
|
|
|
HLSLPROGRAM
|
|
#pragma vertex FullscreenVert
|
|
#pragma fragment Frag
|
|
ENDHLSL
|
|
}
|
|
}
|
|
}
|