Need help porting a shader from shadertoy

  • Posts: 9
5 months 13 hours ago - 5 months 9 hours ago #1 by originalnicodr
Hello there, a guy asked me some days ago about doing some kind of pixel sorting shader. He shared some links with me, one of those was the following shader:
www.shadertoy.com/view/XsBfRG

It lacks some features but I thought it wouldnt be to difficult to port it since I dont think I will get into making a shader with more stuff. The thing is after converting it it doesnt work as it does in shadertoy, so I wanted to ask if its possible to port the shader and if so where did i mess it up, here is the code:


#include "ReShade.fxh"

#include "ReShadeUI.fxh"

uniform float Amount < __UNIFORM_SLIDER_FLOAT1
    ui_min = 0.0;
    ui_max = 1;
> = 1.0;

uniform bool VERT < 
> = false;

uniform bool SHADOW < 
> = false;

uniform bool REVERSE <
> = false;

float fmod(float a, float b)
{
    return (a - b * floor(a / b));
}

float fromRgb( float3 v ) {
    return ( ( v.z * 256.0 + v.y ) * 256.0 + v.x ) * 255.0;
}

uniform float2 MouseCoords < source = "mousepoint"; >;
uniform bool LeftMouseDown < source = "mousebutton"; keycode = 0; toggle = false; >;

uniform float timer < source = "timer"; >;

#define THR ( MouseCoords.x < 1.0 ? ( sin( timer * 5.0 ) * 0.5 + 0.5 ) : MouseCoords.x)

float gray( float3 c ) {
    return dot(c,float3( 0.299, 0.587, 0.114));
}

float3 toRgb( float i ) {
    return float3(
        fmod( i, 256.0 ),
        fmod( floor( i / 256.0 ), 256.0 ),
        floor( i / 65536.0 )
    ) / 255.0;
}

bool thr( float v) {
    return SHADOW ? ( THR < v ) : ( v < THR );
}

float4 drawA( float2 uv, float4 backbuffer ) {
    float2 dirVec = VERT ? float2( 0.0, 1.0 ) : float2( 1.0, 0.0 );
    float wid = VERT ? BUFFER_HEIGHT : BUFFER_WIDTH;
    float pos = VERT ? floor( uv.y * BUFFER_HEIGHT ) : floor( uv.x * BUFFER_WIDTH );
    
    float val = gray( backbuffer.rgb );
    
    float thrvalue= ( MouseCoords.x < 1.0 ? ( sin( timer * 5.0 ) * 0.5 + 0.5 ) : MouseCoords.x);
    //thrvalue= Amount;

    if ( !thr(val) ) {
        float post = pos;
        float rank = 0.0;
        float head = 0.0;
        float tail = 0.0;
        
        for ( int i = 0; i < wid; i ++ ) {
            post -= 1.0;
            if ( post == -1.0 ) { head = post + 1.0; break; }
            float2 p = dirVec * ( post + 0.5 ) / wid + dirVec.xy * uv;
            float v = gray( backbuffer.rgb );
            if ( thr(v) ) { head = post + 1.0; break; }
            if ( v <= val ) { rank += 1.0; }
        }
        
        post = pos;
        for ( int i = 0; i < wid; i ++ ) {
            post += 1.0;
            if ( wid == post ) { tail = post - 1.0; break; }
            float2 p = dirVec * ( post + 0.5 ) / wid + dirVec.xy * uv;
            float v = gray( backbuffer.rgb );
            if ( thr(v) ) { tail = post - 1.0; break; }
            if ( v < val ) { rank += 1.0; }
        }
        
        pos = REVERSE ? ( tail - rank ) : ( head + rank );
    }
    
    return float4( toRgb( pos ), 1.0 );
}

float4 draw( float2 uv, float4 backbuffer, float4 backbufferA ) {
    float2 dirVec = VERT ? float2( 0.0, 1.0 ) : float2( 1.0, 0.0 );
    float wid = VERT ? BUFFER_HEIGHT : BUFFER_WIDTH;
    float pos = VERT ? floor( uv.y * BUFFER_HEIGHT ) : floor( uv.x * BUFFER_WIDTH );
    
    for ( int i = 0; i < wid; i ++ ) {
        float2 p = uv + dirVec * float( i ) / wid;
        if ( p.x < 1.0 && p.y < 1.0 ) {
            float v = fromRgb( backbufferA.rgb );
            if ( abs( v - pos ) < 0.5 ) {
                return backbuffer;
                //break;
            }
        }
        
        p = uv - dirVec * float( i ) / wid;
        if ( 0.0 < p.x && 0.0 < p.y ) {
            float v = fromRgb( backbufferA.rgb );
            if ( abs( v - pos ) < 0.5 ) {
                return backbuffer;
                //break;
            }
        }
    }
    return float4( 1.0, 0.0, 1.0, 1.0 );
}

void PixelSorting (float4 vpos: SV_Position, float2 texcoord: TEXCOORD, out float4 fragment: SV_Target0)
{
    fragment.rgba = tex2D(ReShade::BackBuffer, texcoord).rgb;
    float4 backbufferA= drawA(texcoord,fragment.rgba);
    fragment=draw(texcoord,fragment,backbufferA);
    //fragment=backbufferA;
}

technique PixelSorting {
    pass{
        VertexShader=PostProcessVS;
        PixelShader=PS_PixelSorting;
    }
}

The commented lines are for debugging. Any help would be much appreciated!

Edit: I should point out i dont know how this shader works, hence my struggle getting it work. I dont expect any of you to understand the code from shadertoy (if you do it would be really cool), but just helping me out in porting the code would be more than enough.

Please Log in or Create an account to join the conversation.