Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Rubberduckycooly
GitHub Repository: Rubberduckycooly/RSDKv5-Decompilation
Path: blob/master/RSDKv5/Shaders/Vulkan/CRT-Yee64.frag
1175 views
#version 450 

// =======================
// VARIABLES
// =======================
layout (location = 0) in vec2 ex_UV;
layout (location = 1) in vec4 ex_color;

layout (location = 0) out vec4 out_frag;

layout (binding = 0) uniform sampler2D texDiffuse; // screen display texture
layout (binding = 1) uniform RSDKBuffer {
    vec2 pixelSize;   // internal game resolution (usually 424x240 or smth)
    vec2 textureSize; // size of the internal framebuffer texture
    vec2 viewSize;    // window viewport size
#if RETRO_REV02  // if RETRO_REV02 is defined it assumes the engine is plus/rev02 RSDKv5, else it assumes pre-plus/Rev01 RSDKv5
    float screenDim; // screen dimming percent
#endif
};


// =======================
// DEFINITIONS
// =======================
#define viewSizeHD  720.0                    // how tall viewSize.y has to be before it simulates the dimming effect
#define intencity   vec3(1.2, 0.9, 0.9)   // how much to "dim" the screen when simulating a CRT effect
#define brightness  1.25                    // the brightness multipler of the colors

// In GLSL results are undefined if x < 0 (yet it works fine with OpenGL...).
// This hack is enough to make the shader work correctly on Vulkan.
#define pow(x,y) pow(abs(x),(y))

void main()
{
    vec2 texelPos = (textureSize.xy / pixelSize.xy) * ex_UV.xy;
    vec4 size     = (pixelSize.xy / textureSize.xy).xyxy * texelPos.xyxy;
    vec2 exp      = size.zw * textureSize.xy + -floor(size.zw * textureSize.xy) + -0.5;

    vec4 factor  = pow(vec4(2.0), pow(-exp.x + vec4(-1.0, 1.0, -2.0, 2.0), vec4(2.0)) * -3.0);
    float  factor2 = pow(2, pow(exp.x, 2) * -3); // used for the same stuff as 'factor', just doesn't fit in a vec4 :)

    vec3 power;
    power.x = pow(2, pow(exp.y, 2) * -8);
    power.y = pow(2, pow(-exp.y + -1, 2) * -8);
    power.z = pow(2, pow(-exp.y + 1, 2) * -8);

    vec2 viewPos      = floor(texelPos.xy * viewSize.xy) + 0.5;
    float intencityPos  = fract((viewPos.y * 3.0 + viewPos.x) * 0.166667);

    vec4 scanlineIntencity;
    if (intencityPos < 0.333)
        scanlineIntencity.rgb = intencity.xyz;
    else if (intencityPos < 0.666)
        scanlineIntencity.rgb = intencity.zxy;
    else
        scanlineIntencity.rgb = intencity.yzx;

    vec3 color1  = texture(texDiffuse, (floor(size.zw * textureSize.xy   + vec2( 1, -1))   + 0.5)      / textureSize.xy).rgb * factor.y * brightness;
    vec3 color2  = texture(texDiffuse, (floor(size.zw * textureSize.xy   + vec2(-2,  0))   + 0.5)      / textureSize.xy).rgb * factor.z * brightness;
    vec3 color3  = texture(texDiffuse, (floor(size.zw * textureSize.xy   + vec2(-1,  0))   + 0.5)      / textureSize.xy).rgb * factor.x * brightness;
    vec3 color4  = texture(texDiffuse, (floor(size.zw * textureSize.xy   + vec2( 1,  0))   + 0.5)      / textureSize.xy).rgb * factor.y * brightness;
    vec3 color5  = texture(texDiffuse, (floor(size.zw * textureSize.xy   + 0)              + 0.5)      / textureSize.xy).rgb * factor2  * brightness;
    vec3 color6  = texture(texDiffuse, (floor(size.zw * textureSize.xy   + vec2(-1,  1))   + 0.5)      / textureSize.xy).rgb * factor.x * brightness;
    vec3 color7  = texture(texDiffuse, (floor(size.zw * textureSize.xy   + vec2( 2,  0))   + 0.5)      / textureSize.xy).rgb * factor.w * brightness;
    vec3 color8  = texture(texDiffuse, (floor(size.zw * textureSize.xy   + -1)             + 0.5)      / textureSize.xy).rgb * factor.x * brightness;
    vec3 color9  = texture(texDiffuse, (floor(size.zw * textureSize.xy   + vec2( 0, -1))   + 0.5)      / textureSize.xy).rgb * factor2  * brightness;
    vec3 color10 = texture(texDiffuse, (floor(size.zw * textureSize.xy   + 1)              + 0.5)      / textureSize.xy).rgb * factor.y * brightness;
    vec3 color11 = texture(texDiffuse, (floor(size.xy * textureSize.xy   + vec2( 0,  1))   + 0.5)      / textureSize.xy).rgb * factor2  * brightness;

    vec3 final = 
        power.x * (color2 + color3 + color4 + color5 + color7) / (factor.z + factor.x + factor.y + factor2 + factor.w) +
        power.y * (color1 + color8 + color9)                   / (factor.y + factor.x + factor2)                       +
        power.z * (color10 + color6 + color11)                 / (factor.y + factor.x + factor2);

    out_frag.rgb = viewSizeHD < viewSize.y ? (scanlineIntencity.rgb * final.rgb) : final.rgb;
    out_frag.a = 1.0;
    
#if defined(RETRO_REV02) 
	out_frag *= screenDim;
#endif
}