Duckstation/data/resources/shaders/reshade/Shaders/crt/crt-royale.fx
Hyllian bf1b023f12
Add a new port of crt-royale.fx (#3260)
- A new port of crt-royale. More faithful to original. It uses the same mask textures.
- The only thing not ported is the original geometry pass. It was replaced by geom curvature code.
- It's configured for 1080p displays. 4k displays need to adjust param mask_triad_size_desired from 3.0 to 4.0.

OBS: It's up to you decide if the two versions should be maintained.
2024-07-26 14:33:01 +10:00

495 lines
15 KiB
HLSL

#include "ReShade.fxh"
///////////////////////////// GPL LICENSE NOTICE /////////////////////////////
// crt-royale: A full-featured CRT shader, with cheese.
// Copyright (C) 2014 TroggleMonkey <trogglemonkey@gmx.com>
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License, or any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the Free Software Foundation, Inc., 59 Temple
// Place, Suite 330, Boston, MA 02111-1307 USA
// Ported to Duckstation (ReShade specs) by Hyllian (2024).
// Set shader params for all passes here:
uniform float crt_gamma <
ui_type = "drag";
ui_min = 1.0;
ui_max = 5.0;
ui_step = 0.025;
ui_label = "Simulated CRT Gamma";
> = 2.5;
uniform float lcd_gamma <
ui_type = "drag";
ui_min = 1.0;
ui_max = 5.0;
ui_step = 0.025;
ui_label = "Your Display Gamma";
> = 2.2;
uniform float levels_contrast <
ui_type = "drag";
ui_min = 0.0;
ui_max = 4.0;
ui_step = 0.015625;
ui_label = "Contrast";
> = 1.0;
uniform float halation_weight <
ui_type = "drag";
ui_min = 0.0;
ui_max = 1.0;
ui_step = 0.005;
ui_label = "Halation Weight";
> = 0.0;
uniform float diffusion_weight <
ui_type = "drag";
ui_min = 0.0;
ui_max = 1.0;
ui_step = 0.005;
ui_label = "Diffusion Weight";
> = 0.075;
uniform float bloom_underestimate_levels <
ui_type = "drag";
ui_min = 0.0;
ui_max = 5.0;
ui_step = 0.01;
ui_label = "Bloom - Underestimate Levels";
> = 0.8;
uniform float bloom_excess <
ui_type = "drag";
ui_min = 0.0;
ui_max = 1.0;
ui_step = 0.005;
ui_label = "Bloom - Excess";
> = 0.0;
uniform float beam_min_sigma <
ui_type = "drag";
ui_min = 0.005;
ui_max = 1.0;
ui_step = 0.005;
ui_label = "Beam - Min Sigma";
> = 0.02;
uniform float beam_max_sigma <
ui_type = "drag";
ui_min = 0.005;
ui_max = 1.0;
ui_step = 0.005;
ui_label = "Beam - Max Sigma";
> = 0.3;
uniform float beam_spot_power <
ui_type = "drag";
ui_min = 0.01;
ui_max = 16.0;
ui_step = 0.01;
ui_label = "Beam - Spot Power";
> = 0.33;
uniform float beam_min_shape <
ui_type = "drag";
ui_min = 2.0;
ui_max = 32.0;
ui_step = 0.1;
ui_label = "Beam - Min Shape";
> = 2.0;
uniform float beam_max_shape <
ui_type = "drag";
ui_min = 2.0;
ui_max = 32.0;
ui_step = 0.1;
ui_label = "Beam - Max Shape";
> = 4.0;
uniform float beam_shape_power <
ui_type = "drag";
ui_min = 0.01;
ui_max = 16.0;
ui_step = 0.01;
ui_label = "Beam - Shape Power";
> = 0.25;
uniform int beam_horiz_filter <
ui_type = "combo";
ui_items = "Quilez (fast)\0Gaussian (slow)\0Lanczos (medium)\0";
ui_label = "Beam - Horiz Filter";
> = 0;
uniform float beam_horiz_sigma <
ui_type = "drag";
ui_min = 0.0;
ui_max = 0.67;
ui_step = 0.005;
ui_label = "Beam - Horiz Sigma";
> = 0.35;
uniform float beam_horiz_linear_rgb_weight <
ui_type = "drag";
ui_min = 0.0;
ui_max = 1.0;
ui_step = 0.01;
ui_label = "Beam - Horiz Linear RGB Weight";
> = 1.0;
uniform float convergence_offset_x_r <
ui_type = "drag";
ui_min = -4.0;
ui_max = 4.0;
ui_step = 0.05;
ui_label = "Convergence - Offset X Red";
> = 0.0;
uniform float convergence_offset_x_g <
ui_type = "drag";
ui_min = -4.0;
ui_max = 4.0;
ui_step = 0.05;
ui_label = "Convergence - Offset X Green";
> = 0.0;
uniform float convergence_offset_x_b <
ui_type = "drag";
ui_min = -4.0;
ui_max = 4.0;
ui_step = 0.05;
ui_label = "Convergence - Offset X Blue";
> = 0.0;
uniform float convergence_offset_y_r <
ui_type = "drag";
ui_min = -2.0;
ui_max = 2.0;
ui_step = 0.05;
ui_label = "Convergence - Offset Y Red";
> = 0.0;
uniform float convergence_offset_y_g <
ui_type = "drag";
ui_min = -2.0;
ui_max = 2.0;
ui_step = 0.05;
ui_label = "Convergence - Offset Y Green";
> = 0.0;
uniform float convergence_offset_y_b <
ui_type = "drag";
ui_min = -2.0;
ui_max = 2.0;
ui_step = 0.05;
ui_label = "Convergence - Offset Y Blue";
> = 0.0;
uniform int mask_type <
ui_type = "combo";
ui_items = "Aperture Grille\0Slot Mask\0Shadow Mask\0";
ui_label = "Mask - Type";
> = 0;
uniform float mask_sample_mode_desired <
ui_type = "drag";
ui_min = 0.0;
ui_max = 2.0;
ui_step = 1.;
ui_label = "Mask - Sample Mode";
> = 0.0;
uniform float mask_specify_num_triads <
ui_type = "drag";
ui_min = 0.0;
ui_max = 1.0;
ui_step = 1.0;
ui_label = "Mask - Specify Number of Triads";
> = 0.0;
uniform float mask_triad_size_desired <
ui_type = "drag";
ui_min = 1.0;
ui_max = 18.0;
ui_step = 0.125;
ui_label = "Mask - Triad Size Desired";
> = 3.0;
uniform float mask_num_triads_desired <
ui_type = "drag";
ui_min = 342.0;
ui_max = 1920.0;
ui_step = 1.0;
ui_label = "Mask - Number of Triads Desired";
> = 480.0;
uniform bool interlace_detect <
ui_type = "radio";
ui_label = "Enable Interlacing Detection";
ui_category = "Interlacing";
> = true;
uniform bool interlace_bff <
ui_type = "radio";
ui_label = "Bottom Field First";
ui_category = "Interlacing";
> = false;
uniform bool interlace_1080i <
ui_type = "radio";
ui_label = "Detect 1080i";
ui_category = "Interlacing";
> = false;
uniform float FrameCount < source = "framecount"; >;
uniform float2 BufferToViewportRatio < source = "buffer_to_viewport_ratio"; >;
uniform float2 InternalPixelSize < source = "internal_pixel_size"; >;
uniform float2 NativePixelSize < source = "native_pixel_size"; >;
uniform float2 NormalizedInternalPixelSize < source = "normalized_internal_pixel_size"; >;
uniform float2 NormalizedNativePixelSize < source = "normalized_native_pixel_size"; >;
uniform float UpscaleMultiplier < source = "upscale_multiplier"; >;
uniform float2 ViewportSize < source = "viewportsize"; >;
uniform float ViewportWidth < source = "viewportwidth"; >;
uniform float ViewportHeight < source = "viewportheight"; >;
#include "../misc/include/geom.fxh"
#define VIEWPORT_SIZE (ViewportSize*BufferToViewportRatio)
#define TEXTURE_SIZE (1.0/NormalizedNativePixelSize)
#define ORIG_LINEARIZED_texture_size TEXTURE_SIZE
#define VERTICAL_SCANLINES_texture_size TEXTURE_SIZE
#define BLOOM_APPROX_texture_size TEXTURE_SIZE
#define BLUR9FAST_VERTICAL_texture_size TEXTURE_SIZE
#define HALATION_BLUR_texture_size TEXTURE_SIZE
#define MASK_RESIZE_VERT_texture_size TEXTURE_SIZE
#define MASK_RESIZE_texture_size float2(64.0,0.0625*((VIEWPORT_SIZE).y))
#define MASKED_SCANLINES_texture_size (0.0625*VIEWPORT_SIZE)
#define BRIGHTPASS_texture_size VIEWPORT_SIZE
#define BLOOM_VERTICAL_texture_size VIEWPORT_SIZE
#define BLOOM_HORIZONTAL_texture_size VIEWPORT_SIZE
#define ORIG_LINEARIZED_video_size ORIG_LINEARIZED_texture_size
#define VERTICAL_SCANLINES_video_size VERTICAL_SCANLINES_texture_size
#define BLOOM_APPROX_video_size BLOOM_APPROX_texture_size
#define BLUR9FAST_VERTICAL_video_size BLUR9FAST_VERTICAL_texture_size
#define HALATION_BLUR_video_size HALATION_BLUR_texture_size
#define MASK_RESIZE_VERT_video_size MASK_RESIZE_VERT_texture_size
#define MASK_RESIZE_video_size MASK_RESIZE_texture_size
#define MASKED_SCANLINES_video_size MASKED_SCANLINES_texture_size
#define BRIGHTPASS_video_size BRIGHTPASS_texture_size
#define BLOOM_VERTICAL_video_size BLOOM_VERTICAL_texture_size
#define BLOOM_HORIZONTAL_video_size BLOOM_HORIZONTAL_texture_size
#define video_size texture_size
texture2D tmask_grille_texture_small < source = "crt-royale/TileableLinearApertureGrille15Wide8And5d5SpacingResizeTo64.png"; > {Width=64.0;Height=64.0;MipLevels=0;};
texture2D tmask_slot_texture_small < source = "crt-royale/TileableLinearSlotMaskTall15Wide9And4d5Horizontal9d14VerticalSpacingResizeTo64.png"; > {Width=64.0;Height=64.0;MipLevels=0;};
texture2D tmask_shadow_texture_small < source = "crt-royale/TileableLinearShadowMaskEDPResizeTo64.png"; > {Width=64.0;Height=64.0;MipLevels=0;};
texture2D tmask_grille_texture_large < source = "crt-royale/TileableLinearApertureGrille15Wide8And5d5Spacing.png"; > {Width=512.0;Height=512.0;MipLevels=4;};
texture2D tmask_slot_texture_large < source = "crt-royale/TileableLinearSlotMaskTall15Wide9And4d5Horizontal9d14VerticalSpacing.png"; > {Width=512.0;Height=512.0;MipLevels=4;};
texture2D tmask_shadow_texture_large < source = "crt-royale/TileableLinearShadowMaskEDP.png"; > {Width=512.0;Height=512.0;MipLevels=4;};
sampler2D mask_grille_texture_small { Texture = tmask_grille_texture_small; AddressU = REPEAT; AddressV = REPEAT; MinFilter = POINT; MagFilter = POINT;};
sampler2D mask_slot_texture_small { Texture = tmask_slot_texture_small; AddressU = REPEAT; AddressV = REPEAT; MinFilter = POINT; MagFilter = POINT;};
sampler2D mask_shadow_texture_small { Texture = tmask_shadow_texture_small; AddressU = REPEAT; AddressV = REPEAT; MinFilter = POINT; MagFilter = POINT;};
sampler2D mask_grille_texture_large { Texture = tmask_grille_texture_large; AddressU = REPEAT; AddressV = REPEAT; MinFilter = POINT; MagFilter = POINT;};
sampler2D mask_slot_texture_large { Texture = tmask_slot_texture_large; AddressU = REPEAT; AddressV = REPEAT; MinFilter = POINT; MagFilter = POINT;};
sampler2D mask_shadow_texture_large { Texture = tmask_shadow_texture_large; AddressU = REPEAT; AddressV = REPEAT; MinFilter = POINT; MagFilter = POINT;};
#ifndef DEBUG_PASSES
#define DEBUG_PASSES 11
#endif
texture2D tORIG_LINEARIZED{Width=BUFFER_WIDTH;Height=BUFFER_HEIGHT;Format=RGBA16f;};
sampler2D ORIG_LINEARIZED{Texture=tORIG_LINEARIZED;AddressU=BORDER;AddressV=BORDER;AddressW=BORDER;MagFilter=LINEAR;MinFilter=LINEAR;};
#if (DEBUG_PASSES > 1)
texture2D tVERTICAL_SCANLINES{Width=BUFFER_WIDTH;Height=BUFFER_HEIGHT;Format=RGBA16f;};
sampler2D VERTICAL_SCANLINES{Texture=tVERTICAL_SCANLINES;AddressU=BORDER;AddressV=BORDER;AddressW=BORDER;MagFilter=LINEAR;MinFilter=LINEAR;};
#endif
#if (DEBUG_PASSES > 2)
texture2D tBLOOM_APPROX{Width=BUFFER_WIDTH;Height=BUFFER_HEIGHT;Format=RGBA16f;};
sampler2D BLOOM_APPROX{Texture=tBLOOM_APPROX;AddressU=BORDER;AddressV=BORDER;AddressW=BORDER;MagFilter=LINEAR;MinFilter=LINEAR;};
#endif
#if (DEBUG_PASSES > 3)
// Need checking if it's really necessary to rendertarget.
texture2D tBLUR9FAST_VERTICAL{Width=BUFFER_WIDTH;Height=BUFFER_HEIGHT;Format=RGBA16f;};
sampler2D BLUR9FAST_VERTICAL{Texture=tBLUR9FAST_VERTICAL;AddressU=BORDER;AddressV=BORDER;AddressW=BORDER;MagFilter=LINEAR;MinFilter=LINEAR;};
#endif
#if (DEBUG_PASSES > 4)
texture2D tHALATION_BLUR{Width=BUFFER_WIDTH;Height=BUFFER_HEIGHT;Format=RGBA16f;};
sampler2D HALATION_BLUR{Texture=tHALATION_BLUR;AddressU=BORDER;AddressV=BORDER;AddressW=BORDER;MagFilter=LINEAR;MinFilter=LINEAR;};
#endif
#if (DEBUG_PASSES > 5)
texture2D tMASK_RESIZE_VERTICAL{Width=64.0;Height=BUFFER_HEIGHT*0.0625;Format=RGBA8;};
sampler2D MASK_RESIZE_VERTICAL{Texture=tMASK_RESIZE_VERTICAL;AddressU=BORDER;AddressV=BORDER;AddressW=BORDER;MagFilter=POINT;MinFilter=POINT;};
#endif
#if (DEBUG_PASSES > 6)
texture2D tMASK_RESIZE{Width=BUFFER_WIDTH*0.0625;Height=BUFFER_HEIGHT*0.0625;Format=RGBA8;};
sampler2D MASK_RESIZE{Texture=tMASK_RESIZE;AddressU=BORDER;AddressV=BORDER;AddressW=BORDER;MagFilter=POINT;MinFilter=POINT;};
#endif
#if (DEBUG_PASSES > 7)
texture2D tMASKED_SCANLINES{Width=BUFFER_WIDTH;Height=BUFFER_HEIGHT;Format=RGBA16f;};
sampler2D MASKED_SCANLINES{Texture=tMASKED_SCANLINES;AddressU=BORDER;AddressV=BORDER;AddressW=BORDER;MagFilter=LINEAR;MinFilter=LINEAR;};
#endif
#if (DEBUG_PASSES > 8)
texture2D tBRIGHTPASS{Width=BUFFER_WIDTH;Height=BUFFER_HEIGHT;Format=RGBA16f;};
sampler2D BRIGHTPASS{Texture=tBRIGHTPASS;AddressU=BORDER;AddressV=BORDER;AddressW=BORDER;MagFilter=LINEAR;MinFilter=LINEAR;};
#endif
#if (DEBUG_PASSES > 9)
texture2D tBLOOM_VERTICAL{Width=BUFFER_WIDTH;Height=BUFFER_HEIGHT;Format=RGBA16f;};
sampler2D BLOOM_VERTICAL{Texture=tBLOOM_VERTICAL;AddressU=BORDER;AddressV=BORDER;AddressW=BORDER;MagFilter=LINEAR;MinFilter=LINEAR;};
#endif
#include "crt-royale/src/crt-royale-first-pass-linearize-crt-gamma-bob-fields.fxh"
#if (DEBUG_PASSES > 1)
#include "crt-royale/src/crt-royale-scanlines-vertical-interlacing.fxh"
#endif
#if (DEBUG_PASSES > 2)
#include "crt-royale/src/crt-royale-bloom-approx.fxh"
#endif
#if (DEBUG_PASSES > 3)
#include "crt-royale/src/blur9fast-vertical.fxh"
#endif
#if (DEBUG_PASSES > 4)
#include "crt-royale/src/blur9fast-horizontal.fxh"
#endif
#if (DEBUG_PASSES > 5)
#include "crt-royale/src/crt-royale-mask-resize-vertical.fxh"
#endif
#if (DEBUG_PASSES > 6)
#include "crt-royale/src/crt-royale-mask-resize-horizontal.fxh"
#endif
#if (DEBUG_PASSES > 7)
#include "crt-royale/src/crt-royale-scanlines-horizontal-apply-mask.fxh"
#endif
#if (DEBUG_PASSES > 8)
#include "crt-royale/src/crt-royale-brightpass.fxh"
#endif
#if (DEBUG_PASSES > 9)
#include "crt-royale/src/crt-royale-bloom-vertical.fxh"
#endif
#if (DEBUG_PASSES > 10)
#include "crt-royale/src/crt-royale-bloom-horizontal-reconstitute.fxh"
#endif
technique CRT_Royale
{
pass
{
VertexShader = VS_Linearize;
PixelShader = PS_Linearize;
RenderTarget = tORIG_LINEARIZED;
}
#if (DEBUG_PASSES > 1)
pass
{
VertexShader = VS_Scanlines_Vertical_Interlacing;
PixelShader = PS_Scanlines_Vertical_Interlacing;
RenderTarget = tVERTICAL_SCANLINES;
}
#endif
#if (DEBUG_PASSES > 2)
pass
{
VertexShader = VS_Bloom_Approx;
PixelShader = PS_Bloom_Approx;
RenderTarget = tBLOOM_APPROX;
}
#endif
#if (DEBUG_PASSES > 3)
pass
{
VertexShader = VS_Blur9Fast_Vertical;
PixelShader = PS_Blur9Fast_Vertical;
RenderTarget = tBLUR9FAST_VERTICAL;
}
#endif
#if (DEBUG_PASSES > 4)
pass
{
VertexShader = VS_Blur9Fast_Horizontal;
PixelShader = PS_Blur9Fast_Horizontal;
RenderTarget = tHALATION_BLUR;
}
#endif
#if (DEBUG_PASSES > 5)
pass
{
VertexShader = VS_Mask_Resize_Vertical;
PixelShader = PS_Mask_Resize_Vertical;
RenderTarget = tMASK_RESIZE_VERTICAL;
}
#endif
#if (DEBUG_PASSES > 6)
pass
{
VertexShader = VS_Mask_Resize_Horizontal;
PixelShader = PS_Mask_Resize_Horizontal;
RenderTarget = tMASK_RESIZE;
}
#endif
#if (DEBUG_PASSES > 7)
pass
{
VertexShader = VS_Scanlines_Horizontal_Apply_Mask;
PixelShader = PS_Scanlines_Horizontal_Apply_Mask;
RenderTarget = tMASKED_SCANLINES;
}
#endif
#if (DEBUG_PASSES > 8)
pass
{
VertexShader = VS_Brightpass;
PixelShader = PS_Brightpass;
RenderTarget = tBRIGHTPASS;
}
#endif
#if (DEBUG_PASSES > 9)
pass
{
VertexShader = VS_Bloom_Vertical;
PixelShader = PS_Bloom_Vertical;
RenderTarget = tBLOOM_VERTICAL;
}
#endif
#if (DEBUG_PASSES > 10)
pass
{
VertexShader = VS_Bloom_Horizontal;
PixelShader = PS_Bloom_Horizontal;
}
#endif
}