Hammster / windows-terminal-shaders

A small collection of terminal shaders
Creative Commons Zero v1.0 Universal
510 stars 34 forks source link

ENABLE_NOISE not used in CRT #14

Closed Fred-Vatin closed 1 year ago

Fred-Vatin commented 3 years ago

Hi,

In #define you use ENABLE_NOISE and in the if statement you replaced it by ENABLE_GRAIN. Hence the user can not use noise option. It is always disable.

Here is my fix. I added options to control scanline.

// Data provided by Windows Terminal
Texture2D shaderTexture;
SamplerState samplerState;

cbuffer PixelShaderSettings {
    float  Time;
    float  Scale;
    float2 Resolution;
    float4 Background;
};

// Settings
#define GRAIN_INTENSITY 0.052
// colors are RGBA, value between 0.0f and 1.0f or more for intensity
// #define TINT_COLOR float4(1, 0.7f, 0, 0) // yeloow
#define TINT_COLOR float4(0,1.0f,0.4f,0) // green
// #define TINT_COLOR float4(0,0.7f,1.0f,0) // blue
#define ENABLE_SCANLINES 1
#define ENABLE_REFRESHLINE 1
#define ENABLE_NOISE 1
#define ENABLE_CURVE 0
#define ENABLE_TINT 1
#define DEBUG 0
// line speed. default is 5, little is faster. minimum is 0.1
#define REFRESH_SPEED 5
// line thickness. default is 0.03f
#define LINE_THICKNESS 0.01f
// line opacity. default is 5.0f
#define LINE_OPACITY 10.15f

// Grain Lookup Table
#define a0  0.151015505647689
#define a1 -0.5303572634357367
#define a2  1.365020122861334
#define b0  0.132089632343748
#define b1 -0.7607324991323768

static const float4 tint = TINT_COLOR;
static const float4 scanlineTint = float4(0.6f, 0.6f, 0.6f, 0.0f);

float permute(float x)
{
    x *= (34 * x + 1);
    return 289 * frac(x * 1 / 289.0f);
}

float rand(inout float state)
{
    state = permute(state);
    return frac(state / 41.0f);
}

float4 mainImage(float2 tex) : TARGET
{
    float2 xy = tex.xy;

    #if ENABLE_CURVE
    // TODO: add control variable for transform intensity
    xy -= 0.5f;             // offcenter screen
    float r = xy.x * xy.x + xy.y * xy.y;    // get ratio
    xy *= 4.2f + r;             // apply ratio
    xy *= 0.25f;                // zoom
    xy += 0.5f;             // move back to center

    // TODO: add monitor visuals and make colors static consts
    // Outter Box
    if(xy.x < -0.025f || xy.y < -0.025f) return float4(0, 0, 0, 0);
    if(xy.x > 1.025f  || xy.y > 1.025f)  return float4(0, 0, 0, 0);
    // Bazel
    if(xy.x < -0.015f || xy.y < -0.015f) return float4(0.03f, 0.03f, 0.03f, 0.0f);
    if(xy.x > 1.015f  || xy.y > 1.015f)  return float4(0.03f, 0.03f, 0.03f, 0.0f);
    // Screen Border
    if(xy.x < 0.001f  || xy.y < 0.001f)  return float4(0.0f, 0.0f, 0.0f, 0.0f);
    if(xy.x > 0.999f  || xy.y > 0.999f)  return float4(0.0f, 0.0f, 0.0f, 0.0f);
    #endif

    float4 color = shaderTexture.Sample(samplerState, xy);

    #if DEBUG
    if(xy.x < 0.5f) return color;
    #endif

    #if ENABLE_REFRESHLINE
    float timeOver = fmod(Time / REFRESH_SPEED, 1);
    float refreshLineColorTint = timeOver - xy.y;
    if(xy.y > timeOver && xy.y - LINE_THICKNESS < timeOver ) color.rgb += (refreshLineColorTint * LINE_OPACITY);
    #endif

    #if ENABLE_SCANLINES
    // TODO: fixing the precision issue so that scanlines are always 1px
    if(floor(xy.y * 1000) % 2) color *= scanlineTint;
    #endif

    #if ENABLE_TINT
    float grayscale = (color.r + color.g + color.b) / 3.f;
    color = float4(grayscale, grayscale, grayscale, 0);
    color *= tint;
    #endif

    #if ENABLE_NOISE
    float3 m = float3(tex, Time % 5 / 5) + 1.;
    float state = permute(permute(m.x) + m.y) + m.z;

    float p = 0.95 * rand(state) + 0.025;
    float q = p - 0.5;
    float r2 = q * q;

    float grain = q * (a2 + (a1 * r2 + a0) / (r2 * r2 + b1 * r2 + b0));
    color.rgb += GRAIN_INTENSITY * grain;
    #endif

    return color;
}

float4 main(float4 pos : SV_POSITION, float2 tex : TEXCOORD) : SV_TARGET
{
    return mainImage(tex);
}
rbeesley commented 3 years ago

I addressed this in #10. Look at PR #11 for a more complete rewrite with additional functionality.

Fred-Vatin commented 3 years ago

I addressed this in #10. Look at PR #11 for a more complete rewrite with additional functionality.

Thanks. For me, any shaders used in Windows Terminal (v1.8.1444.0) end up heating my GPU (NVIDIA GeForce GTX 770). 3D processes between 10% and 40%. No issue using the built-in retro option. I stick with this for now.

rbeesley commented 3 years ago

@freMea, it definitely does. I created a couple more shaders not included in a repository yet, and it gets the fans on my laptop running like crazy. There are a few bugs I'll probably be submitting now that I've been really exercising this feature of wt.exe.

Hammster commented 1 year ago

I think this is resolved since #11 was merged 😅 sorry for the very late responses from my side