Porting from shadertoy to retroarch (GLSL)

I was wanting to try this shader out in retroarch, but I don’t understand how to use “const”… Can anyone help me out?

Here’s the shadertoy shader: https://www.shadertoy.com/view/4scGDr

const is fine in RA shaders, it just needs to be a constant value (i.e., something like 3.14159 for Pi and not something like a parameter).

1 Like

So should this be a fairly straightforward port?

Just skimming over it, I didn’t spot anything that would be a big problem, no.

1 Like

Thanks, I’ll try it sometime later today or tomorrow.

@hunterk Okkkkkk… This was more complicated then I thought. Could you help me finish this? (started yesterday…)

// version directive if necessary

// good place for credits/license

// Parameter lines go here:
#pragma parameter WHATEVER "Whatever" 0.0 0.0 1.0 1.0

#if defined(VERTEX)

#if __VERSION__ >= 130
#define COMPAT_VARYING out
#define COMPAT_ATTRIBUTE in
#define COMPAT_TEXTURE texture
#else
#define COMPAT_VARYING varying 
#define COMPAT_ATTRIBUTE attribute 
#define COMPAT_TEXTURE texture2D
#endif

#ifdef GL_ES
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif

COMPAT_ATTRIBUTE vec4 VertexCoord;
COMPAT_ATTRIBUTE vec4 COLOR;
COMPAT_ATTRIBUTE vec4 TexCoord;
COMPAT_VARYING vec4 COL0;
COMPAT_VARYING vec4 TEX0;
// out variables go here as COMPAT_VARYING whatever

vec4 _oPosition1; 
uniform mat4 MVPMatrix;
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
uniform COMPAT_PRECISION vec3 iResolution;
uniform float iTime;

// compatibility #defines
#define vTexCoord TEX0.xy
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
#define OutSize vec4(OutputSize, 1.0 / OutputSize)

#ifdef PARAMETER_UNIFORM
uniform COMPAT_PRECISION float WHATEVER;
#else
#define WHATEVER 0.0
#endif

void main()
{
    gl_Position = MVPMatrix * VertexCoord;
    TEX0.xy = TexCoord.xy;
// Paste vertex contents here:
}

#elif defined(FRAGMENT)

#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif

#if __VERSION__ >= 130
#define COMPAT_VARYING in
#define COMPAT_TEXTURE texture
out COMPAT_PRECISION vec4 FragColor;
#else
#define COMPAT_VARYING varying
#define FragColor gl_FragColor
#define COMPAT_TEXTURE texture2D
#endif

uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
uniform sampler2D Texture;
uniform COMPAT_PRECISION vec3 iResolution;
uniform float iTime;
COMPAT_VARYING vec4 TEX0;
// in variables go here as COMPAT_VARYING whatever

// compatibility #defines
#define Source Texture
#define vTexCoord TEX0.xy

#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
#define OutSize vec4(OutputSize, 1.0 / OutputSize)

// delete all 'params.' or 'registers.' or whatever in the fragment and replace
// texture(a, b) with COMPAT_TEXTURE(a, b) <-can't macro unfortunately

#ifdef PARAMETER_UNIFORM
uniform COMPAT_PRECISION float WHATEVER;
#else
#define WHATEVER 0.0
#endif

const vec3 black_point = vec3(0.05, 0.08, 0.24);
const vec3 white_point = vec3(0.94, 0.90, 0.87);

const float im_saturation = 0.5;
const float im_contrast = 1.2;
const float im_brightness = 0.1;

const float noise1_min = 0.13;
const float noise1_max = 0.93;
const vec4 noise1_freq = vec4(1.4, 2.2, 3.8, 4.2);
const vec4 noise1_amp = vec4(2.5, 1.85, 1.22, 0.9);
const float noise1_threshold = 0.83;

const float noise2_min = 0.06;
const float noise2_max = 0.81;
const vec4 noise2_freq = vec4(0.75, 1.74, 2.12, 3.05);
const vec4 noise2_amp = vec4(2.2, 1.45, 1.12, 0.7);
const float noise2_threshold = 0.78;
const float noise2_saturation = 0.2;

const vec4 colhsh_freq = vec4(0.86, 1.32, 1.82, 2.25);
const vec4 colhsh_amp = vec4(1.45, 2.35, 1.12, 0.58);
const float colhsh_threshold = 0.92;
const float colhsh_intmin = 0.37;
const float colhsh_intmax = 0.40;

const vec4 colvsh_freq = vec4(0.46, 1.92, 3.82, 4.15);
const vec4 colvsh_amp = vec4(2.45, 1.35, 1.02, 0.5);
const float colvsh_threshold = 0.92;
const float colvsh_intmin = 2.80;
const float colvsh_intmax = 2.85;

const vec4 vsize_freq = vec4(0.045, 0.084, 0.112, 0.161);
const vec4 vsize_amp = vec4(1.6, 2.3, 2.7, 1.3);
const float vsize_threshold = 0.73;
const float vsize_factor = 0.21;

const mat3 im_convm = mat3( 1.0,  2.0,  -4.0,
                            2.0,  3.0,  3.0,
                           -2.0,  2.0,  1.0);

const mat3 noise_convm = mat3( 1.0,  2.0,  1.0,
                               2.0,  6.0,  0.0,
                              -2.0,  2.0,  1.0);

const float border_smoothness1 = 0.012;
const float border_smoothness2 = 0.020;
const float border_maxint = 1.16;

const float vig_falloff = 0.32;

const float emb_delta = 3.;
const float emb_int = 0.07;
const vec2 emb_speed = vec2(400., 100);

const float hosc_yfreq1 = 105.;
const float hosc_tfreq1 = 34.;
const float hosc_amp1 = 0.00036;
const float hosc_yfreq2 = 188.;
const float hosc_tfreq2 = 57.;
const float hosc_amp2 = 0.00024;

const float time_factor = 0.75;

float rand1(vec2 co)
{
    return fract(sin(dot(co.xy ,vec2(12.,85.5))) * 120.01);
}

float rand2(vec2 co)
{
    float r1 = fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
    return fract(sin(dot(vec2(r1, co.xy*1.562) ,vec2(12.9898,78.233))) * 43758.5453);
}

vec4 noise1(vec2 fragCoord)
{
	vec2 uvr = 1.1*fragCoord.xy / iResolution.xy + iTime*14.9;
    
    return vec4(vec3(rand1(uvr)*0.7+0.3), 1.0);   
}

vec4 noise2(vec2 fragCoord)
{
	vec2 uvr = 1.124*fragCoord.xy / iResolution.xy + iTime*3.3242;
    vec2 uvg = 2.549*fragCoord.xy / iResolution.xy + iTime*4.2623;
    vec2 uvb = 3.846*fragCoord.xy / iResolution.xy + iTime*6.2344;
    
    return vec4(mix(vec3(rand2(uvr))*1.5, vec3(rand2(uvr), rand2(uvg), rand2(uvb)), noise2_saturation), 1.0);
}

vec4 noise1conv(mat3 mat, vec2 pos)
{
   vec4 pixval = vec4(0.);
   float csum = 0.;
   
   for (int y=0; y<3; y++)
   {
       for (int x=0; x<3; x++)
       {
           vec2 ipos = pos + vec2(float(x-1), float(y-1));
           pixval+= noise1(ipos)*mat[x][y];
           csum+= mat[x][y];
       }
   }
   return pixval/csum; 
}

vec4 noise2conv(mat3 mat, vec2 pos)
{
   vec4 pixval = vec4(0.);
   float csum =0.;
   
   for (int y=0; y<3; y++)
   {
       for (int x=0; x<3; x++)
       {
           vec2 ipos = pos + vec2(float(x-1), float(y-1));
           pixval+= noise2(ipos)*mat[x][y];
           csum+= mat[x][y];
       }
   }
   return pixval/csum; 
}

float harms(vec4 freq, vec4 amp, float threshold)
{
   float val = 0.;
   for (int h=0; h<4; h++)
      val+= amp[h]*sin(iTime*time_factor*freq[h]);
   val = (1. + val/(amp[0]+amp[1]+amp[2]+amp[3]))/2.;
   return smoothstep(threshold, 1., val);
}

vec4 iconv(mat3 mat, vec2 pos)
{
   vec4 pixval = vec4(0.);
   float csum =0.;
   
   for (int y=0; y<3; y++)
   {
       for (int x=0; x<3; x++)
       {
           vec2 ipos = pos + vec2(float(x-1)/iResolution.x, float(y-1)/iResolution.y);
           pixval+= texture(texture2D, ipos)*mat[x][y];
           csum+= mat[x][y];
       }
   }
   return pixval/csum;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec4 im;
    vec2 uv0 = fragCoord.xy / iResolution.xy;
    vec2 uv = fragCoord.xy / iResolution.xy;
    
    float iTime2 = iTime*time_factor;
    
    // Vertical size
    float vsize_f = 1. + vsize_factor*harms(vsize_freq, vsize_amp, vsize_threshold);
    uv = uv*vec2(1., vsize_f) + vec2(0., (1.-vsize_f)/2.);
    float vsize_f2 = border_smoothness1 + border_smoothness2 - 0.005;
    uv.y*= 1. - 2.*vsize_f2;
    uv.y+= vsize_f2;
    
    // Side oscillations
    uv.x+= hosc_amp1*(sin(uv.y*hosc_yfreq1 + iTime2*hosc_tfreq1));
    uv.x+= hosc_amp2*(sin(uv.y*hosc_yfreq2 + iTime2*hosc_tfreq2));

    // Color specific dynamic shift
    float colhsh_d = harms(colhsh_freq, colhsh_amp, colhsh_threshold);
    float colvsh_d = harms(colvsh_freq, colvsh_amp, colvsh_threshold);
    
    vec2 uvr = mod(uv + vec2(colhsh_d*colhsh_intmin, colvsh_d*colvsh_intmin), 1.);
    vec2 uvg = mod(uv + vec2(colhsh_d*(colhsh_intmin + colhsh_intmax)/2., colvsh_d*(colvsh_intmin + colvsh_intmax)/2.), 1.);
    vec2 uvb = mod(uv + vec2(colhsh_d*colhsh_intmax, colvsh_d*colvsh_intmax), 1.);
    
    vec4 wcam;
    
    // Convolution
    //wcam.r = texture(iChannel0, uvr).r;
    //wcam.g = texture(iChannel0, uvg).g;
    //wcam.b = texture(iChannel0, uvb).b;
    wcam = iconv(im_convm, uvr); 
    wcam*= vsize_f;
    
    // Saturation
    wcam = mix(vec4((wcam.r + wcam.g + wcam.b)/3.), wcam, im_saturation);
    
    // Constrast
    wcam = wcam*im_contrast - 0.5*im_contrast + 0.5 + im_brightness;
    
    // Emboss
    vec2 d = iTime2 * emb_speed;
    vec2 uv1 = uv - d/iResolution.xy;
    vec2 uv2 = uv  + (vec2(emb_delta, emb_delta) - d)/iResolution.xy;
    uv1 = mod(uv1, 1.);
    uv2 = mod(uv2, 1.);
    vec4 embc = texture(iChannel0,uv2) - texture(iChannel0,uv1);
    float embi = emb_int*(embc.r + embc.g + embc.b)/3.;
    im = wcam + vec4(embi, embi, embi, 1.);
    
    // Pseudo-harmonic noise
    float noise1_b = harms(noise1_freq, noise1_amp, noise1_threshold)*(noise1_max-noise1_min)+noise1_min;
    im = mix(im, noise1conv(noise_convm, fragCoord), noise1_b);
    
    // White noise
    float noise2_b = harms(noise2_freq, noise2_amp, noise2_threshold)*(noise2_max-noise2_min)+noise2_min;
    im = mix(im, noise2conv(noise_convm, fragCoord), noise2_b);
    
    // Black and white point
    im = im*vec4(white_point - black_point, 1.) + vec4(black_point, 1.);
    
    // Vignette (www.shadertoy.com/view/4lSXDm)
    vec2 coord = (uv0 - 0.5) * (iResolution.x/iResolution.y) * 2.0;
    float rf = sqrt(dot(coord, coord)) * vig_falloff;
    float rf2_1 = rf * rf + 1.0;
    float e = 1.0 / (rf2_1 * rf2_1);
    im*= e;
    
    // Top/bottom borders
    float border_maxint2 = border_maxint*vsize_f;
    float border_smoothness22 = border_smoothness2*pow(vsize_f, 2.);
    im*= smoothstep(0., border_smoothness1, uv.y)*(1. - smoothstep(1.-border_smoothness1, 1., uv.y));
    im*= border_maxint2*(1./border_maxint2 + (1. - 1./border_maxint2)*(1. - smoothstep(border_smoothness1, border_smoothness1 + border_smoothness22, uv.y)));
    im*= border_maxint2*(1./border_maxint2 + (1. - 1./border_maxint2)*(smoothstep(1. - border_smoothness1 - border_smoothness22, 1. - border_smoothness1, uv.y)));    
    
    fragColor = im;
}
#endif

