Last active
December 17, 2020 06:03
-
-
Save KelSolaar/1213139203911a72fef531c32c3d4ec2 to your computer and use it in GitHub Desktop.
Global Tonemapping Operator - Lottes (2016)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://github.com/KhronosGroup/glTF-Compressonator/blob/master/Compressonator/Applications/_Plugins/C3DModel_viewers/glTF_DX12_EX/DX12Util/shaders/Tonemapping.hlsl | |
kernel GlobalTonemappingOperator_Lottes2016 : ImageComputationKernel<ePixelWise> | |
{ | |
Image<eRead, eAccessPoint, eEdgeClamped> src; | |
Image<eWrite> dst; | |
param: | |
float hdrMax; | |
float contrast; | |
float shoulder; | |
float midIn; | |
float midOut; | |
void define() { | |
defineParam(hdrMax, "hdrMax", 16.0f); | |
defineParam(contrast, "contrast", 2.0f); | |
defineParam(shoulder, "shoulder", 1.0f); | |
defineParam(midIn, "midIn", 0.18f); | |
defineParam(midOut, "midOut", 0.18f); | |
} | |
void init() { | |
} | |
float ColToneB(float hdrMax, float contrast, float shoulder, float midIn, float midOut) | |
{ | |
return | |
-((-pow(midIn, contrast) + (midOut*(pow(hdrMax, contrast*shoulder)*pow(midIn, contrast) - | |
pow(hdrMax, contrast)*pow(midIn, contrast*shoulder)*midOut)) / | |
(pow(hdrMax, contrast*shoulder)*midOut - pow(midIn, contrast*shoulder)*midOut)) / | |
(pow(midIn, contrast*shoulder)*midOut)); | |
} | |
// General tonemapping operator, build 'c' term. | |
float ColToneC(float hdrMax, float contrast, float shoulder, float midIn, float midOut) | |
{ | |
return (pow(hdrMax, contrast*shoulder)*pow(midIn, contrast) - pow(hdrMax, contrast)*pow(midIn, contrast*shoulder)*midOut) / | |
(pow(hdrMax, contrast*shoulder)*midOut - pow(midIn, contrast*shoulder)*midOut); | |
} | |
// General tonemapping operator, p := {contrast,shoulder,b,c}. | |
float ColTone(float x, float4 p) | |
{ | |
float z = pow(x, p.x); | |
return z / (pow(z, p.y)*p.z + p.w); | |
} | |
float3 lerp(float3 a, float3 b, float c) { | |
return (1 - c) * a + c * b; | |
} | |
float3 GlobalTonemappingOperator(float3 color) | |
{ | |
float b = ColToneB(hdrMax, contrast, shoulder, midIn, midOut); | |
float c = ColToneC(hdrMax, contrast, shoulder, midIn, midOut); | |
float peak = max(color.x, max(color.y, color.z)); | |
float3 ratio = color / peak; | |
peak = ColTone(peak, float4(contrast, shoulder, b, c) ); | |
// then process ratio | |
// probably want send these pre-computed (so send over saturation/crossSaturation as a constant) | |
float crosstalk = 4.0; // controls amount of channel crosstalk | |
float saturation = contrast; // full tonal range saturation control | |
float crossSaturation = contrast*16.0; // crosstalk saturation | |
float white = 1.0; | |
// wrap crosstalk in transform | |
float saturationCrossSaturation = saturation / crossSaturation; | |
ratio = pow(fabs(ratio), float3(saturationCrossSaturation, saturationCrossSaturation, saturationCrossSaturation)); | |
ratio = lerp(ratio, float3(white, white, white), pow(peak, crosstalk)); | |
ratio = pow(fabs(ratio), float3(crossSaturation, crossSaturation, crossSaturation)); | |
// then apply ratio to peak | |
color = peak * ratio; | |
return color; | |
} | |
void process() { | |
// Read the input image | |
SampleType(src) input = src(); | |
// Isolate the RGB components | |
float3 srcPixel(input.x, input.y, input.z); | |
float3 tonemappedPixel = GlobalTonemappingOperator(srcPixel); | |
// Write the result to the output image | |
dst() = float4(tonemappedPixel.x, tonemappedPixel.y, tonemappedPixel.z, input.w); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment