mirror of
https://github.com/italicsjenga/slang-shaders.git
synced 2024-11-29 19:01:31 +11:00
Merge pull request #235 from MajorPainTheCactus/hdr_5_0
V5.0 Sony PVM 4K HDR Shader
This commit is contained in:
commit
5dae9be43f
|
@ -35,7 +35,7 @@ alias0 = ""
|
||||||
float_framebuffer0 = "false"
|
float_framebuffer0 = "false"
|
||||||
srgb_framebuffer0 = "false"
|
srgb_framebuffer0 = "false"
|
||||||
|
|
||||||
hcrt_red_vertical_convergence = "-0.200000"
|
hcrt_red_vertical_convergence = "-0.140000"
|
||||||
hcrt_green_vertical_convergence = "0.000000"
|
hcrt_green_vertical_convergence = "0.000000"
|
||||||
hcrt_blue_vertical_convergence = "0.000000"
|
hcrt_blue_vertical_convergence = "0.000000"
|
||||||
hcrt_red_scanline_min = "0.550000"
|
hcrt_red_scanline_min = "0.550000"
|
||||||
|
|
|
@ -25,14 +25,6 @@ THIS SHADER DOES NOT SUPPORT WRGB OLED (Due to the sub pixel layout of WRGB - RG
|
||||||
|
|
||||||
#pragma format A2B10G10R10_UNORM_PACK32
|
#pragma format A2B10G10R10_UNORM_PACK32
|
||||||
|
|
||||||
#define WHITE_BALANCE_CONTROL 0
|
|
||||||
|
|
||||||
#include "include\hdr10.h"
|
|
||||||
|
|
||||||
#if WHITE_BALANCE_CONTROL
|
|
||||||
//#include "include\white_balance.h"
|
|
||||||
#endif // WHITE_BALANCE_CONTROL
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
layout(push_constant) uniform Push
|
||||||
{
|
{
|
||||||
// User Settings
|
// User Settings
|
||||||
|
@ -74,12 +66,21 @@ layout(push_constant) uniform Push
|
||||||
float hcrt_blue_beam_sharpness;
|
float hcrt_blue_beam_sharpness;
|
||||||
float hcrt_blue_beam_attack;
|
float hcrt_blue_beam_attack;
|
||||||
|
|
||||||
#if WHITE_BALANCE_CONTROL
|
|
||||||
float hcrt_white_temperature;
|
|
||||||
float hcrt_white_tint;
|
|
||||||
#endif // WHITE_BALANCE_CONTROL
|
|
||||||
} params;
|
} params;
|
||||||
|
|
||||||
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
{
|
||||||
|
mat4 MVP;
|
||||||
|
vec4 SourceSize;
|
||||||
|
vec4 OriginalSize;
|
||||||
|
vec4 OutputSize;
|
||||||
|
uint FrameCount;
|
||||||
|
|
||||||
|
float hcrt_colour_system;
|
||||||
|
float hcrt_colour_space;
|
||||||
|
float hcrt_white_temperature;
|
||||||
|
} global;
|
||||||
|
|
||||||
|
|
||||||
#pragma parameter hcrt_title "SONY PVM/BVM HDR SHADER" 0.0 0.0 0.0001 0.0
|
#pragma parameter hcrt_title "SONY PVM/BVM HDR SHADER" 0.0 0.0 0.0001 0.0
|
||||||
#pragma parameter hcrt_space0 " " 0.0 0.0 0.0001 0.0
|
#pragma parameter hcrt_space0 " " 0.0 0.0 0.0001 0.0
|
||||||
|
@ -99,8 +100,8 @@ layout(push_constant) uniform Push
|
||||||
#pragma parameter hcrt_paper_white_nits " Display's Paper White Luminance" 700.0 0.0 10000.0 10.0
|
#pragma parameter hcrt_paper_white_nits " Display's Paper White Luminance" 700.0 0.0 10000.0 10.0
|
||||||
#pragma parameter hcrt_lcd_resolution " Display's Resolution: 4K | 8K" 0.0 0.0 1.0 1.0
|
#pragma parameter hcrt_lcd_resolution " Display's Resolution: 4K | 8K" 0.0 0.0 1.0 1.0
|
||||||
#pragma parameter hcrt_lcd_subpixel " Display's Subpixel Layout: RGB | BGR" 0.0 0.0 1.0 1.0
|
#pragma parameter hcrt_lcd_subpixel " Display's Subpixel Layout: RGB | BGR" 0.0 0.0 1.0 1.0
|
||||||
#pragma parameter hcrt_brightness " Brightness" 1.0 0.0 2.0 0.01
|
#pragma parameter hcrt_brightness " Brightness" 0.0 -1.0 1.0 0.05
|
||||||
#pragma parameter hcrt_contrast " Contrast" -0.3 -3.0 3.0 0.05
|
#pragma parameter hcrt_contrast " Contrast" 0.0 -1.0 1.0 0.05
|
||||||
#pragma parameter hcrt_expand_gamut " Original/Vivid" 0.0 0.0 1.0 1.0
|
#pragma parameter hcrt_expand_gamut " Original/Vivid" 0.0 0.0 1.0 1.0
|
||||||
#pragma parameter hcrt_red_vertical_convergence " Red Vertical Convergence" 0.00 -10.0 10.0 0.01
|
#pragma parameter hcrt_red_vertical_convergence " Red Vertical Convergence" 0.00 -10.0 10.0 0.01
|
||||||
#pragma parameter hcrt_green_vertical_convergence " Green Vertical Convergence" 0.00 -10.0 10.0 0.01
|
#pragma parameter hcrt_green_vertical_convergence " Green Vertical Convergence" 0.00 -10.0 10.0 0.01
|
||||||
|
@ -113,6 +114,9 @@ layout(push_constant) uniform Push
|
||||||
#pragma parameter hcrt_developer_settings "DEVELOPER SETTINGS:" 0.0 0.0 0.0001 0.0
|
#pragma parameter hcrt_developer_settings "DEVELOPER SETTINGS:" 0.0 0.0 0.0001 0.0
|
||||||
#pragma parameter hcrt_crt_screen_type " CRT Type: APERTURE GRILLE | SHADOW MASK | SLOT MASK" 0.0 0.0 2.0 1.0
|
#pragma parameter hcrt_crt_screen_type " CRT Type: APERTURE GRILLE | SHADOW MASK | SLOT MASK" 0.0 0.0 2.0 1.0
|
||||||
#pragma parameter hcrt_crt_resolution " CRT Resolution: 600TVL | 800TVL | 1000TVL" 0.0 0.0 2.0 1.0
|
#pragma parameter hcrt_crt_resolution " CRT Resolution: 600TVL | 800TVL | 1000TVL" 0.0 0.0 2.0 1.0
|
||||||
|
#pragma parameter hcrt_colour_system " CRT Colour System: PAL | NTSC-U | NTSC-J" 1.0 0.0 2.0 1.0
|
||||||
|
#pragma parameter hcrt_colour_space " Colour Space: Rec.601/Rec.709 | sRGB" 0.0 0.0 1.0 1.0
|
||||||
|
#pragma parameter hcrt_white_temperature " White Point: (PAL:D65, NTSC-U:D65, NTSC-J:D93)" 0.0 -5000.0 12000.0 100.0
|
||||||
|
|
||||||
#pragma parameter hcrt_developer_settings0 " VERTICAL SETTINGS:" 0.0 0.0 0.0001 0.0
|
#pragma parameter hcrt_developer_settings0 " VERTICAL SETTINGS:" 0.0 0.0 0.0001 0.0
|
||||||
#pragma parameter hcrt_red_scanline_min " Red Scanline Min" 0.50 0.0 2.0 0.01
|
#pragma parameter hcrt_red_scanline_min " Red Scanline Min" 0.50 0.0 2.0 0.01
|
||||||
|
@ -132,11 +136,6 @@ layout(push_constant) uniform Push
|
||||||
#pragma parameter hcrt_blue_beam_sharpness " Blue Beam Sharpness" 1.75 0.0 5.0 0.05
|
#pragma parameter hcrt_blue_beam_sharpness " Blue Beam Sharpness" 1.75 0.0 5.0 0.05
|
||||||
#pragma parameter hcrt_blue_beam_attack " Blue Beam Attack" 0.50 0.0 2.0 0.01
|
#pragma parameter hcrt_blue_beam_attack " Blue Beam Attack" 0.50 0.0 2.0 0.01
|
||||||
|
|
||||||
#if WHITE_BALANCE_CONTROL
|
|
||||||
//#pragma parameter hcrt_whitetemperature "White Temperature" 6500.0 0.0 13000.0 50.0
|
|
||||||
//#pragma parameter hcrt_whitetint "White Tint" 0.0 -1.0 1.0 0.01
|
|
||||||
#endif // WHITE_BALANCE_CONTROL
|
|
||||||
|
|
||||||
|
|
||||||
#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
|
||||||
|
@ -155,6 +154,9 @@ layout(push_constant) uniform Push
|
||||||
|
|
||||||
#define HCRT_CRT_SCREEN_TYPE params.hcrt_crt_screen_type
|
#define HCRT_CRT_SCREEN_TYPE params.hcrt_crt_screen_type
|
||||||
#define HCRT_CRT_RESOLUTION params.hcrt_crt_resolution
|
#define HCRT_CRT_RESOLUTION params.hcrt_crt_resolution
|
||||||
|
#define HCRT_CRT_COLOUR_SPACE global.hcrt_colour_space
|
||||||
|
#define HCRT_CRT_COLOUR_SYSTEM global.hcrt_colour_system
|
||||||
|
#define HCRT_WHITE_TEMPERATURE global.hcrt_white_temperature
|
||||||
|
|
||||||
#define HCRT_RED_SCANLINE_MIN params.hcrt_red_scanline_min
|
#define HCRT_RED_SCANLINE_MIN params.hcrt_red_scanline_min
|
||||||
#define HCRT_RED_SCANLINE_MAX params.hcrt_red_scanline_max
|
#define HCRT_RED_SCANLINE_MAX params.hcrt_red_scanline_max
|
||||||
|
@ -175,15 +177,6 @@ layout(push_constant) uniform Push
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c, d) texture(c, d)
|
#define COMPAT_TEXTURE(c, d) texture(c, d)
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
|
||||||
{
|
|
||||||
mat4 MVP;
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
} global;
|
|
||||||
|
|
||||||
#pragma stage vertex
|
#pragma stage vertex
|
||||||
layout(location = 0) in vec4 Position;
|
layout(location = 0) in vec4 Position;
|
||||||
layout(location = 1) in vec2 TexCoord;
|
layout(location = 1) in vec2 TexCoord;
|
||||||
|
@ -394,21 +387,21 @@ float ModInteger(float a, float b)
|
||||||
return floor(m + 0.5);
|
return floor(m + 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const mat4 kCubicBezier = mat4( 1.0f, 0.0f, 0.0f, 0.0f,
|
||||||
|
-3.0f, 3.0f, 0.0f, 0.0f,
|
||||||
|
3.0f, -6.0f, 3.0f, 0.0f,
|
||||||
|
-1.0f, 3.0f, -3.0f, 1.0f );
|
||||||
|
|
||||||
|
float Bezier(const float t0, const vec4 control_points)
|
||||||
|
{
|
||||||
|
vec4 t = vec4(1.0, t0, t0*t0, t0*t0*t0);
|
||||||
|
return dot(t, control_points * kCubicBezier);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "include\hdr10.h"
|
||||||
#include "include\inverse_tonemap.h"
|
#include "include\inverse_tonemap.h"
|
||||||
|
#include "include\colour_grade.h"
|
||||||
#define kLumaRatio 0.5f
|
#include "include\scanline_generation.h"
|
||||||
|
|
||||||
vec3 InverseTonemapConditional(const vec3 sdr_balanced)
|
|
||||||
{
|
|
||||||
if(HCRT_HDR > 0.0f)
|
|
||||||
{
|
|
||||||
return InverseTonemap(sdr_balanced, HCRT_MAX_NITS, HCRT_PAPER_WHITE_NITS, kLumaRatio);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return sdr_balanced;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 Hdr10Conditional(const vec3 scanline_colour)
|
vec3 Hdr10Conditional(const vec3 scanline_colour)
|
||||||
{
|
{
|
||||||
|
@ -422,16 +415,15 @@ vec3 Hdr10Conditional(const vec3 scanline_colour)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "include\scanline_generation.h"
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec3 scanline_colour = GenerateScanline(global.SourceSize.xy);
|
const float scanline_size = global.OutputSize.y / global.SourceSize.y;
|
||||||
|
vec3 scanline_colour = GenerateScanline(global.SourceSize.xy, scanline_size);
|
||||||
|
|
||||||
uint screen_type = uint(HCRT_CRT_SCREEN_TYPE);
|
const uint screen_type = uint(HCRT_CRT_SCREEN_TYPE);
|
||||||
uint crt_resolution = uint(HCRT_CRT_RESOLUTION);
|
const uint crt_resolution = uint(HCRT_CRT_RESOLUTION);
|
||||||
uint lcd_resolution = uint(HCRT_LCD_RESOLUTION);
|
const uint lcd_resolution = uint(HCRT_LCD_RESOLUTION);
|
||||||
uint lcd_subpixel_layout = uint(HCRT_LCD_SUBPIXEL);
|
const uint lcd_subpixel_layout = uint(HCRT_LCD_SUBPIXEL);
|
||||||
|
|
||||||
const vec2 current_position = vTexCoord * global.OutputSize.xy;
|
const vec2 current_position = vTexCoord * global.OutputSize.xy;
|
||||||
|
|
||||||
|
|
152
hdr/shaders/include/colour_grade.h
Normal file
152
hdr/shaders/include/colour_grade.h
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
|
||||||
|
#define kColourSystems 3
|
||||||
|
|
||||||
|
#define kD50 5003.0f
|
||||||
|
#define kD55 5503.0f
|
||||||
|
#define kD65 6504.0f
|
||||||
|
#define kD75 7504.0f
|
||||||
|
#define kD93 9305.0f
|
||||||
|
|
||||||
|
const mat3 XYZ_to_sRGB = mat3(
|
||||||
|
3.24081254005432130, -0.969243049621582000, 0.055638398975133896,
|
||||||
|
-1.53730857372283940, 1.875966310501098600, -0.204007431864738460,
|
||||||
|
-0.49858659505844116, 0.041555050760507584, 1.057129383087158200);
|
||||||
|
|
||||||
|
const mat3 sRGB_to_XYZ = mat3(
|
||||||
|
0.41241079568862915, 0.21264933049678802, 0.019331756979227066,
|
||||||
|
0.35758456587791443, 0.71516913175582890, 0.119194857776165010,
|
||||||
|
0.18045382201671600, 0.07218152284622192, 0.950390160083770800);
|
||||||
|
|
||||||
|
// Phosphor transforms found in Grade.slang
|
||||||
|
|
||||||
|
// SMPTE-C - Measured Average Phosphor (1979-1994)
|
||||||
|
const mat3 P22_transform = mat3(
|
||||||
|
0.4665636420249939, 0.25661000609397890, 0.005832045804709196,
|
||||||
|
0.3039233088493347, 0.66820019483566280, 0.105618737637996670,
|
||||||
|
0.1799621731042862, 0.07518967241048813, 0.977465748786926300);
|
||||||
|
|
||||||
|
// SMPTE RP 145-1994 (SMPTE-C), 170M-1999
|
||||||
|
// SMPTE-C - Standard Phosphor (Rec.601 NTSC)
|
||||||
|
const mat3 SMPTE_transform = mat3(
|
||||||
|
0.39354196190834045, 0.21238772571086884, 0.01874009333550930,
|
||||||
|
0.36525884270668030, 0.70106136798858640, 0.11193416267633438,
|
||||||
|
0.19164848327636720, 0.08655092865228653, 0.95824241638183590);
|
||||||
|
|
||||||
|
// SMPTE RP 145-1994 (SMPTE-C), 170M-1999
|
||||||
|
// NTSC-J - Standard Phosphor (https://web.archive.org/web/20130413104152/http://arib.or.jp/english/html/overview/doc/4-TR-B09v1_0.pdf)
|
||||||
|
const mat3 NTSC_J_transform = mat3(
|
||||||
|
0.39603787660598755, 0.22429330646991730, 0.02050681784749031,
|
||||||
|
0.31201449036598206, 0.67417418956756590, 0.12814880907535553,
|
||||||
|
0.24496731162071228, 0.10153251141309738, 1.26512730121612550);
|
||||||
|
|
||||||
|
// ITU-R BT.470/601 (B/G)
|
||||||
|
// EBU Tech.3213-E PAL - Standard Phosphor for Studio Monitors
|
||||||
|
const mat3 EBU_transform = mat3(
|
||||||
|
0.43194326758384705, 0.22272075712680817, 0.020247340202331543,
|
||||||
|
0.34123489260673523, 0.70600330829620360, 0.129433929920196530,
|
||||||
|
0.17818950116634370, 0.07127580046653748, 0.938464701175689700);
|
||||||
|
|
||||||
|
// CRT Phosphor Gamut
|
||||||
|
const mat3 kPhosphorGamut[kColourSystems] = { EBU_transform , P22_transform, NTSC_J_transform };
|
||||||
|
|
||||||
|
const float kTemperatures[kColourSystems] = { kD65, kD65, kD93 }; // 8942.0f
|
||||||
|
|
||||||
|
// Values from: http://blenderartists.org/forum/showthread.php?270332-OSL-Goodness&p=2268693&viewfull=1#post2268693
|
||||||
|
const mat3 kWarmTemperature = mat3(
|
||||||
|
vec3(0.0, -2902.1955373783176, -8257.7997278925690),
|
||||||
|
vec3(0.0, 1669.5803561666639, 2575.2827530017594),
|
||||||
|
vec3(1.0, 1.3302673723350029, 1.8993753891711275));
|
||||||
|
|
||||||
|
const mat3 kCoolTemperature = mat3(
|
||||||
|
vec3( 1745.0425298314172, 1216.6168361476490, -8257.7997278925690),
|
||||||
|
vec3(-2666.3474220535695, -2173.1012343082230, 2575.2827530017594),
|
||||||
|
vec3( 0.55995389139931482, 0.70381203140554553, 1.8993753891711275));
|
||||||
|
|
||||||
|
vec3 WhiteBalance(float temperature, vec3 colour)
|
||||||
|
{
|
||||||
|
const mat3 m = (temperature < kD65) ? kWarmTemperature : kCoolTemperature;
|
||||||
|
|
||||||
|
const vec3 rgb_temperature = mix(clamp(vec3(m[0] / (vec3(clamp(temperature, 1000.0f, 40000.0f)) + m[1]) + m[2]), vec3(0.0f), vec3(1.0f)), vec3(1.0f), smoothstep(1000.0f, 0.0f, temperature));
|
||||||
|
|
||||||
|
vec3 result = colour * rgb_temperature;
|
||||||
|
|
||||||
|
result *= dot(colour, vec3(0.2126, 0.7152, 0.0722)) / max(dot(result, vec3(0.2126, 0.7152, 0.0722)), 1e-5); // Preserve luminance
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
float r601r709ToLinear_1(const float channel)
|
||||||
|
{
|
||||||
|
return (channel > 0.081f) ? pow((channel + 0.099f) * (1.0f / 1.099f), 1.0f / 0.45f) : channel * (1.0f / 4.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 r601r709ToLinear(const vec3 colour)
|
||||||
|
{
|
||||||
|
return vec3(r601r709ToLinear_1(colour.r), r601r709ToLinear_1(colour.g), r601r709ToLinear_1(colour.b));
|
||||||
|
}
|
||||||
|
|
||||||
|
const vec4 kTopBrightnessControlPoints = vec4(0.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
const vec4 kMidBrightnessControlPoints = vec4(0.0f, 1.0f / 3.0f, (1.0f / 3.0f) * 2.0f, 1.0f);
|
||||||
|
const vec4 kBottomBrightnessControlPoints = vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
vec3 Brightness(const vec3 colour)
|
||||||
|
{
|
||||||
|
if(HCRT_BRIGHTNESS >= 0.0f)
|
||||||
|
{
|
||||||
|
return vec3(Bezier(colour.r, mix(kMidBrightnessControlPoints, kTopBrightnessControlPoints, HCRT_BRIGHTNESS)),
|
||||||
|
Bezier(colour.g, mix(kMidBrightnessControlPoints, kTopBrightnessControlPoints, HCRT_BRIGHTNESS)),
|
||||||
|
Bezier(colour.b, mix(kMidBrightnessControlPoints, kTopBrightnessControlPoints, HCRT_BRIGHTNESS)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return vec3(Bezier(colour.r, mix(kMidBrightnessControlPoints, kBottomBrightnessControlPoints, abs(HCRT_BRIGHTNESS))),
|
||||||
|
Bezier(colour.g, mix(kMidBrightnessControlPoints, kBottomBrightnessControlPoints, abs(HCRT_BRIGHTNESS))),
|
||||||
|
Bezier(colour.b, mix(kMidBrightnessControlPoints, kBottomBrightnessControlPoints, abs(HCRT_BRIGHTNESS))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const vec4 kTopContrastControlPoints = vec4(0.0f, 0.0f, 1.0f, 1.0f);
|
||||||
|
const vec4 kMidContrastControlPoints = vec4(0.0f, 1.0f / 3.0f, (1.0f / 3.0f) * 2.0f, 1.0f);
|
||||||
|
const vec4 kBottomContrastControlPoints = vec4(0.0f, 1.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
vec3 Contrast(const vec3 colour)
|
||||||
|
{
|
||||||
|
if(HCRT_CONTRAST >= 0.0f)
|
||||||
|
{
|
||||||
|
return vec3(Bezier(colour.r, mix(kMidContrastControlPoints, kTopContrastControlPoints, HCRT_CONTRAST)),
|
||||||
|
Bezier(colour.g, mix(kMidContrastControlPoints, kTopContrastControlPoints, HCRT_CONTRAST)),
|
||||||
|
Bezier(colour.b, mix(kMidContrastControlPoints, kTopContrastControlPoints, HCRT_CONTRAST)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return vec3(Bezier(colour.r, mix(kMidContrastControlPoints, kBottomContrastControlPoints, abs(HCRT_CONTRAST))),
|
||||||
|
Bezier(colour.g, mix(kMidContrastControlPoints, kBottomContrastControlPoints, abs(HCRT_CONTRAST))),
|
||||||
|
Bezier(colour.b, mix(kMidContrastControlPoints, kBottomContrastControlPoints, abs(HCRT_CONTRAST))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float sRGBToLinear_1(const float channel)
|
||||||
|
{
|
||||||
|
return (channel > 0.04045f) ? pow((channel + 0.055f) * (1.0f / 1.055f), 2.4f) : channel * (1.0f / 12.92f);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 sRGBToLinear(const vec3 colour)
|
||||||
|
{
|
||||||
|
return vec3(sRGBToLinear_1(colour.r), sRGBToLinear_1(colour.g), sRGBToLinear_1(colour.b));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 ColourGrade(const vec3 colour)
|
||||||
|
{
|
||||||
|
const uint colour_system = uint(HCRT_CRT_COLOUR_SYSTEM);
|
||||||
|
|
||||||
|
const vec3 brightness = Brightness(colour);
|
||||||
|
|
||||||
|
const vec3 contrast = Contrast(brightness);
|
||||||
|
|
||||||
|
const vec3 linear = HCRT_CRT_COLOUR_SPACE == 0.0f ? r601r709ToLinear(contrast) : sRGBToLinear(contrast);
|
||||||
|
|
||||||
|
const vec3 gamut = kPhosphorGamut[colour_system] * linear;
|
||||||
|
|
||||||
|
const vec3 white_point = WhiteBalance(kTemperatures[colour_system] + HCRT_WHITE_TEMPERATURE, gamut);
|
||||||
|
|
||||||
|
return clamp(XYZ_to_sRGB * white_point, 0.0f, 1.0f);
|
||||||
|
}
|
|
@ -4,11 +4,7 @@
|
||||||
#define kMax 1.0f
|
#define kMax 1.0f
|
||||||
|
|
||||||
#define kBeamWidth 0.5f
|
#define kBeamWidth 0.5f
|
||||||
|
#define kLumaRatio 0.5f
|
||||||
const mat4 kCubicBezier = mat4( 1.0f, 0.0f, 0.0f, 0.0f,
|
|
||||||
-3.0f, 3.0f, 0.0f, 0.0f,
|
|
||||||
3.0f, -6.0f, 3.0f, 0.0f,
|
|
||||||
-1.0f, 3.0f, -3.0f, 1.0f );
|
|
||||||
|
|
||||||
const vec4 kFallOffControlPoints = vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
const vec4 kFallOffControlPoints = vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
const vec4 kAttackControlPoints = vec4(0.0f, 1.0f, 1.0f, 1.0f);
|
const vec4 kAttackControlPoints = vec4(0.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
@ -38,38 +34,19 @@ vec4 BlueBeamControlPoints(const bool falloff)
|
||||||
return falloff ? kFallOffControlPoints + vec4(0.0f, outer_attack, inner_attack, 0.0f) : kAttackControlPoints - vec4(0.0f, inner_attack, outer_attack, 0.0f);
|
return falloff ? kFallOffControlPoints + vec4(0.0f, outer_attack, inner_attack, 0.0f) : kAttackControlPoints - vec4(0.0f, inner_attack, outer_attack, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
float Bezier(const float t0, const vec4 control_points)
|
vec3 InverseTonemapConditional(const vec3 linear)
|
||||||
{
|
{
|
||||||
vec4 t = vec4(1.0, t0, t0*t0, t0*t0*t0);
|
if(HCRT_HDR > 0.0f)
|
||||||
return dot(t, control_points * kCubicBezier);
|
{
|
||||||
|
return InverseTonemap(linear, HCRT_MAX_NITS, HCRT_PAPER_WHITE_NITS, kLumaRatio);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return linear;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float ToLinear1(float channel)
|
vec3 ScanlineColour(const vec2 source_size, const float scanline_size, const vec3 source_tex_coord_x, const vec3 narrowed_source_pixel_offset, inout vec3 next_prev)
|
||||||
{
|
|
||||||
return (channel > 0.04045f) ? pow(abs(channel) * (1.0f / 1.055f) + (0.055f / 1.055f), 2.4f) : channel * (1.0f / 12.92f);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 ToLinear(vec3 colour)
|
|
||||||
{
|
|
||||||
return vec3(ToLinear1(colour.r), ToLinear1(colour.g), ToLinear1(colour.b));
|
|
||||||
}
|
|
||||||
|
|
||||||
float Contrast1(float linear, float channel)
|
|
||||||
{
|
|
||||||
return (channel > 0.04045f) ? linear * pow(abs(channel) * (1.0f / 1.055f) + (0.055f / 1.055f), HCRT_CONTRAST) : channel * (1.0f / 12.92f);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 Contrast(vec3 linear, vec3 colour)
|
|
||||||
{
|
|
||||||
return vec3(Contrast1(linear.r, colour.r), Contrast1(linear.g, colour.g), Contrast1(linear.b, colour.b));
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 Ramp(const vec3 luminance, const vec3 colour)
|
|
||||||
{
|
|
||||||
return clamp(luminance * colour, 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 ScanlineColour(const vec2 source_size, const vec3 source_tex_coord_x, const vec3 narrowed_source_pixel_offset, inout vec3 next_prev)
|
|
||||||
{
|
{
|
||||||
const vec3 current_source_position_y = (vec3(vTexCoord.y * source_size.y) - vec3(HCRT_RED_VERTICAL_CONVERGENCE, HCRT_GREEN_VERTICAL_CONVERGENCE, HCRT_BLUE_VERTICAL_CONVERGENCE)) + next_prev;
|
const vec3 current_source_position_y = (vec3(vTexCoord.y * source_size.y) - vec3(HCRT_RED_VERTICAL_CONVERGENCE, HCRT_GREEN_VERTICAL_CONVERGENCE, HCRT_BLUE_VERTICAL_CONVERGENCE)) + next_prev;
|
||||||
const vec3 current_source_center_y = floor(current_source_position_y) + 0.5f;
|
const vec3 current_source_center_y = floor(current_source_position_y) + 0.5f;
|
||||||
|
@ -78,8 +55,6 @@ vec3 ScanlineColour(const vec2 source_size, const vec3 source_tex_coord_x, const
|
||||||
|
|
||||||
const vec3 scanline_delta = fract(current_source_position_y) - 0.5f;
|
const vec3 scanline_delta = fract(current_source_position_y) - 0.5f;
|
||||||
|
|
||||||
const float scanline_size = global.OutputSize.y / source_size.y;
|
|
||||||
|
|
||||||
// Slightly increase the beam width to get maximum brightness
|
// Slightly increase the beam width to get maximum brightness
|
||||||
vec3 beam_distance = abs(scanline_delta - next_prev) - (kBeamWidth / scanline_size);
|
vec3 beam_distance = abs(scanline_delta - next_prev) - (kBeamWidth / scanline_size);
|
||||||
beam_distance = vec3(beam_distance.x < 0.0f ? 0.0f : beam_distance.x,
|
beam_distance = vec3(beam_distance.x < 0.0f ? 0.0f : beam_distance.x,
|
||||||
|
@ -109,34 +84,19 @@ vec3 ScanlineColour(const vec2 source_size, const vec3 source_tex_coord_x, const
|
||||||
const float blue_0 = COMPAT_TEXTURE(Source, blue_tex_coord_0).z;
|
const float blue_0 = COMPAT_TEXTURE(Source, blue_tex_coord_0).z;
|
||||||
const float blue_1 = COMPAT_TEXTURE(Source, blue_tex_coord_1).z;
|
const float blue_1 = COMPAT_TEXTURE(Source, blue_tex_coord_1).z;
|
||||||
|
|
||||||
const vec3 sdr_colour_0 = vec3(red_0, green_0, blue_0);
|
const vec3 sdr_colour_0 = ColourGrade(vec3(red_0, green_0, blue_0));
|
||||||
const vec3 sdr_colour_1 = vec3(red_1, green_1, blue_1);
|
const vec3 sdr_colour_1 = ColourGrade(vec3(red_1, green_1, blue_1));
|
||||||
|
|
||||||
const vec3 sdr_linear_0 = ToLinear(sdr_colour_0);
|
const vec3 hdr_colour_0 = InverseTonemapConditional(sdr_colour_0);
|
||||||
const vec3 sdr_linear_1 = ToLinear(sdr_colour_1);
|
const vec3 hdr_colour_1 = InverseTonemapConditional(sdr_colour_1);
|
||||||
|
|
||||||
const vec3 sdr_constrast_0 = Contrast(sdr_linear_0, sdr_colour_0);
|
|
||||||
const vec3 sdr_constrast_1 = Contrast(sdr_linear_1, sdr_colour_1);
|
|
||||||
|
|
||||||
#if WHITE_BALANCE_CONTROL
|
|
||||||
//const vec3 sdr_balanced_0 = WhiteBalance(sdr_constrast_0, HCRT_WHITE_TEMPERATURE, HCRT_WHITE_TINT);
|
|
||||||
//const vec3 sdr_balanced_1 = WhiteBalance(sdr_constrast_1, HCRT_WHITE_TEMPERATURE, HCRT_WHITE_TINT);
|
|
||||||
#else
|
|
||||||
const vec3 sdr_balanced_0 = sdr_constrast_0;
|
|
||||||
const vec3 sdr_balanced_1 = sdr_constrast_1;
|
|
||||||
#endif // WHITE_BALANCE_CONTROL
|
|
||||||
|
|
||||||
// HACK: To get maximum brightness we just set paper white luminance to max luminance
|
|
||||||
const vec3 hdr_colour_0 = InverseTonemapConditional(sdr_balanced_0);
|
|
||||||
const vec3 hdr_colour_1 = InverseTonemapConditional(sdr_balanced_1);
|
|
||||||
|
|
||||||
/* Horizontal interpolation between pixels */
|
/* Horizontal interpolation between pixels */
|
||||||
const vec3 horiz_interp = vec3(Bezier(narrowed_source_pixel_offset.x, RedBeamControlPoints(sdr_linear_0.x > sdr_linear_1.x)),
|
const vec3 horiz_interp = vec3(Bezier(narrowed_source_pixel_offset.x, RedBeamControlPoints(sdr_colour_0.x > sdr_colour_1.x)),
|
||||||
Bezier(narrowed_source_pixel_offset.y, GreenBeamControlPoints(sdr_linear_0.y > sdr_linear_1.y)),
|
Bezier(narrowed_source_pixel_offset.y, GreenBeamControlPoints(sdr_colour_0.y > sdr_colour_1.y)),
|
||||||
Bezier(narrowed_source_pixel_offset.z, BlueBeamControlPoints(sdr_linear_0.z > sdr_linear_1.z)));
|
Bezier(narrowed_source_pixel_offset.z, BlueBeamControlPoints(sdr_colour_0.z > sdr_colour_1.z)));
|
||||||
|
|
||||||
const vec3 hdr_colour = mix(hdr_colour_0, hdr_colour_1, horiz_interp);
|
const vec3 hdr_colour = mix(hdr_colour_0, hdr_colour_1, horiz_interp);
|
||||||
const vec3 sdr_colour = mix(sdr_linear_0, sdr_linear_1, horiz_interp);
|
const vec3 sdr_colour = mix(sdr_colour_0, sdr_colour_1, horiz_interp);
|
||||||
|
|
||||||
const float red_scanline_distance = clamp(scanline_distance.x / ((sdr_colour.r * (HCRT_RED_SCANLINE_MAX - HCRT_RED_SCANLINE_MIN)) + HCRT_RED_SCANLINE_MIN), 0.0f, 1.0f);
|
const float red_scanline_distance = clamp(scanline_distance.x / ((sdr_colour.r * (HCRT_RED_SCANLINE_MAX - HCRT_RED_SCANLINE_MIN)) + HCRT_RED_SCANLINE_MIN), 0.0f, 1.0f);
|
||||||
const float green_scanline_distance = clamp(scanline_distance.y / ((sdr_colour.g * (HCRT_GREEN_SCANLINE_MAX - HCRT_GREEN_SCANLINE_MIN)) + HCRT_GREEN_SCANLINE_MIN), 0.0f, 1.0f);
|
const float green_scanline_distance = clamp(scanline_distance.y / ((sdr_colour.g * (HCRT_GREEN_SCANLINE_MAX - HCRT_GREEN_SCANLINE_MIN)) + HCRT_GREEN_SCANLINE_MIN), 0.0f, 1.0f);
|
||||||
|
@ -153,7 +113,7 @@ vec3 ScanlineColour(const vec2 source_size, const vec3 source_tex_coord_x, const
|
||||||
return luminance * hdr_colour;
|
return luminance * hdr_colour;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 GenerateScanline(const vec2 source_size)
|
vec3 GenerateScanline(const vec2 source_size, const float scanline_size)
|
||||||
{
|
{
|
||||||
const vec3 current_source_position_x = vec3(vTexCoord.x * source_size.x) - vec3(HCRT_RED_HORIZONTAL_CONVERGENCE, HCRT_GREEN_HORIZONTAL_CONVERGENCE, HCRT_BLUE_HORIZONTAL_CONVERGENCE);
|
const vec3 current_source_position_x = vec3(vTexCoord.x * source_size.x) - vec3(HCRT_RED_HORIZONTAL_CONVERGENCE, HCRT_GREEN_HORIZONTAL_CONVERGENCE, HCRT_BLUE_HORIZONTAL_CONVERGENCE);
|
||||||
const vec3 current_source_center_x = floor(current_source_position_x) + 0.5f;
|
const vec3 current_source_center_x = floor(current_source_position_x) + 0.5f;
|
||||||
|
@ -167,14 +127,14 @@ vec3 GenerateScanline(const vec2 source_size)
|
||||||
|
|
||||||
vec3 next_prev = vec3(0.0f);
|
vec3 next_prev = vec3(0.0f);
|
||||||
|
|
||||||
const vec3 scanline_colour0 = ScanlineColour(source_size, source_tex_coord_x, narrowed_source_pixel_offset, next_prev);
|
const vec3 scanline_colour0 = ScanlineColour(source_size, scanline_size, source_tex_coord_x, narrowed_source_pixel_offset, next_prev);
|
||||||
|
|
||||||
// Optionally sample the neighbouring scanline
|
// Optionally sample the neighbouring scanline
|
||||||
vec3 scanline_colour1 = vec3(0.0f);
|
vec3 scanline_colour1 = vec3(0.0f);
|
||||||
if(HCRT_RED_SCANLINE_MAX > 1.0f || HCRT_GREEN_SCANLINE_MAX > 1.0f || HCRT_BLUE_SCANLINE_MAX > 1.0f)
|
if(HCRT_RED_SCANLINE_MAX > 1.0f || HCRT_GREEN_SCANLINE_MAX > 1.0f || HCRT_BLUE_SCANLINE_MAX > 1.0f)
|
||||||
{
|
{
|
||||||
scanline_colour1 = ScanlineColour(source_size, source_tex_coord_x, narrowed_source_pixel_offset, next_prev);
|
scanline_colour1 = ScanlineColour(source_size, scanline_size, source_tex_coord_x, narrowed_source_pixel_offset, next_prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
return scanline_colour0 * HCRT_BRIGHTNESS + scanline_colour1;
|
return scanline_colour0 + scanline_colour1;
|
||||||
}
|
}
|
Loading…
Reference in a new issue