This is what errors I’m currently getting, I’m not sure what to do about the first three errors at all and I’m not sure what I should be switching ichannel0 with.

ERROR: 3:186: error(#229) Overloaded functions must have the same return type: vec4
ERROR: 3:193: error(#229) Overloaded functions must have the same return type: vec4
ERROR: 3:255: error(#202) No matching overloaded function found: texture
ERROR: 3:310: error(#143) Undeclared identifier: iChannel0
ERROR: 3:310: error(#202) No matching overloaded function found: texture
ERROR: 3:310: error(#202) No matching overloaded function found: texture

Sorry for bothering you.

1 Like

So, for the shadertoy uniforms, like iChannel0, iResolution and iTime, you’ll need to substitute things RetroArch’s shader system understands. The easiest way to do this (so you don’t have to change a bunch of stuff in the actual shader code) is to use preprocessor macros, like this:

#define iChannel0 Texture
#define iResolution TextureSize
#define iTime FrameCount

Just using bare FrameCount often makes the animations too fast, so you might try something like:

#define iTime (FrameCount / 60.0)

instead. You’ll also need to change the ‘void mainImage( stuff)’ line with the ‘void main()’ that was there before. It doesn’t need to be changed.

fragCoord.xy / iResolution.xy is really just trying to get the texture coordinate, so you can replace it with vTexCoord.xy.

EDIT: also, you’ll need to replace texture() with COMPAT_TEXTURE()

1 Like

Thank you so much for taking the time to help me with this, wish I could give you a star or something lol.

I’ll try these changes as soon as I get a chance!

I’ll let you know know how it goes either way.

Update: I’ve implemented everything you suggested, it’s still not working but I seem to be closer.

// version directive if necessary

// good place for credits/license

// Parameter lines go here:
#pragma parameter WHATEVER "Whatever" 0.0 0.0 1.0 1.0

#if defined(VERTEX)

#if __VERSION__ >= 130
#define COMPAT_VARYING out
#define COMPAT_ATTRIBUTE in
#define COMPAT_TEXTURE texture
#else
#define COMPAT_VARYING varying 
#define COMPAT_ATTRIBUTE attribute 
#define COMPAT_TEXTURE texture2D
#endif

#ifdef GL_ES
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif

COMPAT_ATTRIBUTE vec4 VertexCoord;
COMPAT_ATTRIBUTE vec4 COLOR;
COMPAT_ATTRIBUTE vec4 TexCoord;
COMPAT_VARYING vec4 COL0;
COMPAT_VARYING vec4 TEX0;
// out variables go here as COMPAT_VARYING whatever

vec4 _oPosition1; 
uniform mat4 MVPMatrix;
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;

// compatibility #defines
#define vTexCoord TEX0.xy
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
#define OutSize vec4(OutputSize, 1.0 / OutputSize)

#ifdef PARAMETER_UNIFORM
uniform COMPAT_PRECISION float WHATEVER;
#else
#define WHATEVER 0.0
#endif

void main()
{
    gl_Position = MVPMatrix * VertexCoord;
    TEX0.xy = TexCoord.xy;
// Paste vertex contents here:
}

#elif defined(FRAGMENT)

#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif

#if __VERSION__ >= 130
#define COMPAT_VARYING in
#define COMPAT_TEXTURE texture
out COMPAT_PRECISION vec4 FragColor;
#else
#define COMPAT_VARYING varying
#define FragColor gl_FragColor
#define COMPAT_TEXTURE texture2D
#endif

uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
uniform sampler2D Texture;
COMPAT_VARYING vec4 TEX0;
// in variables go here as COMPAT_VARYING whatever

// compatibility #defines
#define Source Texture
#define vTexCoord TEX0.xy

#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
#define OutSize vec4(OutputSize, 1.0 / OutputSize)

#define iChannel0 Texture
#define iResolution TextureSize
#define iTime (FrameCount / 60.0)

// delete all 'params.' or 'registers.' or whatever in the fragment and replace
// texture(a, b) with COMPAT_TEXTURE(a, b) <-can't macro unfortunately

#ifdef PARAMETER_UNIFORM
uniform COMPAT_PRECISION float WHATEVER;
#else
#define WHATEVER 0.0
#endif

const vec3 black_point = vec3(0.05, 0.08, 0.24);
const vec3 white_point = vec3(0.94, 0.90, 0.87);

const float im_saturation = 0.5;
const float im_contrast = 1.2;
const float im_brightness = 0.1;

const float noise1_min = 0.13;
const float noise1_max = 0.93;
const vec4 noise1_freq = vec4(1.4, 2.2, 3.8, 4.2);
const vec4 noise1_amp = vec4(2.5, 1.85, 1.22, 0.9);
const float noise1_threshold = 0.83;

const float noise2_min = 0.06;
const float noise2_max = 0.81;
const vec4 noise2_freq = vec4(0.75, 1.74, 2.12, 3.05);
const vec4 noise2_amp = vec4(2.2, 1.45, 1.12, 0.7);
const float noise2_threshold = 0.78;
const float noise2_saturation = 0.2;

const vec4 colhsh_freq = vec4(0.86, 1.32, 1.82, 2.25);
const vec4 colhsh_amp = vec4(1.45, 2.35, 1.12, 0.58);
const float colhsh_threshold = 0.92;
const float colhsh_intmin = 0.37;
const float colhsh_intmax = 0.40;

const vec4 colvsh_freq = vec4(0.46, 1.92, 3.82, 4.15);
const vec4 colvsh_amp = vec4(2.45, 1.35, 1.02, 0.5);
const float colvsh_threshold = 0.92;
const float colvsh_intmin = 2.80;
const float colvsh_intmax = 2.85;

const vec4 vsize_freq = vec4(0.045, 0.084, 0.112, 0.161);
const vec4 vsize_amp = vec4(1.6, 2.3, 2.7, 1.3);
const float vsize_threshold = 0.73;
const float vsize_factor = 0.21;

const mat3 im_convm = mat3( 1.0,  2.0,  -4.0,
                            2.0,  3.0,  3.0,
                           -2.0,  2.0,  1.0);

const mat3 noise_convm = mat3( 1.0,  2.0,  1.0,
                               2.0,  6.0,  0.0,
                              -2.0,  2.0,  1.0);

const float border_smoothness1 = 0.012;
const float border_smoothness2 = 0.020;
const float border_maxint = 1.16;

const float vig_falloff = 0.32;

const float emb_delta = 3.;
const float emb_int = 0.07;
const vec2 emb_speed = vec2(400., 100);

const float hosc_yfreq1 = 105.;
const float hosc_tfreq1 = 34.;
const float hosc_amp1 = 0.00036;
const float hosc_yfreq2 = 188.;
const float hosc_tfreq2 = 57.;
const float hosc_amp2 = 0.00024;

const float time_factor = 0.75;

float rand1(vec2 co)
{
    return fract(sin(dot(co.xy ,vec2(12.,85.5))) * 120.01);
}

float rand2(vec2 co)
{
    float r1 = fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
    return fract(sin(dot(vec2(r1, co.xy*1.562) ,vec2(12.9898,78.233))) * 43758.5453);
}

vec4 noise1(vec2 fragCoord)
{
	vec2 uvr = 1.1*fragCoord.xy / iResolution.xy + iTime*14.9;
    
    return vec4(vec3(rand1(uvr)*0.7+0.3), 1.0);   
}

vec4 noise2(vec2 fragCoord)
{
	vec2 uvr = 1.124*fragCoord.xy / iResolution.xy + iTime*3.3242;
    vec2 uvg = 2.549*fragCoord.xy / iResolution.xy + iTime*4.2623;
    vec2 uvb = 3.846*fragCoord.xy / iResolution.xy + iTime*6.2344;
    
    return vec4(mix(vec3(rand2(uvr))*1.5, vec3(rand2(uvr), rand2(uvg), rand2(uvb)), noise2_saturation), 1.0);
}

vec4 noise1conv(mat3 mat, vec2 pos)
{
   vec4 pixval = vec4(0.);
   float csum = 0.;
   
   for (int y=0; y<3; y++)
   {
       for (int x=0; x<3; x++)
       {
           vec2 ipos = pos + vec2(float(x-1), float(y-1));
           pixval+= noise1(ipos)*mat[x][y];
           csum+= mat[x][y];
       }
   }
   return pixval/csum; 
}

vec4 noise2conv(mat3 mat, vec2 pos)
{
   vec4 pixval = vec4(0.);
   float csum =0.;
   
   for (int y=0; y<3; y++)
   {
       for (int x=0; x<3; x++)
       {
           vec2 ipos = pos + vec2(float(x-1), float(y-1));
           pixval+= noise2(ipos)*mat[x][y];
           csum+= mat[x][y];
       }
   }
   return pixval/csum; 
}

float harms(vec4 freq, vec4 amp, float threshold)
{
   float val = 0.;
   for (int h=0; h<4; h++)
      val+= amp[h]*sin(iTime*time_factor*freq[h]);
   val = (1. + val/(amp[0]+amp[1]+amp[2]+amp[3]))/2.;
   return smoothstep(threshold, 1., val);
}

vec4 iconv(mat3 mat, vec2 pos)
{
   vec4 pixval = vec4(0.);
   float csum =0.;
   
   for (int y=0; y<3; y++)
   {
       for (int x=0; x<3; x++)
       {
           vec2 ipos = pos + vec2(float(x-1)/iResolution.x, float(y-1)/iResolution.y);
           pixval+= COMPAT_TEXTURE(texture2D, ipos)*mat[x][y];
           csum+= mat[x][y];
       }
   }
   return pixval/csum;
}

void main()
{
    vec4 im;
    vec2 uv0 = vTexCoord.xy;
    vec2 uv = vTexCoord.xy;
    
    float iTime2 = iTime*time_factor;
    
    // Vertical size
    float vsize_f = 1. + vsize_factor*harms(vsize_freq, vsize_amp, vsize_threshold);
    uv = uv*vec2(1., vsize_f) + vec2(0., (1.-vsize_f)/2.);
    float vsize_f2 = border_smoothness1 + border_smoothness2 - 0.005;
    uv.y*= 1. - 2.*vsize_f2;
    uv.y+= vsize_f2;
    
    // Side oscillations
    uv.x+= hosc_amp1*(sin(uv.y*hosc_yfreq1 + iTime2*hosc_tfreq1));
    uv.x+= hosc_amp2*(sin(uv.y*hosc_yfreq2 + iTime2*hosc_tfreq2));

    // Color specific dynamic shift
    float colhsh_d = harms(colhsh_freq, colhsh_amp, colhsh_threshold);
    float colvsh_d = harms(colvsh_freq, colvsh_amp, colvsh_threshold);
    
    vec2 uvr = mod(uv + vec2(colhsh_d*colhsh_intmin, colvsh_d*colvsh_intmin), 1.);
    vec2 uvg = mod(uv + vec2(colhsh_d*(colhsh_intmin + colhsh_intmax)/2., colvsh_d*(colvsh_intmin + colvsh_intmax)/2.), 1.);
    vec2 uvb = mod(uv + vec2(colhsh_d*colhsh_intmax, colvsh_d*colvsh_intmax), 1.);
    
    vec4 wcam;
    
    // Convolution
    //wcam.r = COMPAT_TEXTURE(iChannel0, uvr).r;
    //wcam.g = COMPAT_TEXTURE(iChannel0, uvg).g;
    //wcam.b = COMPAT_TEXTURE(iChannel0, uvb).b;
    wcam = iconv(im_convm, uvr); 
    wcam*= vsize_f;
    
    // Saturation
    wcam = mix(vec4((wcam.r + wcam.g + wcam.b)/3.), wcam, im_saturation);
    
    // Constrast
    wcam = wcam*im_contrast - 0.5*im_contrast + 0.5 + im_brightness;
    
    // Emboss
    vec2 d = iTime2 * emb_speed;
    vec2 uv1 = uv - d/iResolution.xy;
    vec2 uv2 = uv  + (vec2(emb_delta, emb_delta) - d)/iResolution.xy;
    uv1 = mod(uv1, 1.);
    uv2 = mod(uv2, 1.);
    vec4 embc = COMPAT_TEXTURE(iChannel0,uv2) - COMPAT_TEXTURE(iChannel0,uv1);
    float embi = emb_int*(embc.r + embc.g + embc.b)/3.;
    im = wcam + vec4(embi, embi, embi, 1.);
/*    
    // Pseudo-harmonic noise
    float noise1_b = harms(noise1_freq, noise1_amp, noise1_threshold)*(noise1_max-noise1_min)+noise1_min;
    im = mix(im, noise1conv(noise_convm, fragCoord), noise1_b);
    
    // White noise
    float noise2_b = harms(noise2_freq, noise2_amp, noise2_threshold)*(noise2_max-noise2_min)+noise2_min;
    im = mix(im, noise2conv(noise_convm, fragCoord), noise2_b);
*/
    // Black and white point
    im = im*vec4(white_point - black_point, 1.) + vec4(black_point, 1.);
    
    // Vignette (www.shadertoy.com/view/4lSXDm)
    vec2 coord = (uv0 - 0.5) * (iResolution.x/iResolution.y) * 2.0;
    float rf = sqrt(dot(coord, coord)) * vig_falloff;
    float rf2_1 = rf * rf + 1.0;
    float e = 1.0 / (rf2_1 * rf2_1);
    im*= e;
    
    // Top/bottom borders
    float border_maxint2 = border_maxint*vsize_f;
    float border_smoothness22 = border_smoothness2*pow(vsize_f, 2.);
    im*= smoothstep(0., border_smoothness1, uv.y)*(1. - smoothstep(1.-border_smoothness1, 1., uv.y));
    im*= border_maxint2*(1./border_maxint2 + (1. - 1./border_maxint2)*(1. - smoothstep(border_smoothness1, border_smoothness1 + border_smoothness22, uv.y)));
    im*= border_maxint2*(1./border_maxint2 + (1. - 1./border_maxint2)*(smoothstep(1. - border_smoothness1 - border_smoothness22, 1. - border_smoothness1, uv.y)));    
    
    vec4 fragColor = im;
}
#endif

These are my errors now:

ERROR: 3:186: error(#229) Overloaded functions must have the same return type: vec4
ERROR: 3:193: error(#229) Overloaded functions must have the same return type: vec4
ERROR: 3:255: error(#202) No matching overloaded function found: texture2D

I also had a fragCoord error at lines 316 and 320, I commented that section out for time being. The fragCoord error had to do with it not being defined.

You were close. I fixed the last couple of things for you:

// version directive if necessary

// good place for credits/license

// Parameter lines go here:
#pragma parameter WHATEVER "Whatever" 0.0 0.0 1.0 1.0

#if defined(VERTEX)

#if __VERSION__ >= 130
#define COMPAT_VARYING out
#define COMPAT_ATTRIBUTE in
#define COMPAT_TEXTURE texture
#else
#define COMPAT_VARYING varying 
#define COMPAT_ATTRIBUTE attribute 
#define COMPAT_TEXTURE texture2D
#endif

#ifdef GL_ES
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif

COMPAT_ATTRIBUTE vec4 VertexCoord;
COMPAT_ATTRIBUTE vec4 TexCoord;
COMPAT_VARYING vec4 TEX0;
// out variables go here as COMPAT_VARYING whatever

uniform mat4 MVPMatrix;
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;

// compatibility #defines
#define vTexCoord TEX0.xy
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
#define OutSize vec4(OutputSize, 1.0 / OutputSize)

#ifdef PARAMETER_UNIFORM
uniform COMPAT_PRECISION float WHATEVER;
#else
#define WHATEVER 0.0
#endif

void main()
{
    gl_Position = MVPMatrix * VertexCoord;
    TEX0.xy = TexCoord.xy;
// Paste vertex contents here:
}

#elif defined(FRAGMENT)

#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif

#if __VERSION__ >= 130
#define COMPAT_VARYING in
#define COMPAT_TEXTURE texture
out COMPAT_PRECISION vec4 FragColor;
#else
#define COMPAT_VARYING varying
#define FragColor gl_FragColor
#define COMPAT_TEXTURE texture2D
#endif

uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
uniform sampler2D Texture;
COMPAT_VARYING vec4 TEX0;
// in variables go here as COMPAT_VARYING whatever

// compatibility #defines
#define Source Texture
#define vTexCoord TEX0.xy

#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
#define OutSize vec4(OutputSize, 1.0 / OutputSize)

#define iChannel0 Texture
#define iResolution TextureSize
#define iTime (float(FrameCount) / 60.0)

// delete all 'params.' or 'registers.' or whatever in the fragment and replace
// texture(a, b) with COMPAT_TEXTURE(a, b) <-can't macro unfortunately

#ifdef PARAMETER_UNIFORM
uniform COMPAT_PRECISION float WHATEVER;
#else
#define WHATEVER 0.0
#endif

const vec3 black_point = vec3(0.05, 0.08, 0.24);
const vec3 white_point = vec3(0.94, 0.90, 0.87);

const float im_saturation = 0.5;
const float im_contrast = 1.2;
const float im_brightness = 0.1;

const float noise1_min = 0.13;
const float noise1_max = 0.93;
const vec4 noise1_freq = vec4(1.4, 2.2, 3.8, 4.2);
const vec4 noise1_amp = vec4(2.5, 1.85, 1.22, 0.9);
const float noise1_threshold = 0.83;

const float noise2_min = 0.06;
const float noise2_max = 0.81;
const vec4 noise2_freq = vec4(0.75, 1.74, 2.12, 3.05);
const vec4 noise2_amp = vec4(2.2, 1.45, 1.12, 0.7);
const float noise2_threshold = 0.78;
const float noise2_saturation = 0.2;

const vec4 colhsh_freq = vec4(0.86, 1.32, 1.82, 2.25);
const vec4 colhsh_amp = vec4(1.45, 2.35, 1.12, 0.58);
const float colhsh_threshold = 0.92;
const float colhsh_intmin = 0.37;
const float colhsh_intmax = 0.40;

const vec4 colvsh_freq = vec4(0.46, 1.92, 3.82, 4.15);
const vec4 colvsh_amp = vec4(2.45, 1.35, 1.02, 0.5);
const float colvsh_threshold = 0.92;
const float colvsh_intmin = 2.80;
const float colvsh_intmax = 2.85;

const vec4 vsize_freq = vec4(0.045, 0.084, 0.112, 0.161);
const vec4 vsize_amp = vec4(1.6, 2.3, 2.7, 1.3);
const float vsize_threshold = 0.73;
const float vsize_factor = 0.21;

const mat3 im_convm = mat3( 1.0,  2.0,  -4.0,
                            2.0,  3.0,  3.0,
                           -2.0,  2.0,  1.0);

const mat3 noise_convm = mat3( 1.0,  2.0,  1.0,
                               2.0,  6.0,  0.0,
                              -2.0,  2.0,  1.0);

const float border_smoothness1 = 0.012;
const float border_smoothness2 = 0.020;
const float border_maxint = 1.16;

const float vig_falloff = 0.32;

const float emb_delta = 3.;
const float emb_int = 0.07;
const vec2 emb_speed = vec2(400., 100);

const float hosc_yfreq1 = 105.;
const float hosc_tfreq1 = 34.;
const float hosc_amp1 = 0.00036;
const float hosc_yfreq2 = 188.;
const float hosc_tfreq2 = 57.;
const float hosc_amp2 = 0.00024;

const float time_factor = 0.75;

float rand1(vec2 co)
{
    return fract(sin(dot(co.xy ,vec2(12.,85.5))) * 120.01);
}

float rand2(vec2 co)
{
    float r1 = fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
    return fract(sin(dot(vec2(r1, co.xy*1.562) ,vec2(12.9898,78.233))) * 43758.5453);
}

vec4 noise1(vec2 fragCoord)
{
	vec2 uvr = 1.1*fragCoord.xy / iResolution.xy + vec2(iTime)*14.9;
    
    return vec4(vec3(rand1(uvr)*0.7+0.3), 1.0);   
}

vec4 noise2(vec2 fragCoord)
{
	vec2 uvr = 1.124*fragCoord.xy / iResolution.xy + iTime*3.3242;
    vec2 uvg = 2.549*fragCoord.xy / iResolution.xy + iTime*4.2623;
    vec2 uvb = 3.846*fragCoord.xy / iResolution.xy + iTime*6.2344;
    
    return vec4(mix(vec3(rand2(uvr))*1.5, vec3(rand2(uvr), rand2(uvg), rand2(uvb)), noise2_saturation), 1.0);
}

vec4 noise1conv(mat3 mat, vec2 pos)
{
   vec4 pixval = vec4(0.);
   float csum = 0.;
   
   for (int y=0; y<3; y++)
   {
       for (int x=0; x<3; x++)
       {
           vec2 ipos = pos + vec2(float(x-1), float(y-1));
           pixval+= noise1(ipos)*mat[x][y];
           csum+= mat[x][y];
       }
   }
   return pixval/csum; 
}

vec4 noise2conv(mat3 mat, vec2 pos)
{
   vec4 pixval = vec4(0.);
   float csum =0.;
   
   for (int y=0; y<3; y++)
   {
       for (int x=0; x<3; x++)
       {
           vec2 ipos = pos + vec2(float(x-1), float(y-1));
           pixval+= noise2(ipos)*mat[x][y];
           csum+= mat[x][y];
       }
   }
   return pixval/csum; 
}

float harms(vec4 freq, vec4 amp, float threshold)
{
   float val = 0.;
   for (int h=0; h<4; h++)
      val+= amp[h]*sin(iTime*time_factor*freq[h]);
   val = (1. + val/(amp[0]+amp[1]+amp[2]+amp[3]))/2.;
   return smoothstep(threshold, 1., val);
}

vec4 iconv(mat3 mat, vec2 pos)
{
   vec4 pixval = vec4(0.);
   float csum =0.;
   
   for (int y=0; y<3; y++)
   {
       for (int x=0; x<3; x++)
       {
           vec2 ipos = pos + vec2(float(x-1)/iResolution.x, float(y-1)/iResolution.y);
           pixval+= COMPAT_TEXTURE(Texture, ipos)*mat[x][y];
           csum+= mat[x][y];
       }
   }
   return pixval/csum;
}

void main()
{
    vec4 im;
    vec2 uv0 = vTexCoord.xy;
    vec2 uv = vTexCoord.xy;
    vec2 fragCoord = gl_FragCoord.xy;
    
    float iTime2 = iTime*time_factor;
    
    // Vertical size
    float vsize_f = 1. + vsize_factor*harms(vsize_freq, vsize_amp, vsize_threshold);
    uv = uv*vec2(1., vsize_f) + vec2(0., (1.-vsize_f)/2.);
    float vsize_f2 = border_smoothness1 + border_smoothness2 - 0.005;
    uv.y*= 1. - 2.*vsize_f2;
    uv.y+= vsize_f2;
    
    // Side oscillations
    uv.x+= hosc_amp1*(sin(uv.y*hosc_yfreq1 + iTime2*hosc_tfreq1));
    uv.x+= hosc_amp2*(sin(uv.y*hosc_yfreq2 + iTime2*hosc_tfreq2));

    // Color specific dynamic shift
    float colhsh_d = harms(colhsh_freq, colhsh_amp, colhsh_threshold);
    float colvsh_d = harms(colvsh_freq, colvsh_amp, colvsh_threshold);
    
    vec2 uvr = mod(uv + vec2(colhsh_d*colhsh_intmin, colvsh_d*colvsh_intmin), 1.);
    vec2 uvg = mod(uv + vec2(colhsh_d*(colhsh_intmin + colhsh_intmax)/2., colvsh_d*(colvsh_intmin + colvsh_intmax)/2.), 1.);
    vec2 uvb = mod(uv + vec2(colhsh_d*colhsh_intmax, colvsh_d*colvsh_intmax), 1.);
    
    vec4 wcam;
    
    // Convolution
    wcam.r = COMPAT_TEXTURE(iChannel0, uvr).r;
    wcam.g = COMPAT_TEXTURE(iChannel0, uvg).g;
    wcam.b = COMPAT_TEXTURE(iChannel0, uvb).b;
    wcam = iconv(im_convm, uvr); 
    wcam*= vsize_f;
    
    // Saturation
    wcam = mix(vec4((wcam.r + wcam.g + wcam.b)/3.), wcam, im_saturation);
    
    // Constrast
    wcam = wcam*im_contrast - 0.5*im_contrast + 0.5 + im_brightness;
    
    // Emboss
    vec2 d = iTime2 * emb_speed;
    vec2 uv1 = uv - d/iResolution.xy;
    vec2 uv2 = uv  + (vec2(emb_delta, emb_delta) - d)/iResolution.xy;
    uv1 = mod(uv1, 1.);
    uv2 = mod(uv2, 1.);
    vec4 embc = COMPAT_TEXTURE(iChannel0,uv2) - COMPAT_TEXTURE(iChannel0,uv1);
    float embi = emb_int*(embc.r + embc.g + embc.b)/3.;
    im = wcam + vec4(embi, embi, embi, 1.);
   
    // Pseudo-harmonic noise
    float noise1_b = harms(noise1_freq, noise1_amp, noise1_threshold)*(noise1_max-noise1_min)+noise1_min;
    im = mix(im, noise1conv(noise_convm, fragCoord), noise1_b);
    
    // White noise
    float noise2_b = harms(noise2_freq, noise2_amp, noise2_threshold)*(noise2_max-noise2_min)+noise2_min;
    im = mix(im, noise2conv(noise_convm, fragCoord), noise2_b);

    // Black and white point
    im = im*vec4(white_point - black_point, 1.) + vec4(black_point, 1.);
    
    // Vignette (www.shadertoy.com/view/4lSXDm)
    vec2 coord = (uv0 - 0.5) * (iResolution.x/iResolution.y) * 2.0;
    float rf = sqrt(dot(coord, coord)) * vig_falloff;
    float rf2_1 = rf * rf + 1.0;
    float e = 1.0 / (rf2_1 * rf2_1);
    im*= e;
    
    // Top/bottom borders
    float border_maxint2 = border_maxint*vsize_f;
    float border_smoothness22 = border_smoothness2*pow(vsize_f, 2.);
    im*= smoothstep(0., border_smoothness1, uv.y)*(1. - smoothstep(1.-border_smoothness1, 1., uv.y));
    im*= border_maxint2*(1./border_maxint2 + (1. - 1./border_maxint2)*(1. - smoothstep(border_smoothness1, border_smoothness1 + border_smoothness22, uv.y)));
    im*= border_maxint2*(1./border_maxint2 + (1. - 1./border_maxint2)*(smoothstep(1. - border_smoothness1 - border_smoothness22, 1. - border_smoothness1, uv.y)));    
    
    FragColor = im;
}
#endif
1 Like

Not to bother you, but could you explain what you did? I’ve spotted most of the changes but it would be nice to know what I was screwing up.

Thanks so much for getting it working, I really do appreciate all your help and everything you for the community.

The FrameCount uniform is an int, so it needed be explicitly cast to a float. That’s what the “operand” errors were about.

One of the sampling functions had COMPAT_TEXTURE(texture2D, uv-something… so that “texture2D” needed to be just Texture (or Source or iChannel0; they all resolve to Texture anyway in this case).

There was a fragCoord.xy that I switched to gl_FragCoord.xy, which is a built-in thing in GLSL that points to actual screen coordinates (good for making effects that tie to actual monitor pixels, like mask effects). We try not to use it in slang shaders, though, and instead use the usually-identical ‘vTexCoord * OutputSize.xy’

The output statement needed to change from vec4 fragColor to just ‘FragColor’, since that’s what the fragment outputs to.

I think that was it.

1 Like

Hmmmm, I half understand what you’re saying (that’s a me issue though), but I appreciate you taking the time to explain it to me (you explained it well, I just have zero formal education to how any of this works).

That covers all the changes I was able to find with a quick once over. So I think you explained everything, lol.

This is supposed to be in GLSL right?

I just tried to run it and I’m still getting this, but that’s the only error it’s throwing now.

ERROR: 3:183: error(#229) Overloaded functions must have the same return type: vec4
ERROR: 3:190: error(#229) Overloaded functions must have the same return type: vec4

I copy and pasted your code block into a clean GLSL file.

That’s a frustrating thing about GLSL: different GPUs and compilers will choke on different things :confused:

To fix that, the noise1 and noise2 functions need to be renamed because they conflict with built-in GLSL functions. I renamed them to _noise1 and _noise2 throughout the code and that seemed to work fine.

EDIT: to add insult to injury, I just learned that no vendors actually even implement noise1/2/3/4. They all just return 0.0. What a drag >_>

1 Like

Hang on, did changing the noise names fix it or not? I’m confused.

If it helps any I have an XFX AMD Radeon RX 460.

EDIT: Nevermind, actually got a chance to hop on the PC. Changing the noise names finally got it running. Oof though, that looks harsher then I thought it was going to look like. It does run now!

@hunterk Sorry to necro this thread but I have a shadertoy related question.

How do I do this in retroarch, like is just a straight port or do I have to do other things for it to work properly?

highp float rand(vec2 co)
{
    highp float a = 12.9898;
    highp float b = 78.233;
    highp float c = 43758.5453;
    highp float dt= dot(co.xy ,vec2(a,b));
    highp float sn= mod(dt,3.14);
    return fract(sin(sn) * c);
}

That’s from this, if you’d like reference. https://www.shadertoy.com/view/MsK3zw

That should work as-is, though you probably want to change the "highp"s to COMPAT_PRECISIONs

1 Like

Could you elaborate some? I’m kind of lost.

COMPAT_PRECISION float rand(vec2 co)
{
    COMPAT_PRECISION float a = 12.9898;
    COMPAT_PRECISION float b = 78.233;
    COMPAT_PRECISION float c = 43758.5453;
    COMPAT_PRECISION float dt= dot(co.xy ,vec2(a,b));
    COMPAT_PRECISION float sn= mod(dt,3.14);
    return fract(sin(sn) * c);
}
1 Like