ppixels, feedback, and colors / determining the color at a location of texture

edited July 7 in GLSL / Shaders

Trying to get a feedback system working with shaders, and as a first-step, was simply trying to get colours to swap on each draw call. I have this working, but if I try using the few lines in my shader that are commented out, things stop working:

EDIT: Looked at the Conway game of life example, and it makes sense. To rephrase the question then - -- can I draw some shapes and have that be the initial texture that the shader uses? How? -- and why am I able to invert colours with swizzle but not able to discern where the red pixels are with a step function / if statement?

PDE file:

PShader fragShader;
PGraphics pg;

void setup() {
  size(600,600,P2D);
  frameRate(1);

  fragShader = loadShader("diffusion.frag");
  fragShader.set("resolution", float(width), float(height));

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


void draw() {

  pg.beginDraw();
    pg.fill(0);
    pg.rect(0,0,pg.width, pg.height);
    pg.noStroke();
    pg.fill(255, 0,0);
    pg.ellipse(300,300,150,150);
    pg.shader(fragShader);
    pg.rect(0, 0, pg.width, pg.height);
  pg.endDraw();

  image(pg, 0, 0);
}

SHADER:

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

uniform vec2 resolution;
uniform sampler2D ppixels;

vec2 psize = 1./resolution.xy;


void main() {
  vec2 st = gl_FragCoord.xy/resolution.xy;

  vec4 tc = texture(ppixels, st);

  //float isRed = step(0.9, tc.r);
  //vec3 col = isRed*vec3(0., 1., 0.) + (1.-isRed)*vec3(1.,0.,0.);


  // gl_FragColor = vec4(col, 1.);
  gl_FragColor = tc.grba;
}

The ellipse's red and green values swap succesfully with this. However, if I use the 3 commented-out lines instead, ie use the step function to calculate if the texture isRed, I lose the ellipse -- all the pixels seem to return 1.0 at the step function, so the entire screen flashes between red and green...

Tried using an if statement instead of step - but same result.

Any help would be much appreciated! Thank you!

Answers

  • edited July 8 Answer ✓

    For anyone who stumbles upon here -- figured it out. Most of the examples for feedback shaders I came across didn't need an initial texture that was drawn in processing itself. To do this, draw to a PGraphics object, convert it to a PImage, and pass that to the shader. I also passed a flag to indicate if it was the first frame, so the PImage was sampled instead of ppixels. Code:

    PDE:

            PShader fragShader;
            PGraphics pg;
    
            void setup() {
              size(600,600,P3D);
              frameRate(1);
    
              fragShader = loadShader("diffusion.frag");
              fragShader.set("resolution", float(width), float(height));
              pg = createGraphics(width, height, P3D);
              pg.noSmooth();
    
              pg.beginDraw();
                pg.fill(0);
                pg.rect(0,0,pg.width, pg.height);
                pg.noStroke();
                pg.fill(255, 0,0);
                pg.ellipse(300,300,150,150);
              pg.endDraw();
              fragShader.set("initialtex", pg.get());
              fragShader.set("firstFrame", 1.0);
            }  
    
    
            void draw() {
              pg.beginDraw();
                pg.background(0);
                pg.shader(fragShader);
                pg.rect(0,0,pg.width,pg.height);
              pg.endDraw();
              image(pg, 0, 0, width, height);
              fragShader.set("firstFrame", 0.0);
            }
    

    SHADER:

    #define PROCESSING_COLOR_SHADER
    
    #ifdef GL_ES
    precision highp float;
    precision mediump int;
    #endif
    
    uniform vec2 resolution;
    uniform sampler2D ppixels;
    uniform sampler2D initialtex;
    
    uniform float firstFrame;
    
    vec2 psize = 1./resolution.xy;
    
    // vec4 getColorAt(vec2 pos, vec2 offset) {
    //   return texture2D(ppixels, pos + (psize*offset));
    // }
    
    void main() {
    
      vec2 st = gl_FragCoord.xy/resolution.xy;
    
    
      vec4 tc;
      if(firstFrame > 0.) {
        tc = texture2D(initialtex, st);
      } else {
        tc = texture2D(ppixels, st);
      }
    
      float isRed = step(0.9, tc.r);
      vec3 col = isRed*vec3(0., 1., 0.) + (1.-isRed)*vec3(1.,0.,0.);
    
    
      gl_FragColor = vec4(col, 1.);
    }
    
Sign In or Register to comment.