mirror of
https://github.com/italicsjenga/slang-shaders.git
synced 2024-11-26 01:11:32 +11:00
Fixed primary transforms for wide colour gamut systems such as HDR breaking the mask and resulting in muddy colours
This commit is contained in:
parent
379eecab7d
commit
2dddb330a7
|
@ -23,6 +23,7 @@ Dont use this shader directly - use the hdr\crt-make-model-hdr.slangp where make
|
||||||
THIS SHADER DOES NOT SUPPORT WRGB OLED (Due to the sub pixel layout of WRGB - RGB QD-OLED or LCD (and variants thereof screens are fine)
|
THIS SHADER DOES NOT SUPPORT WRGB OLED (Due to the sub pixel layout of WRGB - RGB QD-OLED or LCD (and variants thereof screens are fine)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//#pragma format A2B10G10R10_UNORM_PACK32
|
||||||
#pragma format R16G16B16A16_SFLOAT
|
#pragma format R16G16B16A16_SFLOAT
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
layout(push_constant) uniform Push
|
||||||
|
@ -31,6 +32,7 @@ layout(push_constant) uniform Push
|
||||||
float hcrt_hdr;
|
float hcrt_hdr;
|
||||||
float hcrt_max_nits;
|
float hcrt_max_nits;
|
||||||
float hcrt_paper_white_nits;
|
float hcrt_paper_white_nits;
|
||||||
|
float hcrt_expand_gamut;
|
||||||
} params;
|
} params;
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
@ -47,6 +49,7 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#define HCRT_HDR params.hcrt_hdr
|
#define HCRT_HDR params.hcrt_hdr
|
||||||
#define HCRT_MAX_NITS params.hcrt_max_nits
|
#define HCRT_MAX_NITS params.hcrt_max_nits
|
||||||
#define HCRT_PAPER_WHITE_NITS params.hcrt_paper_white_nits
|
#define HCRT_PAPER_WHITE_NITS params.hcrt_paper_white_nits
|
||||||
|
#define HCRT_EXPAND_GAMUT params.hcrt_expand_gamut
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c, d) texture(c, d)
|
#define COMPAT_TEXTURE(c, d) texture(c, d)
|
||||||
|
|
||||||
|
@ -67,6 +70,7 @@ layout(location = 0) out vec4 FragColor;
|
||||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||||
|
|
||||||
#include "include/inverse_tonemap.h"
|
#include "include/inverse_tonemap.h"
|
||||||
|
#include "include/hdr10.h"
|
||||||
|
|
||||||
vec3 InverseTonemapConditional(const vec3 linear)
|
vec3 InverseTonemapConditional(const vec3 linear)
|
||||||
{
|
{
|
||||||
|
@ -84,7 +88,19 @@ void main()
|
||||||
{
|
{
|
||||||
vec3 source = COMPAT_TEXTURE(Source, vTexCoord).rgb;
|
vec3 source = COMPAT_TEXTURE(Source, vTexCoord).rgb;
|
||||||
|
|
||||||
const vec3 hdr_colour = InverseTonemapConditional(source);
|
vec3 hdr_colour = InverseTonemapConditional(source);
|
||||||
|
|
||||||
FragColor = vec4(hdr_colour, 1.0);
|
vec3 transformed_colour;
|
||||||
|
|
||||||
|
if(HCRT_HDR < 1.0f)
|
||||||
|
{
|
||||||
|
transformed_colour = hdr_colour;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const vec3 rec2020 = hdr_colour * k2020Gamuts[uint(HCRT_EXPAND_GAMUT)];
|
||||||
|
transformed_colour = rec2020 * (HCRT_PAPER_WHITE_NITS / kMaxNitsFor2084);
|
||||||
|
}
|
||||||
|
|
||||||
|
FragColor = vec4(transformed_colour, 1.0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,5 +88,23 @@ void main()
|
||||||
|
|
||||||
const vec3 colour = ColourGrade(source);
|
const vec3 colour = ColourGrade(source);
|
||||||
|
|
||||||
FragColor = vec4(colour, 1.0);
|
vec3 transformed_colour;
|
||||||
|
|
||||||
|
if(HCRT_HDR < 1.0f)
|
||||||
|
{
|
||||||
|
if(HCRT_OUTPUT_COLOUR_SPACE == 2.0f)
|
||||||
|
{
|
||||||
|
transformed_colour = (colour * k709_to_XYZ) * kXYZ_to_DCIP3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
transformed_colour = colour;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
transformed_colour = colour;
|
||||||
|
}
|
||||||
|
|
||||||
|
FragColor = vec4(transformed_colour, 1.0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1124,7 +1124,6 @@ const uint kBlackWhiteMasks[kResolutionAxis][kTVLAxis][kBGRAxis][kMaxBlackWhiteS
|
||||||
#endif // ENABLE_BLACK_WHITE_MASKS
|
#endif // ENABLE_BLACK_WHITE_MASKS
|
||||||
|
|
||||||
#include "include/scanline_generation.h"
|
#include "include/scanline_generation.h"
|
||||||
#include "include/hdr10.h"
|
|
||||||
#include "include/gamma_correct.h"
|
#include "include/gamma_correct.h"
|
||||||
|
|
||||||
#define k1080p 0
|
#define k1080p 0
|
||||||
|
@ -1635,9 +1634,9 @@ void main()
|
||||||
scanline_colour += scanline_channel_2 * kColourMask[channel_2];
|
scanline_colour += scanline_channel_2 * kColourMask[channel_2];
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 hdr10;
|
vec3 gamma_corrected;
|
||||||
|
|
||||||
GammaCorrect(scanline_colour, hdr10);
|
GammaCorrect(scanline_colour, gamma_corrected);
|
||||||
|
|
||||||
FragColor = vec4(hdr10, 1.0f);
|
FragColor = vec4(gamma_corrected, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,11 @@ const mat3 kXYZ_to_709 = mat3(
|
||||||
-0.969244f, 1.875968f, 0.041555f,
|
-0.969244f, 1.875968f, 0.041555f,
|
||||||
0.055630f, -0.203977f, 1.056972f);
|
0.055630f, -0.203977f, 1.056972f);
|
||||||
|
|
||||||
|
const mat3 kXYZ_to_DCIP3 = mat3 (
|
||||||
|
2.4934969119f, -0.9313836179f, -0.4027107845f,
|
||||||
|
-0.8294889696f, 1.7626640603f, 0.0236246858f,
|
||||||
|
0.0358458302f, -0.0761723893f, 0.9568845240f);
|
||||||
|
|
||||||
const mat3 kColourGamut[kColourSystems] = { k709_to_XYZ, kPAL_to_XYZ, kNTSC_to_XYZ, kNTSC_to_XYZ };
|
const mat3 kColourGamut[kColourSystems] = { k709_to_XYZ, kPAL_to_XYZ, kNTSC_to_XYZ, kNTSC_to_XYZ };
|
||||||
|
|
||||||
const float kTemperatures[kColourSystems] = { kD65, kD65, kD65, kD93 };
|
const float kTemperatures[kColourSystems] = { kD65, kD65, kD65, kD93 };
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include "hdr10.h"
|
||||||
|
|
||||||
// SDR Colour output spaces
|
// SDR Colour output spaces
|
||||||
|
|
||||||
const mat3 k709_to_XYZ = mat3(
|
const mat3 k709_to_XYZ = mat3(
|
||||||
|
@ -40,26 +42,25 @@ vec3 LinearToDCIP3(const vec3 colour)
|
||||||
return vec3(LinearToDCIP3_1(colour.r), LinearToDCIP3_1(colour.g), LinearToDCIP3_1(colour.b));
|
return vec3(LinearToDCIP3_1(colour.r), LinearToDCIP3_1(colour.g), LinearToDCIP3_1(colour.b));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GammaCorrect(const vec3 scanline_colour, inout vec3 gamma_out)
|
void GammaCorrect(const vec3 scanline_colour, inout vec3 gamma_corrected)
|
||||||
{
|
{
|
||||||
if(HCRT_HDR < 1.0f)
|
if(HCRT_HDR < 1.0f)
|
||||||
{
|
{
|
||||||
if(HCRT_OUTPUT_COLOUR_SPACE == 0.0f)
|
if(HCRT_OUTPUT_COLOUR_SPACE == 0.0f)
|
||||||
{
|
{
|
||||||
gamma_out = LinearTo709(scanline_colour);
|
gamma_corrected = LinearTo709(scanline_colour);
|
||||||
}
|
}
|
||||||
else if(HCRT_OUTPUT_COLOUR_SPACE == 1.0f)
|
else if(HCRT_OUTPUT_COLOUR_SPACE == 1.0f)
|
||||||
{
|
{
|
||||||
gamma_out = LinearTosRGB(scanline_colour);
|
gamma_corrected = LinearTosRGB(scanline_colour);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const vec3 dcip3_colour = (scanline_colour * k709_to_XYZ) * kXYZ_to_DCIP3;
|
gamma_corrected = LinearToDCIP3(scanline_colour);
|
||||||
gamma_out = LinearToDCIP3(dcip3_colour);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gamma_out = Hdr10(scanline_colour, HCRT_PAPER_WHITE_NITS, HCRT_EXPAND_GAMUT);
|
gamma_corrected = LinearToST2084(scanline_colour);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -14,19 +14,25 @@ const mat3 kExpanded709_to_2020 = mat3 (
|
||||||
|
|
||||||
const mat3 k2020Gamuts[2] = { k709_to_2020, kExpanded709_to_2020 };
|
const mat3 k2020Gamuts[2] = { k709_to_2020, kExpanded709_to_2020 };
|
||||||
|
|
||||||
vec3 LinearToST2084(vec3 normalizedLinearValue)
|
float LinearToST2084_1(const float channel)
|
||||||
{
|
{
|
||||||
vec3 ST2084 = pow((0.8359375f + 18.8515625f * pow(abs(normalizedLinearValue), vec3(0.1593017578f))) / (1.0f + 18.6875f * pow(abs(normalizedLinearValue), vec3(0.1593017578f))), vec3(78.84375f));
|
float ST2084 = pow((0.8359375f + 18.8515625f * pow(abs(channel), 0.1593017578f)) / (1.0f + 18.6875f * pow(abs(channel), 0.1593017578f)), 78.84375f);
|
||||||
return ST2084; /* Don't clamp between [0..1], so we can still perform operations on scene values higher than 10,000 nits */
|
return ST2084; /* Don't clamp between [0..1], so we can still perform operations on scene values higher than 10,000 nits */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec3 LinearToST2084(const vec3 colour)
|
||||||
|
{
|
||||||
|
return vec3(LinearToST2084_1(colour.r), LinearToST2084_1(colour.g), LinearToST2084_1(colour.b));
|
||||||
|
}
|
||||||
|
|
||||||
/* END Converted from (Copyright (c) Microsoft Corporation - Licensed under the MIT License.) https://github.com/microsoft/Xbox-ATG-Samples/tree/master/Kits/ATGTK/HDR */
|
/* END Converted from (Copyright (c) Microsoft Corporation - Licensed under the MIT License.) https://github.com/microsoft/Xbox-ATG-Samples/tree/master/Kits/ATGTK/HDR */
|
||||||
|
|
||||||
/* Convert into HDR10 */
|
/* Convert into HDR10 */
|
||||||
vec3 Hdr10(vec3 hdr_linear, float paper_white_nits, float expand_gamut)
|
vec3 Hdr10(const vec3 hdr_linear, float paper_white_nits, float expand_gamut)
|
||||||
{
|
{
|
||||||
vec3 rec2020 = hdr_linear * k2020Gamuts[uint(expand_gamut)];
|
const vec3 rec2020 = hdr_linear * k2020Gamuts[uint(expand_gamut)];
|
||||||
vec3 linearColour = rec2020 * (paper_white_nits / kMaxNitsFor2084);
|
const vec3 linearColour = rec2020 * (paper_white_nits / kMaxNitsFor2084);
|
||||||
vec3 hdr10 = LinearToST2084(linearColour);
|
vec3 hdr10 = LinearToST2084(linearColour);
|
||||||
|
|
||||||
return hdr10;
|
return hdr10;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue