Skip to content

Commit

Permalink
Merge pull request #20 from akgunter/feature/gaussian-scanlines
Browse files Browse the repository at this point in the history
Feature/gaussian scanlines
  • Loading branch information
akgunter authored Aug 27, 2022
2 parents b6ce2dc + 7236fcb commit 1115bb0
Show file tree
Hide file tree
Showing 27 changed files with 1,261 additions and 1,249 deletions.
22 changes: 14 additions & 8 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,28 @@ For the most part, configuring this implementation of crt-royale should be the s
There are a handful of notable differences:
1) Mask Sample Mode "Smooth" has a new setting `Downsampling Sharpness`. You can use it to make Mode "Smooth" look more similar to Mode "Sharp" if you prefer something in between. I find this particularly useful for the Shadow mask.

2) The scanline logic is now user-toggleable instead of autodetected, and you can change the thickness of the scanlines if you want. You can now enable frame blending to smooth out VSync artifacting.
2) The scanline logic is now user-toggleable instead of autodetected, and you can change the thickness of the scanlines if you want.

3) In DX9, the Mask Type is set by a preprocessor definition `phosphor_mask_type`. It can be either 0 for the Grille mask, 1 for the Slot mask, or 2 for the Shadow mask. You can also type "GRILLE", "SLOT", or "SHADOW" if you prefer.
3) You can now choose from a selection of "deinterlacing algorithms," to use the term loosely. The original crt-royale implicitely accomplished this by naively drawing the image on the screen and letting your monitor and eyes do the work. This resulted in image retention, jitter, and combing artifacts. Now you can choose from None (the original behavior), Weaving, Blended Weaving, and Static. All of these work by merging the current frame with the previous frame.
None: the original crt-royale behavior
Weaving: crisp, jitter-free, but noticeable combing artifacts
Blended Weaving: a middleground between None and Weaving
Static: emphasizes the scanlines by choosing the same field for every frame

4) `PHOSPHOR_BLOOM_TRIADS_LARGER_THAN_3_PIXELS` and its siblings are still present. You can choose one or none of them by setting `PHOSPHOR_BLOOM_TRIAD_SIZE_MODE` to a value in range `[0 - 4]`. This is defined in `user-settings.fxh`.
4) In DX9, the Mask Type is set by a preprocessor definition `phosphor_mask_type`. It can be either 0 for the Grille mask, 1 for the Slot mask, or 2 for the Shadow mask. You can also type "GRILLE", "SLOT", or "SHADOW" if you prefer.

5) The same is true for `SIMULATE_CRT_ON_LCD` and its siblings. Set `GAMMA_SIMULATION_MODE` to `[0 - 4]` to control which of those is active. This is defined in `derived-settings-and-constants.fxh`.
5) `PHOSPHOR_BLOOM_TRIADS_LARGER_THAN_3_PIXELS` and its siblings are still present. You can choose one or none of them by setting `PHOSPHOR_BLOOM_TRIAD_SIZE_MODE` to a value in range `[0 - 4]`. This is defined in `user-settings.fxh`.

6) Most of the "RUNTIME_...", "ANISOTROPIC_...", "DRIVERS_ALLOW_...", and other performance-related preprocessor definitions are either hidden from the UI or gone. Some of them are extremely difficult to port correctly. Some of them either don't do anything anymore or never did anything to begin with. And some of them I'll be adding back later, but I'll have to refactor them and the affected code to make them more user-friendly.
6) The same is true for `SIMULATE_CRT_ON_LCD` and its siblings. Set `GAMMA_SIMULATION_MODE` to `[0 - 4]` to control which of those is active. This is defined in `derived-settings-and-constants.fxh`.

7) I've disabled many of the beam settings due to my rewrite of the scanline logic. They currently are unused.
7) Most of the "RUNTIME_...", "ANISOTROPIC_...", "DRIVERS_ALLOW_...", and other performance-related preprocessor definitions are either hidden from the UI or gone. Some of them are extremely difficult to port correctly. Some of them either don't do anything anymore or never did anything to begin with. And some of them I'll be adding back later, but I'll have to refactor them and the affected code to make them more user-friendly.

8) I've exposed `antialias_filter`, `antialias_level`, and `antialias_temporal` as preprocessor definitions. Note that the code dedicated to having `antialias_level` set to `4` is disabled for now because it's currently broken.
8) I've disabled many of the beam settings due to my rewrite of the scanline logic. They currently are unused.

9) I've exposed `antialias_filter`, `antialias_level`, and `antialias_temporal` as preprocessor definitions. Note that the code dedicated to having `antialias_level` set to `4` is disabled for now because it's currently broken.


#### REPORTING DISCREPANCIES
Please be aware that, because ReShade and RetroArch shaders work so differently, it won't be possible to replicate the libretro version's output perfectly. There simply are too many low-level differences in too many bits of math to achieve a pixel-perfect port, especially now that I've rewritten the scanline logic to be variable-width. That being said, you should be able to get pretty darn close.

Obviously my top-priority is to make sure there aren't any breaking issues. If a configuration completely breaks the shader or crashes the game, I need to know about it. Similarly, if there's a configuration that runs well in RetroArch but is unplayably laggy in ReShade, I need to know about it. The same is true for configurations that completely screw up color balance in some stupid way (e.g. setting the Scanline Width to 2 used to throw off the brightness/gamma horribly, but 1 and 3+ were alright). Discrepancies that I won't be able to fix include occassional crushing in shadows, the bloom effect being more potent in places, or the scanlines being slightly different. These go back to limitations of ReShade and those aforementioned functional differences.
Obviously my top-priority is to make sure there aren't any breaking issues. If a configuration completely breaks the shader or crashes the game, I need to know about it. Similarly, if there's a configuration that runs well in RetroArch but is unplayably laggy in ReShade, I need to know about it. The same is true for configurations that completely screw up color balance in some stupid way (e.g. setting the Scanline Width to 2 used to throw off the brightness/gamma horribly, but 1 and 3 were alright). Discrepancies that I won't be able to fix include occassional crushing in shadows, the bloom effect being more potent in places, or the scanlines being slightly different. These go back to limitations of ReShade and those aforementioned functional differences.
157 changes: 96 additions & 61 deletions reshade-shaders/Shaders/crt-royale.fx
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,20 @@
#define CONTENT_BOX_VISIBLE 0
#endif

#include "crt-royale/shaders/content-box.fxh"

#if !CONTENT_BOX_VISIBLE
#include "crt-royale/shaders/content-crop.fxh"
#include "crt-royale/shaders/crt-royale-first-pass-linearize-crt-gamma-bob-fields.fxh"
#include "crt-royale/shaders/crt-royale-scanlines-vertical-interlacing.fxh"
// #include "crt-royale/shaders/crt-royale-scanlines-vertical-interlacing-new.fxh"
#include "crt-royale/shaders/crt-royale-electron-beams.fxh"
#include "crt-royale/shaders/crt-royale-bloom-approx.fxh"
#include "crt-royale/shaders/blur9fast-vertical.fxh"
#include "crt-royale/shaders/blur9fast-horizontal.fxh"
#include "crt-royale/shaders/crt-royale-mask-resize.fxh"
#include "crt-royale/shaders/crt-royale-scanlines-horizontal-apply-mask.fxh"
#include "crt-royale/shaders/crt-royale-deinterlace.fxh"
#include "crt-royale/shaders/crt-royale-phosphor-mask.fxh"
#include "crt-royale/shaders/crt-royale-brightpass.fxh"
#include "crt-royale/shaders/crt-royale-bloom-vertical.fxh"
#include "crt-royale/shaders/crt-royale-bloom-horizontal-reconstitute.fxh"
#include "crt-royale/shaders/crt-royale-geometry-aa-last-pass.fxh"
#include "crt-royale/shaders/crt-royale-blend-frames.fxh"
#else
#include "crt-royale/shaders/content-box.fxh"
#endif


Expand All @@ -50,143 +47,181 @@ technique CRT_Royale
// content-box.fxh
pass contentBoxPass
{
// Draw a box that displays the crop we'll perform.
VertexShader = PostProcessVS;
PixelShader = contentBoxPixelShader;
}
#else
// content-crop.fxh
pass cropPass
{
// Crop the input buffer, so all our math is scaled to the actual
// game content rather than the entire window.
VertexShader = PostProcessVS;
PixelShader = cropContentPixelShader;

RenderTarget = texCrop;
}
// crt-royale-first-pass-linearize-crt-gamma-bob-fields.fx
pass linearizeAndBobPass
// crt-royale-electron-beams.fx
pass interlacingPass
{
VertexShader = vertexShader0;
PixelShader = pixelShader0;
// Simulate interlacing by blending in-field rows
// and blanking out out-of-field rows.
VertexShader = simulateInterlacingVS;
PixelShader = simulateInterlacingPS;

RenderTarget = texOrigLinearized;
RenderTarget = texInterlaced;
}
// crt-royale-scanlines-vertical-interlacing.fxh
pass verticalBeamPass
pass electronBeamPass
{
VertexShader = PostProcessVS;
PixelShader = pixelShader1;
// Simulate emission of the interlaced video as electron beams.
VertexShader = simulateEletronBeamsVS;
PixelShader = simulateEletronBeamsPS;

RenderTarget = texVerticalScanlines;
RenderTarget = texElectronBeams;
}
pass verticalOffsetPass {
pass beamConvergencPass
{
// Simulate beam convergence miscalibration
// Not to be confused with beam purity
VertexShader = PostProcessVS;
PixelShader = verticalOffsetPS;
PixelShader = beamConvergencePS;

RenderTarget = texVerticalOffset;
RenderTarget = texBeamConvergence;
}
// crt-royale-bloom-approx.fxh
pass bloomApproxPass
pass bloomApproxPassVert
{
// The original crt-royale did a bunch of math in this pass
// and then threw it all away. So this is a no-op for now.
// It still has a blur effect b/c its a smaller buffer.
// TODO: activate the math in this pass and see what happens.
VertexShader = approximateBloomVS;
PixelShader = approximateBloomVertPS;

RenderTarget = texBloomApproxVert;
}
pass bloomApproxPassHoriz
{
VertexShader = PostProcessVS;
PixelShader = pixelShader2;
// The original crt-royale did a bunch of math in this pass
// and then threw it all away. So this is a no-op for now.
// It still has a blur effect b/c its a smaller buffer.
// TODO: activate the math in this pass and see what happens.
VertexShader = approximateBloomVS;
PixelShader = approximateBloomHorizPS;

RenderTarget = texBloomApprox;
RenderTarget = texBloomApproxHoriz;
}
// blur9fast-vertical.fxh
pass blurVerticalPass
{
VertexShader = vertexShader3;
PixelShader = pixelShader3;
// Vertically blur the approx bloom
VertexShader = blurVerticalVS;
PixelShader = blurVerticalPS;

RenderTarget = texBlurVertical;
}
// blur9fast-horizontal.fxh
pass blurHorizontalPass
{
VertexShader = vertexShader4;
PixelShader = pixelShader4;
// Horizontally blur the approx bloom
VertexShader = blurHorizontalVS;
PixelShader = blurHorizontalPS;

RenderTarget = texBlurHorizontal;
}
// crt-royale-mask-resize.fxh
// crt-royale-deinterlace.fxh
pass deinterlacePass
{
// Optionally deinterlace the video. This can produce more
// consistent behavior across monitors and emulators.
// It can also help simulate some edge cases.
VertexShader = deinterlaceVS;
PixelShader = deinterlacePS;

RenderTarget = texDeinterlace;
}
pass freezeFramePass
{
// Capture the current frame, so we can use it in the next
// frame's deinterlacing pass.
VertexShader = PostProcessVS;
PixelShader = freezeFramePS;

RenderTarget = texFreezeFrame;

// Explicitly disable clearing render targets
// scanlineBlendPass will not work properly if this ever defaults to true
ClearRenderTargets = false;
}
// crt-royale-phosphor-mask.fxh
pass phosphorMaskResizeVerticalPass
{
// Scale the phosphor mask vertically
VertexShader = maskResizeVertVS;
PixelShader = maskResizeVertPS;

RenderTarget = texMaskResizeVertical;
}
// crt-royale-mask-resize.fxh
pass phosphorMaskResizeHorizontalPass
{
// Scale the phosphor mask horizontally
VertexShader = maskResizeHorizVS;
PixelShader = maskResizeHorizPS;

RenderTarget = texMaskResizeHorizontal;
}
// crt-royale-scanlines-horizontal-apply-mask-new.fxh
pass phosphorMaskPass
{
// Tile the scaled phosphor mask and apply it to
// the deinterlaced image.
VertexShader = PostProcessVS;
PixelShader = newPixelShader7;
PixelShader = applyPhosphorMaskPS;

RenderTarget = texMaskedScanlines;
}
// crt-royale-brightpass.fxh
pass brightpassPass
{
VertexShader = vertexShader8;
PixelShader = pixelShader8;
// Apply a brightpass filter for the bloom effect
VertexShader = brightpassVS;
PixelShader = brightpassPS;

RenderTarget = texBrightpass;
}
// crt-royale-bloom-vertical.fxh
pass bloomVerticalPass
{
VertexShader = vertexShader9;
PixelShader = pixelShader9;
// Blur vertically for the bloom effect
VertexShader = bloomVerticalVS;
PixelShader = bloomVerticalPS;

RenderTarget = texBloomVertical;
}
// crt-royale-bloom-horizontal-reconstitute.fxh
pass bloomHorizontalPass
{
VertexShader = vertexShader10;
PixelShader = pixelShader10;
// Blur horizontally for the bloom effect.
// Also apply various color changes and effects.
VertexShader = bloomHorizontalVS;
PixelShader = bloomHorizontalPS;

RenderTarget = texBloomHorizontal;
}
// crt-royale-blend-frames.fxh
pass scanlineBlendPass
{
VertexShader = PostProcessVS;
PixelShader = lerpScanlinesPS;

RenderTarget = texBlendScanline;
}
// crt-royale-blend-frames.fxh
pass freezeFramePass
{
VertexShader = PostProcessVS;
PixelShader = freezeFramePS;

RenderTarget = texFreezeFrame;

// Explicitly disable clearing render targets
// scanlineBlendPass will not work properly if this ever defaults to true
ClearRenderTargets = false;
}
// crt-royale-geometry-aa-last-pass.fxh
pass geometryPass
{
VertexShader = vertexShader11;
PixelShader = pixelShader11;
// Apply screen geometry and anti-aliasing.
VertexShader = geometryVS;
PixelShader = geometryPS;

RenderTarget = texGeometry;
}
// content-crop.fxh
pass uncropPass
{
// Uncrop the video, so we draw the game's content
// in the same position it started in.
VertexShader = PostProcessVS;
PixelShader = uncropContentPixelShader;
}
Expand Down
Loading

0 comments on commit 1115bb0

Please sign in to comment.