mirror of
https://github.com/italicsjenga/slang-shaders.git
synced 2024-11-23 00:01:31 +11:00
Merge pull request #239 from MajorPainTheCactus/megatron_1_2
V1.2 Sony Megatron Shader
This commit is contained in:
commit
32a9a5f86e
|
@ -28,16 +28,32 @@ Works only with the D3D11/D3D12/Vulkan drivers currently
|
||||||
THIS SHADER DOES NOT SUPPORT WRGB OLED (Due to the sub pixel layout of WRGB - QD-OLED or LCD (and variants thereof screens are fine) - It will work just wont look right
|
THIS SHADER DOES NOT SUPPORT WRGB OLED (Due to the sub pixel layout of WRGB - QD-OLED or LCD (and variants thereof screens are fine) - It will work just wont look right
|
||||||
*/
|
*/
|
||||||
|
|
||||||
shaders = "1"
|
shaders = "3"
|
||||||
feedback_pass = "0"
|
feedback_pass = "0"
|
||||||
|
|
||||||
shader0 = "shaders/crt-sony-megatron.slang"
|
shader0 = "shaders/crt-sony-megatron-source-pass.slang"
|
||||||
filter_linear0 = "false"
|
filter_linear0 = "false"
|
||||||
|
scale_type0 = "source"
|
||||||
|
scale0 = "1.0"
|
||||||
wrap_mode0 = "clamp_to_border"
|
wrap_mode0 = "clamp_to_border"
|
||||||
mipmap_input0 = "false"
|
mipmap_input0 = "false"
|
||||||
alias0 = ""
|
alias0 = "SourceSDR"
|
||||||
float_framebuffer0 = "false"
|
|
||||||
srgb_framebuffer0 = "false"
|
shader1 = "shaders/crt-sony-megatron-hdr-pass.slang"
|
||||||
|
filter_linear1 = "false"
|
||||||
|
scale_type1 = "source"
|
||||||
|
scale1 = "1.0"
|
||||||
|
wrap_mode1 = "clamp_to_border"
|
||||||
|
mipmap_input1 = "false"
|
||||||
|
alias1 = "SourceHDR"
|
||||||
|
|
||||||
|
shader2 = "shaders/crt-sony-megatron.slang"
|
||||||
|
filter_linear2 = "false"
|
||||||
|
wrap_mode2 = "clamp_to_border"
|
||||||
|
mipmap_input2 = "false"
|
||||||
|
alias2 = ""
|
||||||
|
float_framebuffer2 = "false"
|
||||||
|
srgb_framebuffer2 = "false"
|
||||||
|
|
||||||
hcrt_crt_screen_type = "2.000000"
|
hcrt_crt_screen_type = "2.000000"
|
||||||
hcrt_paper_white_nits = "600.000000"
|
hcrt_paper_white_nits = "600.000000"
|
||||||
|
|
|
@ -28,16 +28,32 @@ Works only with the D3D11/D3D12/Vulkan drivers currently
|
||||||
THIS SHADER DOES NOT SUPPORT WRGB OLED (Due to the sub pixel layout of WRGB - QD-OLED or LCD (and variants thereof screens are fine) - It will work just wont look right
|
THIS SHADER DOES NOT SUPPORT WRGB OLED (Due to the sub pixel layout of WRGB - QD-OLED or LCD (and variants thereof screens are fine) - It will work just wont look right
|
||||||
*/
|
*/
|
||||||
|
|
||||||
shaders = "1"
|
shaders = "3"
|
||||||
feedback_pass = "0"
|
feedback_pass = "0"
|
||||||
|
|
||||||
shader0 = "shaders/crt-sony-megatron.slang"
|
shader0 = "shaders/crt-sony-megatron-source-pass.slang"
|
||||||
filter_linear0 = "false"
|
filter_linear0 = "false"
|
||||||
|
scale_type0 = "source"
|
||||||
|
scale0 = "1.0"
|
||||||
wrap_mode0 = "clamp_to_border"
|
wrap_mode0 = "clamp_to_border"
|
||||||
mipmap_input0 = "false"
|
mipmap_input0 = "false"
|
||||||
alias0 = ""
|
alias0 = "SourceSDR"
|
||||||
float_framebuffer0 = "false"
|
|
||||||
srgb_framebuffer0 = "false"
|
shader1 = "shaders/crt-sony-megatron-hdr-pass.slang"
|
||||||
|
filter_linear1 = "false"
|
||||||
|
scale_type1 = "source"
|
||||||
|
scale1 = "1.0"
|
||||||
|
wrap_mode1 = "clamp_to_border"
|
||||||
|
mipmap_input1 = "false"
|
||||||
|
alias1 = "SourceHDR"
|
||||||
|
|
||||||
|
shader2 = "shaders/crt-sony-megatron.slang"
|
||||||
|
filter_linear2 = "false"
|
||||||
|
wrap_mode2 = "clamp_to_border"
|
||||||
|
mipmap_input2 = "false"
|
||||||
|
alias2 = ""
|
||||||
|
float_framebuffer2 = "false"
|
||||||
|
srgb_framebuffer2 = "false"
|
||||||
|
|
||||||
hcrt_crt_screen_type = "2.000000"
|
hcrt_crt_screen_type = "2.000000"
|
||||||
hcrt_red_scanline_min = "0.650000"
|
hcrt_red_scanline_min = "0.650000"
|
||||||
|
|
|
@ -28,16 +28,32 @@ Works only with the D3D11/D3D12/Vulkan drivers currently
|
||||||
THIS SHADER DOES NOT SUPPORT WRGB OLED (Due to the sub pixel layout of WRGB - QD-OLED or LCD (and variants thereof screens are fine) - It will work just wont look right
|
THIS SHADER DOES NOT SUPPORT WRGB OLED (Due to the sub pixel layout of WRGB - QD-OLED or LCD (and variants thereof screens are fine) - It will work just wont look right
|
||||||
*/
|
*/
|
||||||
|
|
||||||
shaders = "1"
|
shaders = "3"
|
||||||
feedback_pass = "0"
|
feedback_pass = "0"
|
||||||
|
|
||||||
shader0 = "shaders/crt-sony-megatron.slang"
|
shader0 = "shaders/crt-sony-megatron-source-pass.slang"
|
||||||
filter_linear0 = "false"
|
filter_linear0 = "false"
|
||||||
|
scale_type0 = "source"
|
||||||
|
scale0 = "1.0"
|
||||||
wrap_mode0 = "clamp_to_border"
|
wrap_mode0 = "clamp_to_border"
|
||||||
mipmap_input0 = "false"
|
mipmap_input0 = "false"
|
||||||
alias0 = ""
|
alias0 = "SourceSDR"
|
||||||
float_framebuffer0 = "false"
|
|
||||||
srgb_framebuffer0 = "false"
|
shader1 = "shaders/crt-sony-megatron-hdr-pass.slang"
|
||||||
|
filter_linear1 = "false"
|
||||||
|
scale_type1 = "source"
|
||||||
|
scale1 = "1.0"
|
||||||
|
wrap_mode1 = "clamp_to_border"
|
||||||
|
mipmap_input1 = "false"
|
||||||
|
alias1 = "SourceHDR"
|
||||||
|
|
||||||
|
shader2 = "shaders/crt-sony-megatron.slang"
|
||||||
|
filter_linear2 = "false"
|
||||||
|
wrap_mode2 = "clamp_to_border"
|
||||||
|
mipmap_input2 = "false"
|
||||||
|
alias2 = ""
|
||||||
|
float_framebuffer2 = "false"
|
||||||
|
srgb_framebuffer2 = "false"
|
||||||
|
|
||||||
hcrt_crt_screen_type = "1.000000"
|
hcrt_crt_screen_type = "1.000000"
|
||||||
hcrt_crt_resolution = "2.000000"
|
hcrt_crt_resolution = "2.000000"
|
||||||
|
|
|
@ -28,16 +28,32 @@ Works only with the D3D11/D3D12/Vulkan drivers currently
|
||||||
THIS SHADER DOES NOT SUPPORT WRGB OLED (Due to the sub pixel layout of WRGB - QD-OLED or LCD (and variants thereof screens are fine) - It will work just wont look right
|
THIS SHADER DOES NOT SUPPORT WRGB OLED (Due to the sub pixel layout of WRGB - QD-OLED or LCD (and variants thereof screens are fine) - It will work just wont look right
|
||||||
*/
|
*/
|
||||||
|
|
||||||
shaders = "1"
|
shaders = "3"
|
||||||
feedback_pass = "0"
|
feedback_pass = "0"
|
||||||
|
|
||||||
shader0 = "shaders/crt-sony-megatron.slang"
|
shader0 = "shaders/crt-sony-megatron-source-pass.slang"
|
||||||
filter_linear0 = "false"
|
filter_linear0 = "false"
|
||||||
|
scale_type0 = "source"
|
||||||
|
scale0 = "1.0"
|
||||||
wrap_mode0 = "clamp_to_border"
|
wrap_mode0 = "clamp_to_border"
|
||||||
mipmap_input0 = "false"
|
mipmap_input0 = "false"
|
||||||
alias0 = ""
|
alias0 = "SourceSDR"
|
||||||
float_framebuffer0 = "false"
|
|
||||||
srgb_framebuffer0 = "false"
|
shader1 = "shaders/crt-sony-megatron-hdr-pass.slang"
|
||||||
|
filter_linear1 = "false"
|
||||||
|
scale_type1 = "source"
|
||||||
|
scale1 = "1.0"
|
||||||
|
wrap_mode1 = "clamp_to_border"
|
||||||
|
mipmap_input1 = "false"
|
||||||
|
alias1 = "SourceHDR"
|
||||||
|
|
||||||
|
shader2 = "shaders/crt-sony-megatron.slang"
|
||||||
|
filter_linear2 = "false"
|
||||||
|
wrap_mode2 = "clamp_to_border"
|
||||||
|
mipmap_input2 = "false"
|
||||||
|
alias2 = ""
|
||||||
|
float_framebuffer2 = "false"
|
||||||
|
srgb_framebuffer2 = "false"
|
||||||
|
|
||||||
hcrt_brightness = "0.150000"
|
hcrt_brightness = "0.150000"
|
||||||
hcrt_colour_system = "0.000000"
|
hcrt_colour_system = "0.000000"
|
||||||
|
|
|
@ -28,15 +28,31 @@ Works only with the D3D11/D3D12/Vulkan drivers currently
|
||||||
THIS SHADER DOES NOT SUPPORT WRGB OLED (Due to the sub pixel layout of WRGB - QD-OLED or LCD (and variants thereof screens are fine) - It will work just wont look right
|
THIS SHADER DOES NOT SUPPORT WRGB OLED (Due to the sub pixel layout of WRGB - QD-OLED or LCD (and variants thereof screens are fine) - It will work just wont look right
|
||||||
*/
|
*/
|
||||||
|
|
||||||
shaders = "1"
|
shaders = "3"
|
||||||
feedback_pass = "0"
|
feedback_pass = "0"
|
||||||
|
|
||||||
shader0 = "shaders/crt-sony-megatron.slang"
|
shader0 = "shaders/crt-sony-megatron-source-pass.slang"
|
||||||
filter_linear0 = "false"
|
filter_linear0 = "false"
|
||||||
|
scale_type0 = "source"
|
||||||
|
scale0 = "1.0"
|
||||||
wrap_mode0 = "clamp_to_border"
|
wrap_mode0 = "clamp_to_border"
|
||||||
mipmap_input0 = "false"
|
mipmap_input0 = "false"
|
||||||
alias0 = ""
|
alias0 = "SourceSDR"
|
||||||
float_framebuffer0 = "false"
|
|
||||||
srgb_framebuffer0 = "false"
|
shader1 = "shaders/crt-sony-megatron-hdr-pass.slang"
|
||||||
|
filter_linear1 = "false"
|
||||||
|
scale_type1 = "source"
|
||||||
|
scale1 = "1.0"
|
||||||
|
wrap_mode1 = "clamp_to_border"
|
||||||
|
mipmap_input1 = "false"
|
||||||
|
alias1 = "SourceHDR"
|
||||||
|
|
||||||
|
shader2 = "shaders/crt-sony-megatron.slang"
|
||||||
|
filter_linear2 = "false"
|
||||||
|
wrap_mode2 = "clamp_to_border"
|
||||||
|
mipmap_input2 = "false"
|
||||||
|
alias2 = ""
|
||||||
|
float_framebuffer2 = "false"
|
||||||
|
srgb_framebuffer2 = "false"
|
||||||
|
|
||||||
hcrt_crt_screen_type = "1.000000"
|
hcrt_crt_screen_type = "1.000000"
|
||||||
|
|
|
@ -28,16 +28,32 @@ Works only with the D3D11/D3D12/Vulkan drivers currently
|
||||||
THIS SHADER DOES NOT SUPPORT WRGB OLED (Due to the sub pixel layout of WRGB - QD-OLED or LCD (and variants thereof screens are fine) - It will work just wont look right
|
THIS SHADER DOES NOT SUPPORT WRGB OLED (Due to the sub pixel layout of WRGB - QD-OLED or LCD (and variants thereof screens are fine) - It will work just wont look right
|
||||||
*/
|
*/
|
||||||
|
|
||||||
shaders = "1"
|
shaders = "3"
|
||||||
feedback_pass = "0"
|
feedback_pass = "0"
|
||||||
|
|
||||||
shader0 = "shaders/crt-sony-megatron.slang"
|
shader0 = "shaders/crt-sony-megatron-source-pass.slang"
|
||||||
filter_linear0 = "false"
|
filter_linear0 = "false"
|
||||||
|
scale_type0 = "source"
|
||||||
|
scale0 = "1.0"
|
||||||
wrap_mode0 = "clamp_to_border"
|
wrap_mode0 = "clamp_to_border"
|
||||||
mipmap_input0 = "false"
|
mipmap_input0 = "false"
|
||||||
alias0 = ""
|
alias0 = "SourceSDR"
|
||||||
float_framebuffer0 = "false"
|
|
||||||
srgb_framebuffer0 = "false"
|
shader1 = "shaders/crt-sony-megatron-hdr-pass.slang"
|
||||||
|
filter_linear1 = "false"
|
||||||
|
scale_type1 = "source"
|
||||||
|
scale1 = "1.0"
|
||||||
|
wrap_mode1 = "clamp_to_border"
|
||||||
|
mipmap_input1 = "false"
|
||||||
|
alias1 = "SourceHDR"
|
||||||
|
|
||||||
|
shader2 = "shaders/crt-sony-megatron.slang"
|
||||||
|
filter_linear2 = "false"
|
||||||
|
wrap_mode2 = "clamp_to_border"
|
||||||
|
mipmap_input2 = "false"
|
||||||
|
alias2 = ""
|
||||||
|
float_framebuffer2 = "false"
|
||||||
|
srgb_framebuffer2 = "false"
|
||||||
|
|
||||||
hcrt_crt_screen_type = "1.000000"
|
hcrt_crt_screen_type = "1.000000"
|
||||||
hcrt_crt_resolution = "2.000000"
|
hcrt_crt_resolution = "2.000000"
|
||||||
|
|
90
hdr/shaders/crt-sony-megatron-hdr-pass.slang
Normal file
90
hdr/shaders/crt-sony-megatron-hdr-pass.slang
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
/*
|
||||||
|
A shader that tries to emulate a sony PVM type aperture grille screen but with full brightness.
|
||||||
|
|
||||||
|
The novel thing about this shader is that it relies on the HDR shaders to brighten up the image so that when
|
||||||
|
we apply this shader which emulates the apperture grille the resulting screen isn't left too dark.
|
||||||
|
|
||||||
|
I think you need at least a DisplayHDR 600 monitor but to get close to CRT levels of brightness I think DisplayHDR 1000.
|
||||||
|
|
||||||
|
Please Enable HDR in RetroArch 1.10+
|
||||||
|
|
||||||
|
NOTE: when this shader is envoked the Contrast, Peak Luminance and Paper White Luminance in the HDR menu do nothing instead set those values through the shader parameters
|
||||||
|
|
||||||
|
For this shader set Paper White Luminance to above 700 and Peak Luminance to the peak luminance of your monitor.
|
||||||
|
|
||||||
|
Also try to use a integer scaling - its just better - overscaling is fine.
|
||||||
|
|
||||||
|
This shader doesn't do any geometry warping or bouncing of light around inside the screen etc - I think these effects just add unwanted noise, I know people disagree. Please feel free to make you own and add them
|
||||||
|
|
||||||
|
Dont use this shader directly - use the hdr\crt-make-model-hdr.slangp where make and model are the make and model of the CRT you want.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
layout(push_constant) uniform Push
|
||||||
|
{
|
||||||
|
// User Settings
|
||||||
|
float hcrt_hdr;
|
||||||
|
float hcrt_max_nits;
|
||||||
|
float hcrt_paper_white_nits;
|
||||||
|
} params;
|
||||||
|
|
||||||
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
{
|
||||||
|
mat4 MVP;
|
||||||
|
vec4 SourceSize;
|
||||||
|
vec4 OriginalSize;
|
||||||
|
vec4 OutputSize;
|
||||||
|
uint FrameCount;
|
||||||
|
} global;
|
||||||
|
|
||||||
|
#include "include/parameters.h"
|
||||||
|
|
||||||
|
#define HCRT_HDR params.hcrt_hdr
|
||||||
|
#define HCRT_MAX_NITS params.hcrt_max_nits
|
||||||
|
#define HCRT_PAPER_WHITE_NITS params.hcrt_paper_white_nits
|
||||||
|
|
||||||
|
#define COMPAT_TEXTURE(c, d) texture(c, d)
|
||||||
|
|
||||||
|
#pragma stage vertex
|
||||||
|
layout(location = 0) in vec4 Position;
|
||||||
|
layout(location = 1) in vec2 TexCoord;
|
||||||
|
layout(location = 0) out vec2 vTexCoord;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = global.MVP * Position;
|
||||||
|
vTexCoord = TexCoord * vec2(1.00001); // To resolve rounding issues when sampling
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma stage fragment
|
||||||
|
layout(location = 0) in vec2 vTexCoord;
|
||||||
|
layout(location = 0) out vec4 FragColor;
|
||||||
|
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||||
|
|
||||||
|
#include "include/inverse_tonemap.h"
|
||||||
|
|
||||||
|
vec3 InverseTonemapConditional(const vec3 linear)
|
||||||
|
{
|
||||||
|
if(HCRT_HDR > 0.0f)
|
||||||
|
{
|
||||||
|
return linear;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return InverseTonemap(linear, HCRT_MAX_NITS, HCRT_PAPER_WHITE_NITS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec3 source = COMPAT_TEXTURE(Source, vTexCoord).rgb;
|
||||||
|
|
||||||
|
const vec3 hdr_colour = InverseTonemapConditional(source);
|
||||||
|
|
||||||
|
FragColor = vec4(hdr_colour, 1.0);
|
||||||
|
}
|
86
hdr/shaders/crt-sony-megatron-source-pass.slang
Normal file
86
hdr/shaders/crt-sony-megatron-source-pass.slang
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
/*
|
||||||
|
A shader that tries to emulate a sony PVM type aperture grille screen but with full brightness.
|
||||||
|
|
||||||
|
The novel thing about this shader is that it relies on the HDR shaders to brighten up the image so that when
|
||||||
|
we apply this shader which emulates the apperture grille the resulting screen isn't left too dark.
|
||||||
|
|
||||||
|
I think you need at least a DisplayHDR 600 monitor but to get close to CRT levels of brightness I think DisplayHDR 1000.
|
||||||
|
|
||||||
|
Please Enable HDR in RetroArch 1.10+
|
||||||
|
|
||||||
|
NOTE: when this shader is envoked the Contrast, Peak Luminance and Paper White Luminance in the HDR menu do nothing instead set those values through the shader parameters
|
||||||
|
|
||||||
|
For this shader set Paper White Luminance to above 700 and Peak Luminance to the peak luminance of your monitor.
|
||||||
|
|
||||||
|
Also try to use a integer scaling - its just better - overscaling is fine.
|
||||||
|
|
||||||
|
This shader doesn't do any geometry warping or bouncing of light around inside the screen etc - I think these effects just add unwanted noise, I know people disagree. Please feel free to make you own and add them
|
||||||
|
|
||||||
|
Dont use this shader directly - use the hdr\crt-make-model-hdr.slangp where make and model are the make and model of the CRT you want.
|
||||||
|
|
||||||
|
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)
|
||||||
|
*/
|
||||||
|
|
||||||
|
layout(push_constant) uniform Push
|
||||||
|
{
|
||||||
|
float hcrt_max_nits;
|
||||||
|
float hcrt_paper_white_nits;
|
||||||
|
float hcrt_lcd_resolution;
|
||||||
|
float hcrt_lcd_subpixel;
|
||||||
|
float hcrt_colour_system;
|
||||||
|
float hcrt_expand_gamut;
|
||||||
|
float hcrt_white_temperature;
|
||||||
|
float hcrt_brightness;
|
||||||
|
float hcrt_contrast;
|
||||||
|
float hcrt_saturation;
|
||||||
|
float hcrt_gamma;
|
||||||
|
} params;
|
||||||
|
|
||||||
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
{
|
||||||
|
mat4 MVP;
|
||||||
|
vec4 SourceSize;
|
||||||
|
vec4 OriginalSize;
|
||||||
|
vec4 OutputSize;
|
||||||
|
uint FrameCount;
|
||||||
|
} global;
|
||||||
|
|
||||||
|
#include "include/parameters.h"
|
||||||
|
|
||||||
|
#define HCRT_CRT_COLOUR_SYSTEM params.hcrt_colour_system
|
||||||
|
#define HCRT_WHITE_TEMPERATURE params.hcrt_white_temperature
|
||||||
|
#define HCRT_BRIGHTNESS params.hcrt_brightness
|
||||||
|
#define HCRT_CONTRAST params.hcrt_contrast
|
||||||
|
#define HCRT_SATURATION params.hcrt_saturation
|
||||||
|
#define HCRT_GAMMA params.hcrt_gamma
|
||||||
|
|
||||||
|
#define COMPAT_TEXTURE(c, d) texture(c, d)
|
||||||
|
|
||||||
|
#pragma stage vertex
|
||||||
|
layout(location = 0) in vec4 Position;
|
||||||
|
layout(location = 1) in vec2 TexCoord;
|
||||||
|
layout(location = 0) out vec2 vTexCoord;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = global.MVP * Position;
|
||||||
|
vTexCoord = TexCoord * vec2(1.00001); // To resolve rounding issues when sampling
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma stage fragment
|
||||||
|
layout(location = 0) in vec2 vTexCoord;
|
||||||
|
layout(location = 0) out vec4 FragColor;
|
||||||
|
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||||
|
|
||||||
|
#include "include/colour_grade.h"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec3 source = COMPAT_TEXTURE(Source, vTexCoord).rgb;
|
||||||
|
|
||||||
|
const vec3 colour = ColourGrade(source);
|
||||||
|
|
||||||
|
FragColor = vec4(colour, 1.0);
|
||||||
|
}
|
|
@ -29,13 +29,15 @@ layout(push_constant) uniform Push
|
||||||
{
|
{
|
||||||
// User Settings
|
// User Settings
|
||||||
float hcrt_hdr;
|
float hcrt_hdr;
|
||||||
|
float hcrt_colour_space;
|
||||||
float hcrt_max_nits;
|
float hcrt_max_nits;
|
||||||
float hcrt_paper_white_nits;
|
float hcrt_paper_white_nits;
|
||||||
|
float hcrt_expand_gamut;
|
||||||
|
float hcrt_gamma;
|
||||||
|
|
||||||
float hcrt_lcd_resolution;
|
float hcrt_lcd_resolution;
|
||||||
float hcrt_lcd_subpixel;
|
float hcrt_lcd_subpixel;
|
||||||
float hcrt_colour_system;
|
|
||||||
float hcrt_colour_space;
|
|
||||||
float hcrt_expand_gamut;
|
|
||||||
float hcrt_red_vertical_convergence;
|
float hcrt_red_vertical_convergence;
|
||||||
float hcrt_green_vertical_convergence;
|
float hcrt_green_vertical_convergence;
|
||||||
float hcrt_blue_vertical_convergence;
|
float hcrt_blue_vertical_convergence;
|
||||||
|
@ -75,78 +77,19 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
vec4 OriginalSize;
|
vec4 OriginalSize;
|
||||||
vec4 OutputSize;
|
vec4 OutputSize;
|
||||||
uint FrameCount;
|
uint FrameCount;
|
||||||
|
|
||||||
float hcrt_white_temperature;
|
|
||||||
float hcrt_brightness;
|
|
||||||
float hcrt_contrast;
|
|
||||||
float hcrt_saturation;
|
|
||||||
float hcrt_gamma;
|
|
||||||
} global;
|
} global;
|
||||||
|
|
||||||
|
#include "include/parameters.h"
|
||||||
#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_support0 "SUPPORTED: RGB/BGR LCD, QD-OLED Displays" 0.0 0.0 0.0001 0.0
|
|
||||||
#pragma parameter hcrt_support1 "NOT SUPPORTED: WRGB OLED Displays" 0.0 0.0 0.0001 0.0
|
|
||||||
#pragma parameter hcrt_support2 "MIN SPEC: DisplayHDR 600, 4K, RetroArch v1.10" 0.0 0.0 0.0001 0.0
|
|
||||||
#pragma parameter hcrt_support3 "REC SPEC: DisplayHDR 1000, 4K+, RetroArch v1.10" 0.0 0.0 0.0001 0.0
|
|
||||||
#pragma parameter hcrt_space1 " " 0.0 0.0 0.0001 0.0
|
|
||||||
#pragma parameter hcrt_instructions0 "HDR: Enable HDR: On" 0.0 0.0 0.0001 0.0
|
|
||||||
#pragma parameter hcrt_instructions1 "SCALING: Integer Scale: ON" 0.0 0.0 0.0001 0.0
|
|
||||||
#pragma parameter hcrt_instructions2 "SCALING: Integer Overscale: ON" 0.0 0.0 0.0001 0.0
|
|
||||||
#pragma parameter hcrt_instructions3 "SCALING: Apect Ratio: Core Provided" 0.0 0.0 0.0001 0.0
|
|
||||||
#pragma parameter hcrt_space2 " " 0.0 0.0 0.0001 0.0
|
|
||||||
#pragma parameter hcrt_user_settings "USER SETTINGS:" 0.0 0.0 0.0001 0.0
|
|
||||||
#pragma parameter hcrt_hdr " HDR | SDR" 0.0 0.0 1.0 1.0
|
|
||||||
#pragma parameter hcrt_max_nits " HDR: Display's Peak Luminance" 700.0 0.0 10000.0 10.0
|
|
||||||
#pragma parameter hcrt_paper_white_nits " HDR: Display's Paper White Luminance" 700.0 0.0 10000.0 10.0
|
|
||||||
#pragma parameter hcrt_colour_space " SDR: Display's Colour Space: sRGB | DCI-P3" 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_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_blue_vertical_convergence " Blue Vertical Convergence" 0.00 -10.0 10.0 0.01
|
|
||||||
#pragma parameter hcrt_red_horizontal_convergence " Red Horizontal Convergence" 0.00 -10.0 10.0 0.01
|
|
||||||
#pragma parameter hcrt_green_horizontal_convergence " Green Horizontal Convergence" 0.00 -10.0 10.0 0.01
|
|
||||||
#pragma parameter hcrt_blue_horizontal_convergence " Blue Horizontal Convergence" 0.00 -10.0 10.0 0.01
|
|
||||||
|
|
||||||
#pragma parameter hcrt_space3 " " 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_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_white_temperature " White Point: (PAL:D65, NTSC-U:D65, NTSC-J:D93)" 0.0 -5000.0 12000.0 100.0
|
|
||||||
#pragma parameter hcrt_expand_gamut " HDR: Original/Vivid" 0.0 0.0 1.0 1.0
|
|
||||||
#pragma parameter hcrt_brightness " Brightness" 0.0 -1.0 1.0 0.01
|
|
||||||
#pragma parameter hcrt_contrast " Contrast" 0.0 -1.0 1.0 0.01
|
|
||||||
#pragma parameter hcrt_saturation " Saturation" 0.0 -1.0 1.0 0.01
|
|
||||||
#pragma parameter hcrt_gamma " Gamma" 0.0 -1.0 1.0 0.01
|
|
||||||
|
|
||||||
#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_max " Red Scanline Max" 1.00 0.0 2.0 0.01
|
|
||||||
#pragma parameter hcrt_red_scanline_attack " Red Scanline Attack" 0.20 0.0 1.0 0.01
|
|
||||||
#pragma parameter hcrt_green_scanline_min " Green Scanline Min" 0.50 0.0 2.0 0.01
|
|
||||||
#pragma parameter hcrt_green_scanline_max " Green Scanline Max" 1.00 0.0 2.0 0.01
|
|
||||||
#pragma parameter hcrt_green_scanline_attack " Green Scanline Attack" 0.20 0.0 1.0 0.01
|
|
||||||
#pragma parameter hcrt_blue_scanline_min " Blue Scanline Min" 0.50 0.0 2.0 0.01
|
|
||||||
#pragma parameter hcrt_blue_scanline_max " Blue Scanline Max" 1.00 0.0 2.0 0.01
|
|
||||||
#pragma parameter hcrt_blue_scanline_attack " Blue Scanline Attack" 0.20 0.0 1.0 0.01
|
|
||||||
#pragma parameter hcrt_developer_settings1 " HORIZONTAL SETTINGS:" 0.0 0.0 0.0001 0.0
|
|
||||||
#pragma parameter hcrt_red_beam_sharpness " Red Beam Sharpness" 1.75 0.0 5.0 0.05
|
|
||||||
#pragma parameter hcrt_red_beam_attack " Red Beam Attack" 0.50 0.0 2.0 0.01
|
|
||||||
#pragma parameter hcrt_green_beam_sharpness " Green Beam Sharpness" 1.75 0.0 5.0 0.05
|
|
||||||
#pragma parameter hcrt_green_beam_attack " Green Beam Attack" 0.50 0.0 2.0 0.01
|
|
||||||
#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
|
|
||||||
|
|
||||||
|
|
||||||
#define HCRT_HDR params.hcrt_hdr
|
#define HCRT_HDR params.hcrt_hdr
|
||||||
|
#define HCRT_OUTPUT_COLOUR_SPACE params.hcrt_colour_space
|
||||||
#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 HCRT_GAMMA params.hcrt_gamma
|
||||||
|
|
||||||
#define HCRT_LCD_RESOLUTION params.hcrt_lcd_resolution
|
#define HCRT_LCD_RESOLUTION params.hcrt_lcd_resolution
|
||||||
#define HCRT_LCD_SUBPIXEL params.hcrt_lcd_subpixel
|
#define HCRT_LCD_SUBPIXEL params.hcrt_lcd_subpixel
|
||||||
#define HCRT_EXPAND_GAMUT params.hcrt_expand_gamut
|
|
||||||
#define HCRT_RED_VERTICAL_CONVERGENCE params.hcrt_red_vertical_convergence
|
#define HCRT_RED_VERTICAL_CONVERGENCE params.hcrt_red_vertical_convergence
|
||||||
#define HCRT_GREEN_VERTICAL_CONVERGENCE params.hcrt_green_vertical_convergence
|
#define HCRT_GREEN_VERTICAL_CONVERGENCE params.hcrt_green_vertical_convergence
|
||||||
#define HCRT_BLUE_VERTICAL_CONVERGENCE params.hcrt_blue_vertical_convergence
|
#define HCRT_BLUE_VERTICAL_CONVERGENCE params.hcrt_blue_vertical_convergence
|
||||||
|
@ -156,13 +99,6 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
|
||||||
#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_SYSTEM params.hcrt_colour_system
|
|
||||||
#define HCRT_OUTPUT_COLOUR_SPACE params.hcrt_colour_space
|
|
||||||
#define HCRT_WHITE_TEMPERATURE global.hcrt_white_temperature
|
|
||||||
#define HCRT_BRIGHTNESS global.hcrt_brightness
|
|
||||||
#define HCRT_CONTRAST global.hcrt_contrast
|
|
||||||
#define HCRT_SATURATION global.hcrt_saturation
|
|
||||||
#define HCRT_GAMMA global.hcrt_gamma
|
|
||||||
|
|
||||||
#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
|
||||||
|
@ -197,16 +133,31 @@ void main()
|
||||||
#pragma stage fragment
|
#pragma stage fragment
|
||||||
layout(location = 0) in vec2 vTexCoord;
|
layout(location = 0) in vec2 vTexCoord;
|
||||||
layout(location = 0) out vec4 FragColor;
|
layout(location = 0) out vec4 FragColor;
|
||||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
layout(set = 0, binding = 2) uniform sampler2D SourceSDR;
|
||||||
|
layout(set = 0, binding = 3) uniform sampler2D SourceHDR;
|
||||||
|
|
||||||
#define kRed vec3(1.0, 0.0, 0.0)
|
|
||||||
#define kGreen vec3(0.0, 1.0, 0.0)
|
#define kChannelMask 3
|
||||||
#define kBlue vec3(0.0, 0.0, 1.0)
|
#define kFirstChannelShift 2
|
||||||
#define kMagenta vec3(1.0, 0.0, 1.0)
|
#define kSecondChannelShift 4
|
||||||
#define kYellow vec3(1.0, 1.0, 0.0)
|
|
||||||
#define kCyan vec3(0.0, 1.0, 1.0)
|
#define kRedId 0
|
||||||
#define kBlack vec3(0.0, 0.0, 0.0)
|
#define kGreenId 1
|
||||||
#define kWhite vec3(1.0, 1.0, 1.0)
|
#define kBlueId 2
|
||||||
|
|
||||||
|
#define kRed (1 | (kRedId << kFirstChannelShift))
|
||||||
|
#define kGreen (1 | (kGreenId << kFirstChannelShift))
|
||||||
|
#define kBlue (1 | (kBlueId << kFirstChannelShift))
|
||||||
|
#define kMagenta (2 | (kRedId << kFirstChannelShift) | (kBlueId << kSecondChannelShift))
|
||||||
|
#define kYellow (2 | (kRedId << kFirstChannelShift) | (kGreenId << kSecondChannelShift))
|
||||||
|
#define kCyan (2 | (kGreenId << kFirstChannelShift) | (kBlueId << kSecondChannelShift))
|
||||||
|
#define kBlack 0
|
||||||
|
|
||||||
|
#define kRedChannel vec3(1.0, 0.0, 0.0)
|
||||||
|
#define kGreenChannel vec3(0.0, 1.0, 0.0)
|
||||||
|
#define kBlueChannel vec3(0.0, 0.0, 1.0)
|
||||||
|
|
||||||
|
const vec3 kColourMask[3] = { kRedChannel, kGreenChannel, kBlueChannel };
|
||||||
|
|
||||||
#define kApertureGrille 0
|
#define kApertureGrille 0
|
||||||
#define kShadowMask 1
|
#define kShadowMask 1
|
||||||
|
@ -237,7 +188,7 @@ layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||||
|
|
||||||
const uint kApertureGrilleMaskSize[kResolutionAxis][kTVLAxis] = { { 4, 3, 2 }, { 7, 5, 4 } }; //4K: 600 TVL, 800 TVL, 1000 TVL 8K: 600 TVL, 800 TVL, 1000 TVL
|
const uint kApertureGrilleMaskSize[kResolutionAxis][kTVLAxis] = { { 4, 3, 2 }, { 7, 5, 4 } }; //4K: 600 TVL, 800 TVL, 1000 TVL 8K: 600 TVL, 800 TVL, 1000 TVL
|
||||||
|
|
||||||
const vec3 kApertureGrilleMasks[kResolutionAxis][kTVLAxis][kBGRAxis][kMaxApertureGrilleSize] = {
|
const uint kApertureGrilleMasks[kResolutionAxis][kTVLAxis][kBGRAxis][kMaxApertureGrilleSize] = {
|
||||||
{ // 4K
|
{ // 4K
|
||||||
{ kRGBX, kBGRX }, // 600 TVL
|
{ kRGBX, kBGRX }, // 600 TVL
|
||||||
{ kBGR, kRGB }, // 800 TVL
|
{ kBGR, kRGB }, // 800 TVL
|
||||||
|
@ -296,7 +247,7 @@ const vec3 kApertureGrilleMasks[kResolutionAxis][kTVLAxis][kBGRAxis][kMaxApertur
|
||||||
const uint kShadowMaskSizeX[kResolutionAxis][kTVLAxis] = { { 6, 2, 2 }, { 12, 6, 6 } };
|
const uint kShadowMaskSizeX[kResolutionAxis][kTVLAxis] = { { 6, 2, 2 }, { 12, 6, 6 } };
|
||||||
const uint kShadowMaskSizeY[kResolutionAxis][kTVLAxis] = { { 4, 2, 2 }, { 8, 4, 4 } };
|
const uint kShadowMaskSizeY[kResolutionAxis][kTVLAxis] = { { 4, 2, 2 }, { 8, 4, 4 } };
|
||||||
|
|
||||||
const vec3 kShadowMasks[kResolutionAxis][kTVLAxis][kBGRAxis][kMaxShadowMaskSizeY][kMaxShadowMaskSizeX] = {
|
const uint kShadowMasks[kResolutionAxis][kTVLAxis][kBGRAxis][kMaxShadowMaskSizeY][kMaxShadowMaskSizeX] = {
|
||||||
{ // 4K
|
{ // 4K
|
||||||
{ kGRRBBG_GRRBBG_BBGGRR_BBGGRR, kGBBRRG_GBBRRG_RRGGBB_RRGGBB }, // 600 TVL
|
{ kGRRBBG_GRRBBG_BBGGRR_BBGGRR, kGBBRRG_GBBRRG_RRGGBB_RRGGBB }, // 600 TVL
|
||||||
{ kMG_GM, kGM_MG }, // 800 TVL
|
{ kMG_GM, kGM_MG }, // 800 TVL
|
||||||
|
@ -362,7 +313,7 @@ const vec3 kShadowMasks[kResolutionAxis][kTVLAxis][kBGRAxis][kMaxShadowMaskSizeY
|
||||||
|
|
||||||
const uint kSlotMaskSize[kResolutionAxis][kTVLAxis] = { { 4, 3, 2 }, { 7, 5, 4 } }; //4K: 600 TVL, 800 TVL, 1000 TVL 8K: 600 TVL, 800 TVL, 1000 TVL
|
const uint kSlotMaskSize[kResolutionAxis][kTVLAxis] = { { 4, 3, 2 }, { 7, 5, 4 } }; //4K: 600 TVL, 800 TVL, 1000 TVL 8K: 600 TVL, 800 TVL, 1000 TVL
|
||||||
|
|
||||||
const vec3 kSlotMasks[kResolutionAxis][kTVLAxis][kBGRAxis][kMaxSlotSizeY][kMaxSlotSizeX][kMaxSlotMaskSize] = {
|
const uint kSlotMasks[kResolutionAxis][kTVLAxis][kBGRAxis][kMaxSlotSizeY][kMaxSlotSizeX][kMaxSlotMaskSize] = {
|
||||||
{ // 4K
|
{ // 4K
|
||||||
{ kRGBXRGBX_RGBXXXXX_RGBXRGBX_XXXXRGBX, kBGRXBGRX_BGRXXXXX_BGRXBGRX_XXXXBGRX }, // 600 TVL
|
{ kRGBXRGBX_RGBXXXXX_RGBXRGBX_XXXXRGBX, kBGRXBGRX_BGRXXXXX_BGRXBGRX_XXXXBGRX }, // 600 TVL
|
||||||
{ kBGRBGR_BGRXXX_BGRBGR_XXXBGR, kRGBRGB_RGBXXX_RGBRGB_XXXRGB }, // 800 TVL
|
{ kBGRBGR_BGRXXX_BGRBGR_XXXBGR, kRGBRGB_RGBXXX_RGBRGB_XXXRGB }, // 800 TVL
|
||||||
|
@ -393,16 +344,8 @@ 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,
|
#include "include/scanline_generation.h"
|
||||||
-3.0f, 3.0f, 0.0f, 0.0f,
|
#include "include/hdr10.h"
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// SDR Colour output spaces
|
// SDR Colour output spaces
|
||||||
float sRGBToLinear_1(const float channel)
|
float sRGBToLinear_1(const float channel)
|
||||||
|
@ -430,11 +373,6 @@ vec3 LinearToDCIP3(const vec3 colour)
|
||||||
return pow(colour, vec3(1.0f / 2.6f));
|
return pow(colour, vec3(1.0f / 2.6f));
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "include\hdr10.h"
|
|
||||||
#include "include\inverse_tonemap.h"
|
|
||||||
#include "include\colour_grade.h"
|
|
||||||
#include "include\scanline_generation.h"
|
|
||||||
|
|
||||||
vec3 GammaCorrect(const vec3 scanline_colour)
|
vec3 GammaCorrect(const vec3 scanline_colour)
|
||||||
{
|
{
|
||||||
if(HCRT_HDR > 0.0f)
|
if(HCRT_HDR > 0.0f)
|
||||||
|
@ -449,9 +387,6 @@ vec3 GammaCorrect(const vec3 scanline_colour)
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
const float scanline_size = global.OutputSize.y / global.SourceSize.y;
|
|
||||||
vec3 scanline_colour = GenerateScanline(global.SourceSize.xy, scanline_size);
|
|
||||||
|
|
||||||
const uint screen_type = uint(HCRT_CRT_SCREEN_TYPE);
|
const uint screen_type = uint(HCRT_CRT_SCREEN_TYPE);
|
||||||
const uint crt_resolution = uint(HCRT_CRT_RESOLUTION);
|
const uint crt_resolution = uint(HCRT_CRT_RESOLUTION);
|
||||||
const uint lcd_resolution = uint(HCRT_LCD_RESOLUTION);
|
const uint lcd_resolution = uint(HCRT_LCD_RESOLUTION);
|
||||||
|
@ -459,13 +394,15 @@ void main()
|
||||||
|
|
||||||
const vec2 current_position = vTexCoord * global.OutputSize.xy;
|
const vec2 current_position = vTexCoord * global.OutputSize.xy;
|
||||||
|
|
||||||
|
uint colour_mask;
|
||||||
|
|
||||||
switch(screen_type)
|
switch(screen_type)
|
||||||
{
|
{
|
||||||
case kApertureGrille:
|
case kApertureGrille:
|
||||||
{
|
{
|
||||||
uint mask = uint(ModInteger(floor(current_position.x), kApertureGrilleMaskSize[lcd_resolution][crt_resolution]));
|
uint mask = uint(ModInteger(floor(current_position.x), kApertureGrilleMaskSize[lcd_resolution][crt_resolution]));
|
||||||
|
|
||||||
scanline_colour *= kApertureGrilleMasks[lcd_resolution][crt_resolution][lcd_subpixel_layout][mask];
|
colour_mask = kApertureGrilleMasks[lcd_resolution][crt_resolution][lcd_subpixel_layout][mask];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -475,7 +412,7 @@ void main()
|
||||||
|
|
||||||
uint mask = uint(ModInteger(floor(current_position.x), kShadowMaskSizeX[lcd_resolution][crt_resolution]));
|
uint mask = uint(ModInteger(floor(current_position.x), kShadowMaskSizeX[lcd_resolution][crt_resolution]));
|
||||||
|
|
||||||
scanline_colour *= kShadowMasks[lcd_resolution][crt_resolution][lcd_subpixel_layout][shadow_y][mask];
|
colour_mask = kShadowMasks[lcd_resolution][crt_resolution][lcd_subpixel_layout][shadow_y][mask];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -486,7 +423,7 @@ void main()
|
||||||
|
|
||||||
uint mask = uint(ModInteger(floor(current_position.x), kSlotMaskSize[lcd_resolution][crt_resolution]));
|
uint mask = uint(ModInteger(floor(current_position.x), kSlotMaskSize[lcd_resolution][crt_resolution]));
|
||||||
|
|
||||||
scanline_colour *= kSlotMasks[lcd_resolution][crt_resolution][lcd_subpixel_layout][slot_x][slot_y][mask];
|
colour_mask = kSlotMasks[lcd_resolution][crt_resolution][lcd_subpixel_layout][slot_x][slot_y][mask];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -496,7 +433,57 @@ void main()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const float scanline_size = global.OutputSize.y / global.SourceSize.y;
|
||||||
|
|
||||||
|
const vec3 horizontal_convergence = vec3(HCRT_RED_HORIZONTAL_CONVERGENCE, HCRT_GREEN_HORIZONTAL_CONVERGENCE, HCRT_BLUE_HORIZONTAL_CONVERGENCE);
|
||||||
|
const vec3 vertical_convergence = vec3(HCRT_RED_VERTICAL_CONVERGENCE, HCRT_GREEN_VERTICAL_CONVERGENCE, HCRT_BLUE_VERTICAL_CONVERGENCE);
|
||||||
|
const vec3 beam_sharpness = vec3(HCRT_RED_BEAM_SHARPNESS, HCRT_GREEN_BEAM_SHARPNESS, HCRT_BLUE_BEAM_SHARPNESS);
|
||||||
|
const vec3 beam_attack = vec3(HCRT_RED_BEAM_ATTACK, HCRT_GREEN_BEAM_ATTACK, HCRT_BLUE_BEAM_ATTACK);
|
||||||
|
const vec3 scanline_min = vec3(HCRT_RED_SCANLINE_MIN, HCRT_GREEN_SCANLINE_MIN, HCRT_BLUE_SCANLINE_MIN);
|
||||||
|
const vec3 scanline_max = vec3(HCRT_RED_SCANLINE_MAX, HCRT_GREEN_SCANLINE_MAX, HCRT_BLUE_SCANLINE_MAX);
|
||||||
|
const vec3 scanline_attack = vec3(HCRT_RED_SCANLINE_ATTACK, HCRT_GREEN_SCANLINE_ATTACK, HCRT_BLUE_SCANLINE_ATTACK);
|
||||||
|
|
||||||
|
const uint channel_count = colour_mask & 3;
|
||||||
|
|
||||||
|
vec3 scanline_colour = vec3(0.0f);
|
||||||
|
|
||||||
|
if(channel_count > 0)
|
||||||
|
{
|
||||||
|
const uint channel_0 = (colour_mask >> 2) & 3;
|
||||||
|
|
||||||
|
const float scanline_channel_0 = GenerateScanline(channel_0,
|
||||||
|
global.SourceSize.xy,
|
||||||
|
scanline_size,
|
||||||
|
horizontal_convergence[channel_0],
|
||||||
|
vertical_convergence[channel_0],
|
||||||
|
beam_sharpness[channel_0],
|
||||||
|
beam_attack[channel_0],
|
||||||
|
scanline_min[channel_0],
|
||||||
|
scanline_max[channel_0],
|
||||||
|
scanline_attack[channel_0]);
|
||||||
|
|
||||||
|
scanline_colour = scanline_channel_0 * kColourMask[channel_0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(channel_count > 1)
|
||||||
|
{
|
||||||
|
const uint channel_1 = (colour_mask >> 4) & 3;
|
||||||
|
|
||||||
|
const float scanline_channel_1 = GenerateScanline(channel_1,
|
||||||
|
global.SourceSize.xy,
|
||||||
|
scanline_size,
|
||||||
|
horizontal_convergence[channel_1],
|
||||||
|
vertical_convergence[channel_1],
|
||||||
|
beam_sharpness[channel_1],
|
||||||
|
beam_attack[channel_1],
|
||||||
|
scanline_min[channel_1],
|
||||||
|
scanline_max[channel_1],
|
||||||
|
scanline_attack[channel_1]);
|
||||||
|
|
||||||
|
scanline_colour += scanline_channel_1 * kColourMask[channel_1];
|
||||||
|
}
|
||||||
|
|
||||||
const vec3 hdr10 = GammaCorrect(scanline_colour);
|
const vec3 hdr10 = GammaCorrect(scanline_colour);
|
||||||
|
|
||||||
FragColor = vec4(hdr10, 1.0);
|
FragColor = vec4(hdr10, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,17 @@ const mat3 kCoolTemperature = mat3(
|
||||||
vec3(-2666.3474220535695, -2173.1012343082230, 2575.2827530017594),
|
vec3(-2666.3474220535695, -2173.1012343082230, 2575.2827530017594),
|
||||||
vec3( 0.55995389139931482, 0.70381203140554553, 1.8993753891711275));
|
vec3( 0.55995389139931482, 0.70381203140554553, 1.8993753891711275));
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
vec3 WhiteBalance(float temperature, vec3 colour)
|
vec3 WhiteBalance(float temperature, vec3 colour)
|
||||||
{
|
{
|
||||||
const mat3 m = (temperature < kD65) ? kWarmTemperature : kCoolTemperature;
|
const mat3 m = (temperature < kD65) ? kWarmTemperature : kCoolTemperature;
|
||||||
|
@ -95,6 +106,32 @@ vec3 LinearTor601r709(const vec3 colour)
|
||||||
return vec3(LinearTor601r709_1(colour.r), LinearTor601r709_1(colour.g), LinearTor601r709_1(colour.b));
|
return vec3(LinearTor601r709_1(colour.r), LinearTor601r709_1(colour.g), LinearTor601r709_1(colour.b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SDR Colour output spaces
|
||||||
|
float sRGBToLinear_1(const float channel)
|
||||||
|
{
|
||||||
|
return (channel > 0.04045f) ? pow((channel + 0.055f) * (1.0f / 1.055f), 2.4f + HCRT_GAMMA) : channel * (1.0f / 12.92f);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 sRGBToLinear(const vec3 colour)
|
||||||
|
{
|
||||||
|
return vec3(sRGBToLinear_1(colour.r), sRGBToLinear_1(colour.g), sRGBToLinear_1(colour.b));
|
||||||
|
}
|
||||||
|
|
||||||
|
float LinearTosRGB_1(const float channel)
|
||||||
|
{
|
||||||
|
return (channel > 0.0031308f) ? (1.055f * pow(channel, 1.0f / 2.4f)) - 0.055f : channel * 12.92f;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 LinearTosRGB(const vec3 colour)
|
||||||
|
{
|
||||||
|
return vec3(LinearTosRGB_1(colour.r), LinearTosRGB_1(colour.g), LinearTosRGB_1(colour.b));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 LinearToDCIP3(const vec3 colour)
|
||||||
|
{
|
||||||
|
return pow(colour, vec3(1.0f / 2.6f));
|
||||||
|
}
|
||||||
|
|
||||||
// XYZ Yxy transforms found in Dogway's Grade.slang shader
|
// XYZ Yxy transforms found in Dogway's Grade.slang shader
|
||||||
|
|
||||||
vec3 XYZtoYxy(const vec3 XYZ)
|
vec3 XYZtoYxy(const vec3 XYZ)
|
||||||
|
@ -153,12 +190,8 @@ vec3 Saturation(const vec3 colour)
|
||||||
return clamp(mix(vec3(luma), colour, vec3(saturation) * 2.0f), 0.0f, 1.0f);
|
return clamp(mix(vec3(luma), colour, vec3(saturation) * 2.0f), 0.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 ColourGrade(const vec3 colour)
|
vec3 BrightnessContrastSaturation(const vec3 linear)
|
||||||
{
|
{
|
||||||
const uint colour_system = uint(HCRT_CRT_COLOUR_SYSTEM);
|
|
||||||
|
|
||||||
const vec3 linear = r601r709ToLinear(colour);
|
|
||||||
|
|
||||||
const vec3 xyz = sRGB_to_XYZ * linear;
|
const vec3 xyz = sRGB_to_XYZ * linear;
|
||||||
const vec3 Yxy = XYZtoYxy(xyz);
|
const vec3 Yxy = XYZtoYxy(xyz);
|
||||||
const float Y_gamma = clamp(LinearTosRGB_1(Yxy.x), 0.0f, 1.0f);
|
const float Y_gamma = clamp(LinearTosRGB_1(Yxy.x), 0.0f, 1.0f);
|
||||||
|
@ -173,7 +206,18 @@ vec3 ColourGrade(const vec3 colour)
|
||||||
|
|
||||||
const vec3 saturation = Saturation(contrast);
|
const vec3 saturation = Saturation(contrast);
|
||||||
|
|
||||||
const vec3 gamut = kPhosphorGamut[colour_system] * saturation;
|
return saturation;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 ColourGrade(const vec3 colour)
|
||||||
|
{
|
||||||
|
const uint colour_system = uint(HCRT_CRT_COLOUR_SYSTEM);
|
||||||
|
|
||||||
|
const vec3 linear = r601r709ToLinear(colour);
|
||||||
|
|
||||||
|
const vec3 graded = BrightnessContrastSaturation(linear);
|
||||||
|
|
||||||
|
const vec3 gamut = kPhosphorGamut[colour_system] * graded;
|
||||||
|
|
||||||
const vec3 white_point = WhiteBalance(kTemperatures[colour_system] + HCRT_WHITE_TEMPERATURE, gamut);
|
const vec3 white_point = WhiteBalance(kTemperatures[colour_system] + HCRT_WHITE_TEMPERATURE, gamut);
|
||||||
|
|
||||||
|
|
|
@ -2,29 +2,20 @@
|
||||||
#define kMaxNitsFor2084 10000.0f
|
#define kMaxNitsFor2084 10000.0f
|
||||||
#define kEpsilon 0.0001f
|
#define kEpsilon 0.0001f
|
||||||
|
|
||||||
vec3 InverseTonemap(vec3 sdr_linear, float max_nits, float paper_white_nits, float luma_ratio)
|
vec3 InverseTonemap(const vec3 sdr_linear, const float max_nits, const float paper_white_nits)
|
||||||
{
|
{
|
||||||
float luma = dot(sdr_linear, vec3(0.2126, 0.7152, 0.0722)); /* Rec BT.709 luma coefficients - https://en.wikipedia.org/wiki/Luma_(video) */
|
const float luma = dot(sdr_linear, vec3(0.2126, 0.7152, 0.0722)); /* Rec BT.709 luma coefficients - https://en.wikipedia.org/wiki/Luma_(video) */
|
||||||
|
|
||||||
/* Inverse reinhard tonemap */
|
/* Inverse reinhard tonemap */
|
||||||
float max_value = (max_nits / paper_white_nits) + kEpsilon;
|
const float max_value = (max_nits / paper_white_nits) + kEpsilon;
|
||||||
float elbow = max_value / (max_value - 1.0f);
|
const float elbow = max_value / (max_value - 1.0f);
|
||||||
float offset = 1.0f - ((0.5f * elbow) / (elbow - 0.5f));
|
const float offset = 1.0f - ((0.5f * elbow) / (elbow - 0.5f));
|
||||||
|
|
||||||
float hdr_luma_inv_tonemap = offset + ((luma * elbow) / (elbow - luma));
|
const float hdr_luma_inv_tonemap = offset + ((luma * elbow) / (elbow - luma));
|
||||||
float sdr_luma_inv_tonemap = luma / ((1.0f + kEpsilon) - luma); /* Convert the srd < 0.5 to 0.0 -> 1.0 range */
|
const float sdr_luma_inv_tonemap = luma / ((1.0f + kEpsilon) - luma); /* Convert the srd < 0.5 to 0.0 -> 1.0 range */
|
||||||
|
|
||||||
float luma_inv_tonemap = (luma > 0.5f) ? hdr_luma_inv_tonemap : sdr_luma_inv_tonemap;
|
const float luma_inv_tonemap = (luma > 0.5f) ? hdr_luma_inv_tonemap : sdr_luma_inv_tonemap;
|
||||||
vec3 per_luma = sdr_linear / (luma + kEpsilon) * luma_inv_tonemap;
|
const vec3 hdr = sdr_linear / (luma + kEpsilon) * luma_inv_tonemap;
|
||||||
|
|
||||||
vec3 hdr_inv_tonemap = offset + ((sdr_linear * elbow) / (elbow - sdr_linear));
|
|
||||||
vec3 sdr_inv_tonemap = sdr_linear / ((1.0f + kEpsilon) - sdr_linear); /* Convert the srd < 0.5 to 0.0 -> 1.0 range */
|
|
||||||
|
|
||||||
vec3 per_channel = vec3(sdr_linear.x > 0.5f ? hdr_inv_tonemap.x : sdr_inv_tonemap.x,
|
|
||||||
sdr_linear.y > 0.5f ? hdr_inv_tonemap.y : sdr_inv_tonemap.y,
|
|
||||||
sdr_linear.z > 0.5f ? hdr_inv_tonemap.z : sdr_inv_tonemap.z);
|
|
||||||
|
|
||||||
vec3 hdr = mix(per_luma, per_channel, vec3(luma_ratio));
|
|
||||||
|
|
||||||
return hdr;
|
return hdr;
|
||||||
}
|
}
|
||||||
|
|
59
hdr/shaders/include/parameters.h
Normal file
59
hdr/shaders/include/parameters.h
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
|
||||||
|
|
||||||
|
#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_support0 "SUPPORTED: RGB/BGR LCD, QD-OLED Displays" 0.0 0.0 0.0001 0.0
|
||||||
|
#pragma parameter hcrt_support1 "NOT SUPPORTED: WRGB OLED Displays" 0.0 0.0 0.0001 0.0
|
||||||
|
#pragma parameter hcrt_support2 "MIN SPEC: DisplayHDR 600, 4K, RetroArch v1.10" 0.0 0.0 0.0001 0.0
|
||||||
|
#pragma parameter hcrt_support3 "REC SPEC: DisplayHDR 1000, 4K+, RetroArch v1.10" 0.0 0.0 0.0001 0.0
|
||||||
|
#pragma parameter hcrt_space1 " " 0.0 0.0 0.0001 0.0
|
||||||
|
#pragma parameter hcrt_instructions0 "HDR: Enable HDR: On" 0.0 0.0 0.0001 0.0
|
||||||
|
#pragma parameter hcrt_instructions1 "SCALING: Integer Scale: ON" 0.0 0.0 0.0001 0.0
|
||||||
|
#pragma parameter hcrt_instructions2 "SCALING: Integer Overscale: ON" 0.0 0.0 0.0001 0.0
|
||||||
|
#pragma parameter hcrt_instructions3 "SCALING: Apect Ratio: Core Provided" 0.0 0.0 0.0001 0.0
|
||||||
|
#pragma parameter hcrt_space2 " " 0.0 0.0 0.0001 0.0
|
||||||
|
#pragma parameter hcrt_user_settings "USER SETTINGS:" 0.0 0.0 0.0001 0.0
|
||||||
|
#pragma parameter hcrt_hdr " HDR | SDR" 0.0 0.0 1.0 1.0
|
||||||
|
#pragma parameter hcrt_max_nits " HDR: Display's Peak Luminance" 700.0 0.0 10000.0 10.0
|
||||||
|
#pragma parameter hcrt_paper_white_nits " HDR: Display's Paper White Luminance" 700.0 0.0 10000.0 10.0
|
||||||
|
#pragma parameter hcrt_colour_space " SDR: Display's Colour Space: sRGB | DCI-P3" 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_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_blue_vertical_convergence " Blue Vertical Convergence" 0.00 -10.0 10.0 0.01
|
||||||
|
#pragma parameter hcrt_red_horizontal_convergence " Red Horizontal Convergence" 0.00 -10.0 10.0 0.01
|
||||||
|
#pragma parameter hcrt_green_horizontal_convergence " Green Horizontal Convergence" 0.00 -10.0 10.0 0.01
|
||||||
|
#pragma parameter hcrt_blue_horizontal_convergence " Blue Horizontal Convergence" 0.00 -10.0 10.0 0.01
|
||||||
|
|
||||||
|
#pragma parameter hcrt_space3 " " 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_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_white_temperature " White Point: (PAL:D65, NTSC-U:D65, NTSC-J:D93)" 0.0 -5000.0 12000.0 100.0
|
||||||
|
#pragma parameter hcrt_expand_gamut " HDR: Original/Vivid" 0.0 0.0 1.0 1.0
|
||||||
|
#pragma parameter hcrt_brightness " Brightness" 0.0 -1.0 1.0 0.01
|
||||||
|
#pragma parameter hcrt_contrast " Contrast" 0.0 -1.0 1.0 0.01
|
||||||
|
#pragma parameter hcrt_saturation " Saturation" 0.0 -1.0 1.0 0.01
|
||||||
|
#pragma parameter hcrt_gamma " Gamma" 0.0 -1.0 1.0 0.01
|
||||||
|
|
||||||
|
#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_max " Red Scanline Max" 1.00 0.0 2.0 0.01
|
||||||
|
#pragma parameter hcrt_red_scanline_attack " Red Scanline Attack" 0.20 0.0 1.0 0.01
|
||||||
|
#pragma parameter hcrt_green_scanline_min " Green Scanline Min" 0.50 0.0 2.0 0.01
|
||||||
|
#pragma parameter hcrt_green_scanline_max " Green Scanline Max" 1.00 0.0 2.0 0.01
|
||||||
|
#pragma parameter hcrt_green_scanline_attack " Green Scanline Attack" 0.20 0.0 1.0 0.01
|
||||||
|
#pragma parameter hcrt_blue_scanline_min " Blue Scanline Min" 0.50 0.0 2.0 0.01
|
||||||
|
#pragma parameter hcrt_blue_scanline_max " Blue Scanline Max" 1.00 0.0 2.0 0.01
|
||||||
|
#pragma parameter hcrt_blue_scanline_attack " Blue Scanline Attack" 0.20 0.0 1.0 0.01
|
||||||
|
#pragma parameter hcrt_developer_settings1 " HORIZONTAL SETTINGS:" 0.0 0.0 0.0001 0.0
|
||||||
|
#pragma parameter hcrt_red_beam_sharpness " Red Beam Sharpness" 1.75 0.0 5.0 0.05
|
||||||
|
#pragma parameter hcrt_red_beam_attack " Red Beam Attack" 0.50 0.0 2.0 0.01
|
||||||
|
#pragma parameter hcrt_green_beam_sharpness " Green Beam Sharpness" 1.75 0.0 5.0 0.05
|
||||||
|
#pragma parameter hcrt_green_beam_attack " Green Beam Attack" 0.50 0.0 2.0 0.01
|
||||||
|
#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
|
||||||
|
|
||||||
|
|
|
@ -4,136 +4,129 @@
|
||||||
#define kMax 1.0f
|
#define kMax 1.0f
|
||||||
|
|
||||||
#define kBeamWidth 0.5f
|
#define kBeamWidth 0.5f
|
||||||
#define kLumaRatio 0.5f
|
|
||||||
|
|
||||||
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);
|
||||||
//const vec4 kScanlineControlPoints = vec4(1.0f, 1.0f, 0.0f, 0.0f);
|
//const vec4 kScanlineControlPoints = vec4(1.0f, 1.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
vec4 RedBeamControlPoints(const bool falloff)
|
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)
|
||||||
{
|
{
|
||||||
float inner_attack = clamp(HCRT_RED_BEAM_ATTACK, 0.0f, 1.0);
|
vec4 t = vec4(1.0, t0, t0*t0, t0*t0*t0);
|
||||||
float outer_attack = clamp(HCRT_RED_BEAM_ATTACK - 1.0f, 0.0f, 1.0);
|
return dot(t, control_points * kCubicBezier);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 BeamControlPoints(const float beam_attack, const bool falloff)
|
||||||
|
{
|
||||||
|
const float inner_attack = clamp(beam_attack, 0.0f, 1.0);
|
||||||
|
const float outer_attack = clamp(beam_attack - 1.0f, 0.0f, 1.0);
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 GreenBeamControlPoints(const bool falloff)
|
float ScanlineColour(const uint channel,
|
||||||
|
const vec2 source_size,
|
||||||
|
const float scanline_size,
|
||||||
|
const float source_tex_coord_x,
|
||||||
|
const float narrowed_source_pixel_offset,
|
||||||
|
const float vertical_convergence,
|
||||||
|
const float beam_attack,
|
||||||
|
const float scanline_min,
|
||||||
|
const float scanline_max,
|
||||||
|
const float scanline_attack,
|
||||||
|
inout float next_prev)
|
||||||
{
|
{
|
||||||
float inner_attack = clamp(HCRT_GREEN_BEAM_ATTACK, 0.0f, 1.0);
|
const float current_source_position_y = ((vTexCoord.y * source_size.y) - vertical_convergence) + next_prev;
|
||||||
float outer_attack = clamp(HCRT_GREEN_BEAM_ATTACK - 1.0f, 0.0f, 1.0);
|
const float current_source_center_y = floor(current_source_position_y) + 0.5f;
|
||||||
|
|
||||||
return falloff ? kFallOffControlPoints + vec4(0.0f, outer_attack, inner_attack, 0.0f) : kAttackControlPoints - vec4(0.0f, inner_attack, outer_attack, 0.0f);
|
const float source_tex_coord_y = current_source_center_y / source_size.y;
|
||||||
}
|
|
||||||
|
|
||||||
vec4 BlueBeamControlPoints(const bool falloff)
|
const float scanline_delta = fract(current_source_position_y) - 0.5f;
|
||||||
{
|
|
||||||
float inner_attack = clamp(HCRT_BLUE_BEAM_ATTACK, 0.0f, 1.0);
|
|
||||||
float outer_attack = clamp(HCRT_BLUE_BEAM_ATTACK - 1.0f, 0.0f, 1.0);
|
|
||||||
|
|
||||||
return falloff ? kFallOffControlPoints + vec4(0.0f, outer_attack, inner_attack, 0.0f) : kAttackControlPoints - vec4(0.0f, inner_attack, outer_attack, 0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 InverseTonemapConditional(const vec3 linear)
|
|
||||||
{
|
|
||||||
if(HCRT_HDR > 0.0f)
|
|
||||||
{
|
|
||||||
return linear;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return InverseTonemap(linear, HCRT_MAX_NITS, HCRT_PAPER_WHITE_NITS, kLumaRatio);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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 source_tex_coord_y = current_source_center_y / source_size.y;
|
|
||||||
|
|
||||||
const vec3 scanline_delta = fract(current_source_position_y) - 0.5f;
|
|
||||||
|
|
||||||
// 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);
|
float 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 = beam_distance < 0.0f ? 0.0f : beam_distance;
|
||||||
beam_distance.y < 0.0f ? 0.0f : beam_distance.y,
|
const float scanline_distance = beam_distance * 2.0f;
|
||||||
beam_distance.z < 0.0f ? 0.0f : beam_distance.z);
|
|
||||||
const vec3 scanline_distance = beam_distance * 2.0f;
|
|
||||||
|
|
||||||
next_prev.x = scanline_delta.x > 0.0f ? 1.0f : -1.0f;
|
next_prev = scanline_delta > 0.0f ? 1.0f : -1.0f;
|
||||||
next_prev.y = scanline_delta.y > 0.0f ? 1.0f : -1.0f;
|
|
||||||
next_prev.z = scanline_delta.z > 0.0f ? 1.0f : -1.0f;
|
|
||||||
|
|
||||||
const vec2 red_tex_coord_0 = vec2(source_tex_coord_x.x, source_tex_coord_y.x);
|
const vec2 tex_coord_0 = vec2(source_tex_coord_x, source_tex_coord_y);
|
||||||
const vec2 red_tex_coord_1 = vec2(source_tex_coord_x.x + (1.0f / source_size.x), source_tex_coord_y.x);
|
const vec2 tex_coord_1 = vec2(source_tex_coord_x + (1.0f / source_size.x), source_tex_coord_y);
|
||||||
|
|
||||||
const vec2 green_tex_coord_0 = vec2(source_tex_coord_x.y, source_tex_coord_y.y);
|
const float sdr_channel_0 = COMPAT_TEXTURE(SourceSDR, tex_coord_0)[channel];
|
||||||
const vec2 green_tex_coord_1 = vec2(source_tex_coord_x.y + (1.0f / source_size.x), source_tex_coord_y.y);
|
const float sdr_channel_1 = COMPAT_TEXTURE(SourceSDR, tex_coord_1)[channel];
|
||||||
|
|
||||||
const vec2 blue_tex_coord_0 = vec2(source_tex_coord_x.z, source_tex_coord_y.z);
|
const float hdr_channel_0 = COMPAT_TEXTURE(SourceHDR, tex_coord_0)[channel];
|
||||||
const vec2 blue_tex_coord_1 = vec2(source_tex_coord_x.z + (1.0f / source_size.x), source_tex_coord_y.z);
|
const float hdr_channel_1 = COMPAT_TEXTURE(SourceHDR, tex_coord_1)[channel];
|
||||||
|
|
||||||
const float red_0 = COMPAT_TEXTURE(Source, red_tex_coord_0).x;
|
|
||||||
const float red_1 = COMPAT_TEXTURE(Source, red_tex_coord_1).x;
|
|
||||||
|
|
||||||
const float green_0 = COMPAT_TEXTURE(Source, green_tex_coord_0).y;
|
|
||||||
const float green_1 = COMPAT_TEXTURE(Source, green_tex_coord_1).y;
|
|
||||||
|
|
||||||
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 vec3 sdr_colour_0 = ColourGrade(vec3(red_0, green_0, blue_0));
|
|
||||||
const vec3 sdr_colour_1 = ColourGrade(vec3(red_1, green_1, blue_1));
|
|
||||||
|
|
||||||
const vec3 hdr_colour_0 = InverseTonemapConditional(sdr_colour_0);
|
|
||||||
const vec3 hdr_colour_1 = InverseTonemapConditional(sdr_colour_1);
|
|
||||||
|
|
||||||
/* Horizontal interpolation between pixels */
|
/* Horizontal interpolation between pixels */
|
||||||
const vec3 horiz_interp = vec3(Bezier(narrowed_source_pixel_offset.x, RedBeamControlPoints(sdr_colour_0.x > sdr_colour_1.x)),
|
const float horiz_interp = Bezier(narrowed_source_pixel_offset, BeamControlPoints(beam_attack, sdr_channel_0 > sdr_channel_1));
|
||||||
Bezier(narrowed_source_pixel_offset.y, GreenBeamControlPoints(sdr_colour_0.y > sdr_colour_1.y)),
|
|
||||||
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 float hdr_channel = mix(hdr_channel_0, hdr_channel_1, horiz_interp);
|
||||||
const vec3 sdr_colour = mix(sdr_colour_0, sdr_colour_1, horiz_interp);
|
const float sdr_channel = mix(sdr_channel_0, sdr_channel_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 channel_scanline_distance = clamp(scanline_distance / ((sdr_channel * (scanline_max - scanline_min)) + 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 blue_scanline_distance = clamp(scanline_distance.z / ((sdr_colour.b * (HCRT_BLUE_SCANLINE_MAX - HCRT_BLUE_SCANLINE_MIN)) + HCRT_BLUE_SCANLINE_MIN), 0.0f, 1.0f);
|
|
||||||
|
|
||||||
const vec4 red_control_points = vec4(1.0f, 1.0f, sdr_colour.r * HCRT_RED_SCANLINE_ATTACK, 0.0f);
|
const vec4 channel_control_points = vec4(1.0f, 1.0f, sdr_channel * scanline_attack, 0.0f);
|
||||||
const vec4 green_control_points = vec4(1.0f, 1.0f, sdr_colour.g * HCRT_GREEN_SCANLINE_ATTACK, 0.0f);
|
|
||||||
const vec4 blue_control_points = vec4(1.0f, 1.0f, sdr_colour.b * HCRT_BLUE_SCANLINE_ATTACK, 0.0f);
|
|
||||||
|
|
||||||
const vec3 luminance = vec3(Bezier(red_scanline_distance, red_control_points),
|
const float luminance = Bezier(channel_scanline_distance, channel_control_points);
|
||||||
Bezier(green_scanline_distance, green_control_points),
|
|
||||||
Bezier(blue_scanline_distance, blue_control_points));
|
|
||||||
|
|
||||||
return luminance * hdr_colour;
|
return luminance * hdr_channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 GenerateScanline(const vec2 source_size, const float scanline_size)
|
float GenerateScanline( const uint channel,
|
||||||
|
const vec2 source_size,
|
||||||
|
const float scanline_size,
|
||||||
|
const float horizontal_convergence,
|
||||||
|
const float vertical_convergence,
|
||||||
|
const float beam_sharpness,
|
||||||
|
const float beam_attack,
|
||||||
|
const float scanline_min,
|
||||||
|
const float scanline_max,
|
||||||
|
const float scanline_attack)
|
||||||
{
|
{
|
||||||
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 float current_source_position_x = (vTexCoord.x * source_size.x) - horizontal_convergence;
|
||||||
const vec3 current_source_center_x = floor(current_source_position_x) + 0.5f;
|
const float current_source_center_x = floor(current_source_position_x) + 0.5f;
|
||||||
|
|
||||||
const vec3 source_tex_coord_x = current_source_center_x / source_size.x;
|
const float source_tex_coord_x = current_source_center_x / source_size.x;
|
||||||
|
|
||||||
const vec3 source_pixel_offset = fract(current_source_position_x);
|
const float source_pixel_offset = fract(current_source_position_x);
|
||||||
|
|
||||||
const vec3 beam_sharpness = vec3(HCRT_RED_BEAM_SHARPNESS, HCRT_GREEN_BEAM_SHARPNESS, HCRT_BLUE_BEAM_SHARPNESS);
|
const float narrowed_source_pixel_offset = clamp(((source_pixel_offset - 0.5f) * beam_sharpness) + 0.5f, 0.0f, 1.0f);
|
||||||
const vec3 narrowed_source_pixel_offset = clamp(((source_pixel_offset - vec3(0.5f)) * beam_sharpness) + vec3(0.5f), vec3(0.0f), vec3(1.0f));
|
|
||||||
|
|
||||||
vec3 next_prev = vec3(0.0f);
|
float next_prev = 0.0f;
|
||||||
|
|
||||||
const vec3 scanline_colour0 = ScanlineColour(source_size, scanline_size, source_tex_coord_x, narrowed_source_pixel_offset, next_prev);
|
const float scanline_colour0 = ScanlineColour( channel,
|
||||||
|
source_size,
|
||||||
|
scanline_size,
|
||||||
|
source_tex_coord_x,
|
||||||
|
narrowed_source_pixel_offset,
|
||||||
|
vertical_convergence,
|
||||||
|
beam_attack,
|
||||||
|
scanline_min,
|
||||||
|
scanline_max,
|
||||||
|
scanline_attack,
|
||||||
|
next_prev);
|
||||||
|
|
||||||
// Optionally sample the neighbouring scanline
|
// Optionally sample the neighbouring scanline
|
||||||
vec3 scanline_colour1 = vec3(0.0f);
|
float scanline_colour1 = 0.0f;
|
||||||
if(HCRT_RED_SCANLINE_MAX > 1.0f || HCRT_GREEN_SCANLINE_MAX > 1.0f || HCRT_BLUE_SCANLINE_MAX > 1.0f)
|
if(scanline_max > 1.0f)
|
||||||
{
|
{
|
||||||
scanline_colour1 = ScanlineColour(source_size, scanline_size, source_tex_coord_x, narrowed_source_pixel_offset, next_prev);
|
scanline_colour1 = ScanlineColour( channel,
|
||||||
|
source_size,
|
||||||
|
scanline_size,
|
||||||
|
source_tex_coord_x,
|
||||||
|
narrowed_source_pixel_offset,
|
||||||
|
vertical_convergence,
|
||||||
|
beam_attack,
|
||||||
|
scanline_min,
|
||||||
|
scanline_max,
|
||||||
|
scanline_attack,
|
||||||
|
next_prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
return scanline_colour0 + scanline_colour1;
|
return scanline_colour0 + scanline_colour1;
|
||||||
|
|
Loading…
Reference in a new issue