How to apply a shader to a PGraphics object?

edited February 2017 in Questions about Code

I'm fairly new to shaders and am beginning to like them because of their capabilities in terms of speed an parallelism. What I'd like to do is to apply a certain shader not to the whole sketch, but only to a certain PGraphics image, is that possible?

When using filter(), everything works fine. I just apply it after drawing everything else to the PGraphics.
When trying to use shader(), I call pg.shader(myShader) before drawing any objects to the PGraphics (because that's how shaders work, right?), and in between pg.beginDraw() and pg.endDraw(), but without success. I've tried other combinations, but they don't work either.

What am I missing?

Answers

  • but they don't work

    we hate it when people say this. what doesn't work? in what way doesn't it work?

    post a runnable example.

  • edited February 2017

    Sorrrrry, by "not working" I mean that the shader is not applied, it acts like the default shader is applied.

    Here's an example of what's working fine:

     PShader blur;  
     PGraphics pg;
    
     void setup() {
        size(500, 500, P2D);
        blur = loadShader("blur.glsl");
    
        pg = createGraphics(500, 500, P2D);
        pg.beginDraw();
        // pg.shader(blur);
        pg.background(200, 40, 60);
        pg.noStroke();
        pg.fill(22);
        pg.ellipse(pg.width/2, pg.height/2, 40, 40);
        pg.endDraw();
    
     }
    
     void draw() {
        shader(blur);
        image(pg, 0, 0);
     }
    

    and here's an example that's not applying the shader:

     PShader blur;  
     PGraphics pg;
    
     void setup() {
        size(500, 500, P2D);
        blur = loadShader("blur.glsl");
    
        pg = createGraphics(500, 500, P2D);
        pg.beginDraw();
        pg.shader(blur);
        pg.background(200, 40, 60);
        pg.noStroke();
        pg.fill(22);
        pg.ellipse(pg.width/2, pg.height/2, 40, 40);
        pg.endDraw();
    
     }
    
     void draw() {
        // shader(blur);
        image(pg, 0, 0);
     }
    

    With which I'm getting a warning: Your shader needs to be of COLOR type to render this geometry properly, using default shader instead.

    The difference between the two codes is in the lines 10 and 20 where I'm changing places where the shader is applied (in the first one I apply it to the whole sketch, and in the other I'm applying it to the PGraphics object).

    Here's the shader code, I'm not sure where should apply the suggested fix that I'm getting in the warning message.

    #ifdef GL_ES
    precision mediump float;
    precision mediump int;
    #endif
    
    #define PROCESSING_TEXTURE_SHADER
    
    uniform sampler2D texture;
    uniform vec2 texOffset;
    
    varying vec4 vertColor;
    varying vec4 vertTexCoord;
    
    void main(void) {
        vec2 tc0 = vertTexCoord.st + vec2(-texOffset.s, -texOffset.t);
        vec2 tc1 = vertTexCoord.st + vec2(         0.0, -texOffset.t);
        vec2 tc2 = vertTexCoord.st + vec2(+texOffset.s, -texOffset.t);
        vec2 tc3 = vertTexCoord.st + vec2(-texOffset.s,          0.0);
        vec2 tc4 = vertTexCoord.st + vec2(         0.0,          0.0);
        vec2 tc5 = vertTexCoord.st + vec2(+texOffset.s,          0.0);
        vec2 tc6 = vertTexCoord.st + vec2(-texOffset.s, +texOffset.t);
        vec2 tc7 = vertTexCoord.st + vec2(         0.0, +texOffset.t);
        vec2 tc8 = vertTexCoord.st + vec2(+texOffset.s, +texOffset.t);
    
        vec4 col0 = texture2D(texture, tc0);
        vec4 col1 = texture2D(texture, tc1);
        vec4 col2 = texture2D(texture, tc2);
        vec4 col3 = texture2D(texture, tc3);
        vec4 col4 = texture2D(texture, tc4);
        vec4 col5 = texture2D(texture, tc5);
        vec4 col6 = texture2D(texture, tc6);
        vec4 col7 = texture2D(texture, tc7);
        vec4 col8 = texture2D(texture, tc8);
    
        vec4 sum = (1.0 * col0 + 2.0 * col1 + 1.0 * col2 +  
                                2.0 * col3 + 4.0 * col4 + 2.0 * col5 +
                                1.0 * col6 + 2.0 * col7 + 1.0 * col8) / 16.0;            
        gl_FragColor = vec4(sum.rgb, 1.0) * vertColor;  
    }
    
  • Answer ✓

    re: COLOR

    have you read this:

    https://processing.org/tutorials/pshader/

    specifically the section: "Types of shaders in Processing"

  • Answer ✓

    where are you setting the texture? i don't think you are, hence it thinking you have a color shader rather than a texture shader.

  • edited February 2017

    Uh.. I get what you're saying and am realizing that this is more complicated than I thought. I see the COLOR/TEXTURE problem, but I'm not sure how to fix it. Should I change the shader code or the Processing code?

    I guess I should just read the Shaders tutorial more thoroughly.

  • But I'm not sure what the texture should be. In the examples it's clear, but if you just want to blur things you have drawn using geometry it's not so obvious.

    Maybe pass the (unblurred) pg in as the texture, applying the blur in draw? Think you may need to draw using a textured PShape rather than image() in draw ()

Sign In or Register to comment.