Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
filmic Tonemapperを打ち消したい
float FilmSlope = 0.88;
float FilmToe = 0.55;
float FilmShoulder = 0.26;
float FilmBlackClip = 0;
float FilmWhiteClip = 0.04;
const float3x3 AP1_2_AP0 = mul( XYZ_2_AP0_MAT, AP1_2_XYZ_MAT );
const float3x3 AP0_2_AP1 = mul( XYZ_2_AP1_MAT, AP0_2_XYZ_MAT );
const float3x3 sRGB_2_AP1 = mul( XYZ_2_AP1_MAT, mul( D65_2_D60_CAT, sRGB_2_XYZ_MAT ) );
const float3x3 AP1_2_sRGB = mul( XYZ_2_sRGB_MAT, mul( D60_2_D65_CAT, AP1_2_XYZ_MAT ) );
// Use ACEScg primaries as working space
half3 WorkingColor = mul( sRGB_2_AP1, saturate(ToneColor) );
//WorkingColor = max( 0, WorkingColor );
//half3 WorkingColor = ToneColor;
// Post desaturate
const float ODT_SAT_FACTOR = 0.93;
WorkingColor = max(0, lerp( dot( WorkingColor, AP1_RGB2Y ), WorkingColor, rcp(ODT_SAT_FACTOR) ));
const half ToeScale = 1 + FilmBlackClip - FilmToe;
const half ShoulderScale = 1 + FilmWhiteClip - FilmShoulder;
const float InMatch = 0.18;
const float OutMatch = 0.18;
float ToeMatch;
if( FilmToe > 0.8 )
{
// 0.18 will be on straight segment
ToeMatch = ( 1 - FilmToe - OutMatch ) / FilmSlope + log10( InMatch );
}
else
{
// 0.18 will be on toe segment
// Solve for ToeMatch such that input of InMatch gives output of OutMatch.
const float bt = ( OutMatch + FilmBlackClip ) / ToeScale - 1;
ToeMatch = log10( InMatch ) - 0.5 * log( (1+bt)/(1-bt) ) * (ToeScale / FilmSlope);
}
float StraightMatch = ( 1 - FilmToe ) / FilmSlope - ToeMatch;
float ShoulderMatch = FilmShoulder / FilmSlope - StraightMatch;
half3 LogColor = WorkingColor == 0.0 ? 0.0 : log10( WorkingColor);
if(WorkingColor.r >= (FilmWhiteClip + 1.0)){ WorkingColor.r = FilmWhiteClip + 1 - 0.01;}
if(WorkingColor.g >= (FilmWhiteClip + 1.0)){ WorkingColor.g = FilmWhiteClip + 1 - 0.01;}
if(WorkingColor.b >= (FilmWhiteClip + 1.0)){ WorkingColor.b = FilmWhiteClip + 1 - 0.01;}
half3 StraightColorInv = WorkingColor == 0.0 ? 0.0 : pow(10, (WorkingColor - FilmSlope * StraightMatch - OutMatch) / FilmSlope);
half3 ToeColorInv = WorkingColor == 1.0 ? 1.0 : pow(10.0, - (ToeScale) / (2.0 * FilmSlope)
* log( (2.0 * ToeScale) / (WorkingColor + FilmBlackClip) - 1.0)
+ ToeMatch);
half3 ShoulderColorInv = WorkingColor == 0.0 ? 0.0 : pow(10.0, (ShoulderScale) / (2.0 * FilmSlope)
* log( (2.0 * ShoulderScale) / ((FilmWhiteClip + 1.0) - WorkingColor) - 1.0)
+ ShoulderMatch);
ToeColorInv = LogColor == 0.0 || LogColor < ToeMatch ? ToeColorInv : StraightColorInv;
ShoulderColorInv = LogColor == 1.0 || LogColor > ShoulderMatch ? ShoulderColorInv : StraightColorInv;
half3 t = saturate( ( LogColor - ToeMatch ) / ( ShoulderMatch - ToeMatch ) );
t = ShoulderMatch < ToeMatch ? t : 1 - t;
t = (3-2*t)*t*t;
half3 LinearColor = lerp(ShoulderColorInv, ToeColorInv, t );
// Pre desaturate
const half RRT_SAT_FACTOR = 0.96;
LinearColor = lerp( dot( LinearColor, AP1_RGB2Y ), LinearColor, rcp(RRT_SAT_FACTOR) );
//rrt
float3 ColorAP0 = mul( AP1_2_AP0, LinearColor );
//ColorAP0 = max( 0, ColorAP0 );
//float3 ColorAP0 = LinearColor;
// --- Red modifier --- //
const float RRT_RED_SCALE = 0.82;
const float RRT_RED_PIVOT = 0.03;
const float RRT_RED_HUE = 0;
const float RRT_RED_WIDTH = 135;
float hue = rgb_2_hue(ColorAP0);
float centeredHue = center_hue( hue, RRT_RED_HUE);
float hueWeight = Square( smoothstep( 0, 1, 1 - abs( 2 * centeredHue / RRT_RED_WIDTH ) ) );
float minChan;
if (centeredHue < 0) {
// min_f3(ColorAP0) = ColorAP0.g (i.e. magenta-red)
minChan = ColorAP0.g;
} else { // min_f3(ColorAP0) = ColorAP0.b (i.e. yellow-red)
minChan = ColorAP0.b;
}
float a = hueWeight * (1. - RRT_RED_SCALE) - 1.;
float b = ColorAP0.r - hueWeight * (RRT_RED_PIVOT + minChan) * (1. - RRT_RED_SCALE);
float c = hueWeight * RRT_RED_PIVOT * minChan * (1. - RRT_RED_SCALE);
//2次方程式の解の公式
ColorAP0.r = -b / (2.0 * a) > 0 ? (-b - sqrt( b * b - 4.0 * a * c)) / ( 2.0 * a) : (-b + sqrt( b * b - 4.0 * a * c)) / ( 2.0 * a);
// "Glow" module constants
const float RRT_GLOW_GAIN = 0.05;
const float RRT_GLOW_MID = 0.08;
// --- Glow module --- //
float saturation = rgb_2_saturation(ColorAP0);
float ycOut = rgb_2_yc(ColorAP0);
float s = sigmoid_shaper( (saturation - 0.4) / 0.2);
float reducedGlow = 1. + glow_inv( ycOut, RRT_GLOW_GAIN * s, RRT_GLOW_MID);
ColorAP0 = reducedGlow * ColorAP0;
//return ColorAP0;
float3 ColorAP1 = mul( AP0_2_AP1, ColorAP0 );
return mul( AP1_2_sRGB, ColorAP1 );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment