简体   繁体   中英

Processing fragment shader not displaying anything

I seem to be having an issue getting a shader to work in Processing. I am working on an ink effect, and after getting some help to write the rest of the shader, I can't seem to get anything to happen. The color stays black, and when I change gl_FragColor = vertColor; (which Processing reserves for color), the image becomes white. From what I understand, it should just pass straight through in that case, so now I believe something might be wrong. Does anyone have some advice?

EDIT: I've made some changes to try to match it closer to what I see in other processing shaders. Instead of vertColor I am now using sampler2D(source,coord).rgb, which is still not working.

PShader shader;
PImage photo;

void setup() {
  size(619,619,P2D);
  photo = loadImage("paintedsky.jpg");
  shader = loadShader("inkspread.glsl");
}

void draw() {
  shader.set("T",(float) millis()/1000.0);
  shader(shader);
  image(photo,619,619);
}

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

#define PROCESSING_TEXTURE_SHADER

uniform sampler2D source;
varying vec4 vertTexCoord;

uniform float T;
const float diag = 1.414213562373095;

vec3 F(vec3 x0,vec3 x1,float dist){
    return (x1 - x0)/(T * dist);
}

void main() {
    vec2 ix  = vertTexCoord.st;

    vec2 c11 = vertTexCoord.st + vec2( 0.0, 0.0);
    vec2 c01 = vertTexCoord.st + vec2(-1.0, 0.0);
    vec2 c21 = vertTexCoord.st + vec2( 1.0, 0.0);
    vec2 c10 = vertTexCoord.st + vec2( 0.0,-1.0);
    vec2 c12 = vertTexCoord.st + vec2( 0.0, 1.0);
    vec2 c00 = vertTexCoord.st + vec2(-1.0,-1.0);
    vec2 c02 = vertTexCoord.st + vec2(-1.0, 1.0);
    vec2 c20 = vertTexCoord.st + vec2( 1.0,-1.0);
    vec2 c22 = vertTexCoord.st + vec2( 1.0, 1.0);

    vec3 x11 = texture2D(source, c11).rgb;
    vec3 x01 = texture2D(source, c01).rgb;
    vec3 x21 = texture2D(source, c21).rgb;
    vec3 x10 = texture2D(source, c10).rgb;
    vec3 x12 = texture2D(source, c12).rgb;
    vec3 x00 = texture2D(source, c00).rgb;
    vec3 x02 = texture2D(source, c02).rgb;
    vec3 x20 = texture2D(source, c20).rgb;
    vec3 x22 = texture2D(source, c22).rgb;

    vec3 d01 = F(x11,x01,1.0);  
    vec3 d21 = F(x11,x21,1.0);  
    vec3 d10 = F(x11,x10,1.0);  
    vec3 d12 = F(x11,x12,1.0);  
    vec3 d00 = F(x11,x00,diag); 
    vec3 d02 = F(x11,x02,diag); 
    vec3 d20 = F(x11,x20,diag); 
    vec3 d22 = F(x11,x22,diag); 

    vec3 result = (x11 + d01+d21+d10+d12 + d00+d02+d20+d22);

    vec3 col = texture2D(source, ix).rgb;
    gl_FragColor = vec4(col*result,1.0);
}

The color stays black, and when I change gl_FragColor = vertColor; (which Processing reserves for colro), the image becomes white.

I assume that vertColor is the position of the vertex interpreted as color. In that case, everything above 1 is clamped to 1, so if you have the vertex position at (1,1,1) the color is white. If you vertex position is at (2,2,2), it will be clamped to (1,1,1) and therefore the color is white again. You would have a non-white color where at least one of the position values is <1. For testing purposes you could try to scale your vertColor here from 0 ( formerly the lowest of the position coordinates) to 1 (formerly the highest of your position coordiantes)

I cant answer on your original question, as you do a lot of float calculations but there is no way to determine, what would be set as gl_FragColor

There are a couple of problems with your code:

1) In inkspread.glsl , you've defined uniform sampler2D source , however you've never set this uniform on your shader. If you want to pass a PImage or PGraphics object into a shader via this uniform, you'd have to call shader.set("source", photo) in the same way you're passing in T for time. HOWEVER, Processing already gives you a texture for free. If you change source to texture throughout your shader file, Processing will automagically pass the main drawing canvas into your shader's uniform sampler2D texture . Your varying vertTexCoord is another special property that Processing automatically hands your fragment shader. There are a few more of those, but I don't think they're currently well-documented.

2) The second issue is the order of your image() & shader() calls. Since your shader is intended to post-process an image, you'll want to draw your image first, then call the shader to act on the main drawing canvas. Then everything should work properly. It should look like this:

void draw() {
    image(photo,619,619);
    shader.set("T",(float) millis()/1000.0);
    shader(shader);
}

I've tested this fix, and everything works. I'm not sure what the intended effect is, but your shader gave my photo a nice darken/saturation effect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM