crt-generate-screen-texture

This shader generates the screen texture, which is effectively overlayed on top of the actual screen image in the rgb-to-crt shader. This includes the emulation of the shadow mask (or slot mask, aperture grill) of a CRT screen, as well as masking around the edges to handle blacking out values that are outside of the visible screen.

This shader uses an expensive 64-tap filter to minimize Moiré patterns in the mask, so it is not intended for this to be run every frame - merely whenever the render parameters change, including the width and height of the final emulated image.

Index

Example Images

Input Textures/Samplers

g_maskTexture
                g_maskTexture
              
Type
texture (platform-specific)
Description
The mask texture we wish to use. This is typically the output from one of generate-shadow-mask, generate-slot-mask, or generate-aperture-grille.
g_sampler
                g_sampler
              
Type
sampler (platform-specific, does not exist on some platforms)
Description
The sampler to use to sample g_maskTexture.

Uniform Buffer Values

g_viewScale
                float2 g_viewScale
              
Type
float2
Description

NOTE: this value is expected to match the equivalent value in rgb-to-crt.

This value describes how to scale the screen to account for different aspect ratios between the output dimensions and the emulated visible CRT dimensions (i.e. excluding any overscan-clipped content).

This shader is intended to render a screen of the correct shape regardless of the output render target shape, effectively letterboxing or pillarboxing as needed (i.e. rendering a 4:3 screen to a 16:9 render target).

In the event the output render target is wider than the intended screen, the screen needs to be scaled down horizontally to pillarbox, usually like:

                  x = (renderTargetWidth / renderTargetHeight) 
                    * (crtScreenHeight / crtScreenWidth)
                  y = 1.0
                

if the output render target is taller than the intended screen, it will end up letterboxed using something like:

                  x = 1.0
                  y = (renderTargetHeight / renderTargetWidth) 
                    * (crtScreenWidth / crtScreenHeight)
                
g_overscanScale
                float2 g_overscanScale
              
Type
float2
Description

NOTE: this value is expected to match the equivalent value in rgb-to-crt.

If overscan emulation is intended (where the edges of the screen cover up some of the picture), then this is the amount of signal texture scaling needed to account for that.

Given an overscan value named overscanAmount that is (where the given values are in texels):

                  overscanAmount.x = overscanLeft + overscanRight
                  overscanAmount.y = overscanTop + overscanBottom
                

the value of g_overscanScale should end up being:

                  (inputImageSize.xy - overscanAmount.xy)
                    * 0.5
                    / inputImageSize.xy
                
g_overscanOffset
                float2 g_overscanOffset
              
Type
float2
Description

NOTE: this value is expected to match the equivalent value in rgb-to-crt.

the texture coordinate offset to adjust for overscan. Because the screen coordinates are [-1..1] instead of [0..1], this is the offset needed to recenter the value.

Given an overscan value named overscanAmount that is (where the given values are in texels):

                  overscanDifference.x = overscanLeft - overscanRight
                  overscanDifference.y = overscanTop - overscanBottom
                

the value of g_overscanScale should end up being:

                  overscanDifference.xy
                    * 0.5
                    / inputImageSize.xy
                
g_distortion
                float2 g_distortion
              
Type
float2
Description

NOTE: this value is expected to match the equivalent value in rgb-to-crt.

The amount along each axis to apply the virtual-curved screen distortion. Usually a value in [0..1], where 0 indicates no curvature (a flat screen) and 1 indicates "quite curved"

g_maskDistortion
                float2 g_maskDistortion
              
Type
float2
Description
The distortion amount used for where the edges of the screen should be. Should be at least g_distortion, but if emulating an older TV which had some additional bevel curvature that cut off part of the picture, this can be applied by adding additional value to this.
g_maskScale
                float2 g_maskScale
              
Type
float2
Description
The scale of the mask texture. Higher value means the coordinates are scaled more and, thus, the shadow mask is smaller.
g_aspect
                float g_aspect
              
Type
float
Description
The aspect ratio of the source texture (width / height, used for aspect correction)
g_roundedCornerSize
                float g_roundedCornerSize
              
Type
float
Description
How much to round the corners of the screen to emulate a TV with rounded corners that cut off a little picture. 0 indicates no rounding (squared-off corners), while a value of 1 means "the whole screen is an oval." Values smaller than 0.2 are recommended.