GLSL Shaders using Processing Pi on a Pi 3 B+

Hey All,

It’s the first time I’m porting over a glsl shader from Processing OSX to run on Processing Pi running on a Raspberry Pi 3 B+. I have a very basic shader that dissolves between two videos playing. It runs totally fine on my mac but when it’s ported to Processing Pi and updated to use the Processing video library GLvideo instead it is throwing an error.

The shader was converted from a ShaderToy post so maybe there’s some compatibility issues? I looked around and wasn’t able to find anything specific that I think would cause this problem. So any references, pointers or help would be greatly appreciated.

The error that I am getting is below:

Cannot link shader program:
ERROR:LEX/PARSE-2 (fragment shader, line 27) Undefined identifier

I’ve added a more verbose error output, apologies that it’s a screenshot… Processing Pi wasn’t allowing me to copy the full error message.

I’ve pased the code sample below but I’ve also linked to a Dropbox folder w/ the source example that I’m working on. It’s: https://www.dropbox.com/sh/z1spn3bv1jkq233/AABsQGFLsM-cdeBeyrMi47KOa?dl=0

_
shaderDisolve_4.pde

import gohai.glvideo.*;

PShader secondShader;  

PGraphics pg;
PGraphics pg2;

GLMovie movie;
GLMovie movie2;

void setup() {
  size(600, 600, P2D);
  noSmooth();
  pg = createGraphics(600, 600, P2D);

  movie = new GLMovie(this, "Timelapse_HD_Sunrise_Sunset_France_1080p.mp4");
  movie.loop();

  movie2 = new GLMovie(this, "y2mate.com-10MinuteRealtimeBurningFireplaceinFullHD1080p_mFcSPt0sEuk_360p.mp4");
  movie2.loop();

  pg = createGraphics(width, height, P2D);
  pg2 = createGraphics(width, height, P2D);

  secondShader = loadShader("secondShader.glsl");
  secondShader.set("iResolution", float(width), float(height));
  secondShader.set("iTime", millis()/1000.);

}  

void movieEvent(GLMovie m) {
  m.read();
  redraw();
}

void draw() {
  
  pg.beginDraw();
    pg.image(movie, 0, 0, width, height);
  pg.endDraw();

  pg2.beginDraw();
    pg2.image(movie2, 0, 0, width, height);
  pg2.endDraw();

  secondShader.set("iTime", millis()/1000.);
  secondShader.set("iChannel0", pg);
  secondShader.set("iChannel1", pg2);
  
  shader(secondShader);
  rect(0, 0, width, height);
  
}

_
secondShader.glsl

#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif

// Type of shader expected by Processing
#define PROCESSING_COLOR_SHADER

uniform float iTime;
uniform sampler2D iChannel0;
uniform sampler2D iChannel1;
uniform vec2 iResolution;

void mainImage( out vec4 fragColor, in vec2 fragCoord );

void main() {
    mainImage(gl_FragColor,gl_FragCoord.xy);
}

#define TEXTURED 1

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 q = fragCoord.xy/iResolution.xy;
    
    // https://www.shadertoy.com/view/4s3XRf

    vec2 uv = fragCoord.xy / iResolution.xy;
    vec4 color0 = texture(iChannel0, uv);
    vec4 color1 = texture(iChannel1, uv);
    float duration = 10.0;
    
    float t = mod(float(iTime), duration) / duration;
    
    fragColor = mix(color0, color1, t);

}

On a more general note, is there a difference between .glsl written for a mac vs. Linux machine?

I appreciate the help,

Cheers,

1 Like

Hi @jshaw3 – were you able to resolve this issue? I am not a GLSL expert, but the ShaderToy porting guide / example in this thread might be helpful:

Hey @jeremydouglass, thanks for the additional references. I went through them, and I was still getting errors, so no not yet. I tried a few different things, including re-writing the shader to work outside of the “ShaderToy” nomenclature. I resized the videos to be smaller, updated the Pi’s GPU memory to 256mb etc. I ensured it still works on OSX, but when it’s run on a Raspberry Pi 3B+ the sketch is an empty white screen.

The only output in the console is:

Final caps: video/x-raw(memory:GLMemory), format=(string)RGBA, width=(int)640, height=(int)360, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)25/1, texture-target=(string)2D
Final caps: video/x-raw(memory:GLMemory), format=(string)RGBA, width=(int)640, height=(int)360, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)25/1, texture-target=(string)2D

Perhaps there’s no support to set PGraphics from Processing to a sampler2D texture in the shader on processing pi? It crossed my mind there’s something with GLVideo images when you set a texture3D. Also, maybe it’s the I’m mixing up something between how frag and color shaders work. At the moment I think I’m only using a Processing Color Shader.

shaderDisolveGLSL.pde

//import processing.video.*;
import gohai.glvideo.*;

PShader mixShader;  

PGraphics pg;
PGraphics pg2;

//Movie movie;
//Movie movie2;

GLMovie movie;
GLMovie movie2;

void setup() {
  size(640, 360, P2D);
  noSmooth();
  pg = createGraphics(640, 360, P2D);

  //movie = new Movie(this, "_sm/LabspaceDawnv1blur2.mp4");
  movie = new GLMovie(this, "_sm/LabspaceDawnv1blur2.mp4");
  movie.loop();

  //movie2 = new Movie(this, "_sm/LabspaceFireblur2.mp4");
  movie2 = new GLMovie(this, "_sm/LabspaceFireblur2.mp4");
  movie2.loop();

  pg = createGraphics(width, height, P2D);
  pg2 = createGraphics(width, height, P2D);

  mixShader = loadShader("fadeshader.glsl");
  mixShader.set("iResolution", float(width), float(height));
  mixShader.set("iTime", millis()/1000.);

  mixShader.set("iChannel0", pg);
  mixShader.set("iChannel1", pg2);

}  

//void movieEvent(Movie m) {
void movieEvent(GLMovie m) {
  m.read();
  redraw();
}

void draw() {
  
  pg.beginDraw();
    pg.image(movie, 0, 0, width, height);
  pg.endDraw();

  pg2.beginDraw();
    pg2.image(movie2, 0, 0, width, height);
  pg2.endDraw();
  
  shader(mixShader);
  rect(0, 0, width, height);
  
}

fadeshader.glsl

#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif

// Type of shader expected by Processing
#define PROCESSING_COLOR_SHADER

uniform float iTime;
uniform sampler2D iChannel0;
uniform sampler2D iChannel1;
uniform vec2 iResolution;

void main() {
    
    vec2 uv = gl_FragCoord.xy / iResolution.xy;
    vec4 mixColor = vec4(0.0);
    vec4 color0 = vec4(uv.x,uv.y,0.0,1.0);
    vec4 color1 = vec4(uv.x,uv.y,0.0,1.0);

    color0 = texture2D(iChannel0, uv);
    color1 = texture2D(iChannel1, uv);

    float duration = 10.0;
    float t = mod(float(iTime), duration) / duration;
    
    mixColor = mix(color0, color1, t);
    gl_FragColor = mixColor;
}

I’ve updated a new version of the sample sketch with the smaller videos here if anyone was curious: https://www.dropbox.com/sh/fu2plxmqhf7shtp/AADxqmW9zf73EsdzworCb5ECa?dl=0

Any recommendations or areas of thought for me to look more into would be greatly appreciated!

1 Like