处理片段着色器不显示任何内容

Processing fragment shader not displaying anything

我似乎在让着色器在 Processing 中工作时遇到了问题。我正在研究墨水效果,在获得一些帮助来编写着色器的其余部分后,我似乎无法发生任何事情。颜色保持黑色,当我改变 gl_FragColor = vertColor; (Processing 为颜色保留),图像变为白色。据我了解,在那种情况下它应该直接通过,所以现在我认为可能有问题。有人有什么建议吗?

编辑:我做了一些更改以尝试使其更接近我在其他处理着色器中看到的内容。我现在使用 sampler2D(source,coord).rgb 而不是 vertColor,它仍然无法正常工作。

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.

我假设 vertColor 是解释为颜色的顶点的位置。在这种情况下,高于 1 的所有内容都被限制为 1,因此如果顶点位置在 (1,1,1) 处,则颜色为白色。如果您的顶点位置在 (2,2,2),它将被限制在 (1,1,1),因此颜色再次变为白色。 您将拥有一种非白色颜色,其中至少一个位置值 <1。 出于测试目的,您可以尝试将此处的 vertColor 从 0(以前是位置坐标的最低值)缩放到 1(以前是位置坐标的最高值)

我无法回答你原来的问题,因为你做了很多浮点数计算但无法确定,将设置为 gl_FragColor

您的代码有几个问题:

1) 在 inkspread.glsl 中,您已经定义了 uniform sampler2D source,但是您从未在着色器上设置此 uniform。如果你想通过这个 uniform 将 PImage 或 PGraphics 对象传递到着色器中,你必须调用 shader.set("source", photo) 就像你在 T 中传递时间一样。但是,Processing 已经免费为您提供纹理。如果在整个着色器文件中将 source 更改为 texture,Processing 将自动将主绘图 canvas 传递到着色器的 uniform sampler2D texture 中。您的 varying vertTexCoord 是 Processing 自动交给您的片段着色器的另一个特殊 属性。还有一些,但我认为它们目前没有得到很好的记录。

2) 第二个问题是 image() 和 shader() 调用的顺序。由于您的着色器旨在 post 处理图像,因此您需要先绘制图像,然后调用着色器对主绘图进行操作 canvas。然后一切都应该正常工作。它应该是这样的:

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

我已经测试了这个修复,一切正常。我不确定预期的效果是什么,但你的着色器给我的照片带来了不错的 darken/saturation 效果。