Basic PShader Issue

Having some trouble passing an PImage to PShader. Doing something wrong, but can’t figure it out. First I’m trying to work with image before moving to video.

tks in advance.

basic code

PShader displace;
PImage moon;
boolean isMoon=true;
PVector moonXNoise;
PVector moonYNoise;

void setup() {
  size(1920, 1080, P3D);
  imageMode(CENTER);

 //Moon Setup
  moon=loadImage("06_lua.jpg");
  displace=loadShader("displaceFrag.glsl", "displaceVert.glsl");
  displace.set("resolution", float(width), float(height));
}

void draw() {
background(0);

if (isMoon) {
    float luax=0.5;
    moonXNoise=new PVector(luax, luax, luax);
    moonYNoise=new PVector(-luax, -luax, -luax);
    displace.set("time", millis()/1000.0);
    displace.set("tex", moon);
    displace.set("x_noise", moonXNoise);
    displace.set("y_noise", moonYNoise);

    shader(displace);
    rect(0, 0, width, height);
    //image(moon,0,0);
  }
}

displaceFrag.glsl

#version 150

uniform float time;
uniform vec2 resolution;
uniform sampler2DRect tex;
uniform vec3 x_noise;
uniform vec3 y_noise;

out vec4 outputColor;

// 2D Random
float random (in vec2 st) {
    return fract(sin(dot(st.xy,
                         vec2(12.9898,78.233)))
                 * 43758.5453123);
}

// 2D Noise based on Morgan McGuire @morgan3d
// https://www.shadertoy.com/view/4dS3Wd
float noise (in vec2 st) {
    vec2 i = floor(st);
    vec2 f = fract(st);

    // Four corners in 2D of a tile
    float a = random(i);
    float b = random(i + vec2(1.0, 0.0));
    float c = random(i + vec2(0.0, 1.0));
    float d = random(i + vec2(1.0, 1.0));

    // Smooth Interpolation

    // Cubic Hermine Curve.  Same as SmoothStep()
    vec2 u = f*f*(3.0-2.0*f);
    // u = smoothstep(0.,1.,f);

    // Mix 4 coorners percentages
    return mix(a, b, u.x) +
            (c - a)* u.y * (1.0 - u.x) +
            (d - b) * u.x * u.y;
}

void main() {

  vec2 p = (gl_FragCoord.xy * 2.0 - resolution) / min(resolution.x, resolution.y);

  float drift = 60.0;
  float r = texture(tex, vec2(gl_FragCoord.x + drift * noise(vec2(p.x + x_noise.r, p.y + time)), (resolution.y - gl_FragCoord.y) + drift * noise(vec2(p.x + time, p.y + y_noise.r)))).r;
  float g = texture(tex, vec2(gl_FragCoord.x + drift * noise(vec2(p.x + x_noise.g, p.y + time)), (resolution.y - gl_FragCoord.y) + drift * noise(vec2(p.x + time, p.y + y_noise.g)))).g;
  float b = texture(tex, vec2(gl_FragCoord.x + drift * noise(vec2(p.x + x_noise.b, p.y + time)), (resolution.y - gl_FragCoord.y) + drift * noise(vec2(p.x + time, p.y + y_noise.b)))).b;
  outputColor = vec4(r, g, b, 1.0);
}

displaceVert.glsl

#version 150

uniform mat4 modelViewProjectionMatrix;
in vec4 position;

void main(){
	gl_Position = modelViewProjectionMatrix * position;
}
1 Like

I think it might be need to use sampler2D rather than sampler2DRect, although always useful to specify what not working means! :slight_smile:

Also you might need to be aware of the texture matrix for the PImage - see this issue which is still outstanding (but fixed in PraxisLIVE) - https://github.com/processing/processing/issues/3437

not working = black screen, nothing happens. if i use a simple color shader it works fine

the original link is here: https://junkiyoshi.com/openframeworks20180905/ . i’m translating it to processing.

I tried making it work. Here are the first steps to fix it.

  • The screen is black, so I make float r = 1.0; in the fragment shader expecting the rect to turn red.
  • It doesn’t, so I compare to the default shaders from Processing. I see that they don’t use modelViewProjectionMatrix but transformMatrix so I make that change and it turns red. Good.
  • Next, I see that in my shaders I use texture2D instead of texture so I make that change. Then it fails to compile, because sampler2DRect should be sampler2D in that case. After that change, it compiles and I get a purple color that I think comes from the image.
  • I think the scale of the image is wrong, maybe related to not using Rect anymore.
  • I try setting float r = texture2D(tex, gl_FragCoord.xy/1000.0).r; to confirm that is a scaling issue (see the divided by 1000 to scale it down) and it seems to be the case: now I see the image.
  • So I try this:
  vec2 uv = gl_FragCoord.xy;
  uv.x /= resolution.x;
  uv.y /= resolution.y;

  float r = texture2D(tex, vec2(
        uv.x + drift * noise(vec2(p.x + x_noise.r, p.y + time)), 
        (resolution.y - uv.y) + drift * noise(vec2(p.x + time, p.y + y_noise.r)))).r;
  float g = texture2D(tex, vec2(
        uv.x + drift * noise(vec2(p.x + x_noise.g, p.y + time)), 
        (resolution.y - uv.y) + drift * noise(vec2(p.x + time, p.y + y_noise.g)))).g;
  float b = texture2D(tex, vec2(
        uv.x + drift * noise(vec2(p.x + x_noise.b, p.y + time)), 
        (resolution.y - uv.y) + drift * noise(vec2(p.x + time, p.y + y_noise.b)))).b;

Which gives me an animated noise effect. Not sure if that what it should do, but it looks interesting :slight_smile:

Maybe this helps you get started?


(I made it a bit brighter in gimp because it was probably too dark for this forum)

2 Likes