Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Glsl 使用着色器实现粘性效果(处理3)_Glsl_Processing_Shader_Colormatrix_Colormatrixfilter - Fatal编程技术网

Glsl 使用着色器实现粘性效果(处理3)

Glsl 使用着色器实现粘性效果(处理3),glsl,processing,shader,colormatrix,colormatrixfilter,Glsl,Processing,Shader,Colormatrix,Colormatrixfilter,我试图复制一个名为“”的网页设计技巧(请现场观看)。 这是一种将SVG过滤器应用于移动椭圆以获得类似水滴的运动的技术。过程相当简单: 应用高斯模糊 仅增加alpha通道的对比度 两者的结合会产生水滴效果 最后一步(增加alpha通道对比度)通常通过“颜色矩阵过滤器”完成 颜色矩阵由5列(RGBA+偏移)和4行组成 前四列中的值分别与源红色、绿色、蓝色和alpha值相乘。第五列值是添加的(偏移量) 在CSS中,增加alpha通道对比度非常简单,只需调用SVG过滤器并指定对比度值(此处为1

我试图复制一个名为“”的网页设计技巧(请现场观看)。 这是一种将SVG过滤器应用于移动椭圆以获得类似水滴的运动的技术。过程相当简单:

  • 应用高斯模糊
  • 仅增加alpha通道的对比度
两者的结合会产生水滴效果

最后一步(增加alpha通道对比度)通常通过“颜色矩阵过滤器”完成

颜色矩阵由5列(RGBA+偏移)和4行组成

前四列中的值分别与源红色、绿色、蓝色和alpha值相乘。第五列值是添加的(偏移量)

在CSS中,增加alpha通道对比度非常简单,只需调用SVG过滤器并指定对比度值(此处为18):

但在处理过程中,它似乎有点复杂。我相信(我可能错了)应用颜色矩阵过滤器的唯一方法是在着色器中创建一个。经过几次尝试后,我提出了这些(非常基本的)用于颜色渲染的顶点和片段着色器:

colorvert.glsl

uniform mat4 transform;
attribute vec4 position;
attribute vec4 color;
varying vec4 vertColor;

uniform vec4 o=vec4(0, 0, 0, -9); 
uniform lowp mat4 colorMatrix = mat4(1.0, 0.0, 0.0, 0.0, 
                                     0.0, 1.0, 0.0, 0.0, 
                                     0.0, 0.0, 1.0, 0.0, 
                                     0.0, 0.0, 0.0, 60.0);


void main() {
  gl_Position = transform * position; 
  vertColor = (color * colorMatrix) + o  ;
}
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif

varying vec4 vertColor;

void main() {
  gl_FragColor = vertColor;
}
/ Adapted from:
// <a href="http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html" target="_blank" rel="nofollow">http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html</a>

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

#define PROCESSING_TEXTURE_SHADER


uniform sampler2D texture;

uniform vec4 o=vec4(0, 0, 0, 0); 
uniform lowp mat4 colorMatrix = mat4(1, 0.0, 0.0, 0.0, 
                                     0.0, 1, 0.0, 0.0, 
                                     0.0, 0.0, 1, 0.0, 
                                     0, 0.0, 0.0, 60.0); //Alpha contrast set to 60


varying vec2 center;

// The inverse of the texture dimensions along X and Y
uniform vec2 texOffset;

varying vec4 vertColor;
varying vec4 vertTexCoord;

uniform int blurSize;       
uniform int horizontalPass; // 0 or 1 to indicate vertical or horizontal pass
uniform float sigma;        // The sigma value for the gaussian function: higher value means more blur
                            // A good value for 9x9 is around 3 to 5
                            // A good value for 7x7 is around 2.5 to 4
                            // A good value for 5x5 is around 2 to 3.5
                            // ... play around with this based on what you need <span class="Emoticon Emoticon1"><span>:)</span></span>

const float pi = 3.14159265;

void main() {  
  float numBlurPixelsPerSide = float(blurSize / 2); 

  vec2 blurMultiplyVec = 0 < horizontalPass ? vec2(1.0, 0.0) : vec2(0.0, 1.0);

  // Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889)
  vec3 incrementalGaussian;
  incrementalGaussian.x = 1.0 / (sqrt(2.0 * pi) * sigma);
  incrementalGaussian.y = exp(-0.5 / (sigma * sigma));
  incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;

  vec4 avgValue = vec4(0.0, 0.0, 0.0, 0.0);
  float coefficientSum = 0.0;

  // Take the central sample first...
  avgValue += texture2D(texture, vertTexCoord.st) * incrementalGaussian.x;
  coefficientSum += incrementalGaussian.x;
  incrementalGaussian.xy *= incrementalGaussian.yz;

  // Go through the remaining 8 vertical samples (4 on each side of the center)
  for (float i = 1.0; i <= numBlurPixelsPerSide; i++) { 
    avgValue += texture2D(texture, vertTexCoord.st - i * texOffset * 
                          blurMultiplyVec) * incrementalGaussian.x;         
    avgValue += texture2D(texture, vertTexCoord.st + i * texOffset * 
                          blurMultiplyVec) * incrementalGaussian.x;         
    coefficientSum += 2.0 * incrementalGaussian.x;
    incrementalGaussian.xy *= incrementalGaussian.yz;
  }
  gl_FragColor = (avgValue / coefficientSum )  * colorMatrix;
}
// Adapted from:
// <a href="http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html" target="_blank" rel="nofollow">http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html</a>

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


#define PROCESSING_TEXTURE_SHADER

uniform sampler2D texture;

// The inverse of the texture dimensions along X and Y
uniform vec2 texOffset;

varying vec4 vertColor;
varying vec4 vertTexCoord;

uniform int blurSize;       
uniform int horizontalPass; // 0 or 1 to indicate vertical or horizontal pass
uniform float sigma;        // The sigma value for the gaussian function: higher value means more blur
                            // A good value for 9x9 is around 3 to 5
                            // A good value for 7x7 is around 2.5 to 4
                            // A good value for 5x5 is around 2 to 3.5
                            // ... play around with this based on what you need <span class="Emoticon Emoticon1"><span>:)</span></span>

const float pi = 3.14159265;

void main() {  
  float numBlurPixelsPerSide = float(blurSize / 2); 

  vec2 blurMultiplyVec = 0 < horizontalPass ? vec2(1.0, 0.0) : vec2(0.0, 1.0);

  // Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889)
  vec3 incrementalGaussian;
  incrementalGaussian.x = 1.0 / (sqrt(2.0 * pi) * sigma);
  incrementalGaussian.y = exp(-0.5 / (sigma * sigma));
  incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;

  vec4 avgValue = vec4(0.0, 0.0, 0.0, 0.0);
  float coefficientSum = 0.0;

  // Take the central sample first...
  avgValue += texture2D(texture, vertTexCoord.st) * incrementalGaussian.x;
  coefficientSum += incrementalGaussian.x;
  incrementalGaussian.xy *= incrementalGaussian.yz;

  // Go through the remaining 8 vertical samples (4 on each side of the center)
  for (float i = 1.0; i <= numBlurPixelsPerSide; i++) { 
    avgValue += texture2D(texture, vertTexCoord.st - i * texOffset * 
                          blurMultiplyVec) * incrementalGaussian.x;         
    avgValue += texture2D(texture, vertTexCoord.st + i * texOffset * 
                          blurMultiplyVec) * incrementalGaussian.x;         
    coefficientSum += 2.0 * incrementalGaussian.x;
    incrementalGaussian.xy *= incrementalGaussian.yz;
  }

  gl_FragColor = avgValue / coefficientSum;
}
#define PROCESSING_TEXTURE_SHADER

uniform sampler2D texture;
varying vec4 vertTexCoord;

uniform vec4 o = vec4(0, 0, 0, -7.0); 
uniform lowp mat4 colorMatrix = mat4(1.0, 0.0, 0.0, 0.0, 
                                     0.0, 1.0, 0.0, 0.0, 
                                     0.0, 0.0, 1.0, 0.0, 
                                     0.0, 0.0, 0.0, 18.0);

void main() {
  vec4 pix = texture2D(texture, vertTexCoord.st);

  vec4 color = (pix * colorMatrix) + o;
  gl_FragColor = color;
}
colorfrag.glsl

uniform mat4 transform;
attribute vec4 position;
attribute vec4 color;
varying vec4 vertColor;

uniform vec4 o=vec4(0, 0, 0, -9); 
uniform lowp mat4 colorMatrix = mat4(1.0, 0.0, 0.0, 0.0, 
                                     0.0, 1.0, 0.0, 0.0, 
                                     0.0, 0.0, 1.0, 0.0, 
                                     0.0, 0.0, 0.0, 60.0);


void main() {
  gl_Position = transform * position; 
  vertColor = (color * colorMatrix) + o  ;
}
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif

varying vec4 vertColor;

void main() {
  gl_FragColor = vertColor;
}
/ Adapted from:
// <a href="http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html" target="_blank" rel="nofollow">http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html</a>

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

#define PROCESSING_TEXTURE_SHADER


uniform sampler2D texture;

uniform vec4 o=vec4(0, 0, 0, 0); 
uniform lowp mat4 colorMatrix = mat4(1, 0.0, 0.0, 0.0, 
                                     0.0, 1, 0.0, 0.0, 
                                     0.0, 0.0, 1, 0.0, 
                                     0, 0.0, 0.0, 60.0); //Alpha contrast set to 60


varying vec2 center;

// The inverse of the texture dimensions along X and Y
uniform vec2 texOffset;

varying vec4 vertColor;
varying vec4 vertTexCoord;

uniform int blurSize;       
uniform int horizontalPass; // 0 or 1 to indicate vertical or horizontal pass
uniform float sigma;        // The sigma value for the gaussian function: higher value means more blur
                            // A good value for 9x9 is around 3 to 5
                            // A good value for 7x7 is around 2.5 to 4
                            // A good value for 5x5 is around 2 to 3.5
                            // ... play around with this based on what you need <span class="Emoticon Emoticon1"><span>:)</span></span>

const float pi = 3.14159265;

void main() {  
  float numBlurPixelsPerSide = float(blurSize / 2); 

  vec2 blurMultiplyVec = 0 < horizontalPass ? vec2(1.0, 0.0) : vec2(0.0, 1.0);

  // Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889)
  vec3 incrementalGaussian;
  incrementalGaussian.x = 1.0 / (sqrt(2.0 * pi) * sigma);
  incrementalGaussian.y = exp(-0.5 / (sigma * sigma));
  incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;

  vec4 avgValue = vec4(0.0, 0.0, 0.0, 0.0);
  float coefficientSum = 0.0;

  // Take the central sample first...
  avgValue += texture2D(texture, vertTexCoord.st) * incrementalGaussian.x;
  coefficientSum += incrementalGaussian.x;
  incrementalGaussian.xy *= incrementalGaussian.yz;

  // Go through the remaining 8 vertical samples (4 on each side of the center)
  for (float i = 1.0; i <= numBlurPixelsPerSide; i++) { 
    avgValue += texture2D(texture, vertTexCoord.st - i * texOffset * 
                          blurMultiplyVec) * incrementalGaussian.x;         
    avgValue += texture2D(texture, vertTexCoord.st + i * texOffset * 
                          blurMultiplyVec) * incrementalGaussian.x;         
    coefficientSum += 2.0 * incrementalGaussian.x;
    incrementalGaussian.xy *= incrementalGaussian.yz;
  }
  gl_FragColor = (avgValue / coefficientSum )  * colorMatrix;
}
// Adapted from:
// <a href="http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html" target="_blank" rel="nofollow">http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html</a>

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


#define PROCESSING_TEXTURE_SHADER

uniform sampler2D texture;

// The inverse of the texture dimensions along X and Y
uniform vec2 texOffset;

varying vec4 vertColor;
varying vec4 vertTexCoord;

uniform int blurSize;       
uniform int horizontalPass; // 0 or 1 to indicate vertical or horizontal pass
uniform float sigma;        // The sigma value for the gaussian function: higher value means more blur
                            // A good value for 9x9 is around 3 to 5
                            // A good value for 7x7 is around 2.5 to 4
                            // A good value for 5x5 is around 2 to 3.5
                            // ... play around with this based on what you need <span class="Emoticon Emoticon1"><span>:)</span></span>

const float pi = 3.14159265;

void main() {  
  float numBlurPixelsPerSide = float(blurSize / 2); 

  vec2 blurMultiplyVec = 0 < horizontalPass ? vec2(1.0, 0.0) : vec2(0.0, 1.0);

  // Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889)
  vec3 incrementalGaussian;
  incrementalGaussian.x = 1.0 / (sqrt(2.0 * pi) * sigma);
  incrementalGaussian.y = exp(-0.5 / (sigma * sigma));
  incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;

  vec4 avgValue = vec4(0.0, 0.0, 0.0, 0.0);
  float coefficientSum = 0.0;

  // Take the central sample first...
  avgValue += texture2D(texture, vertTexCoord.st) * incrementalGaussian.x;
  coefficientSum += incrementalGaussian.x;
  incrementalGaussian.xy *= incrementalGaussian.yz;

  // Go through the remaining 8 vertical samples (4 on each side of the center)
  for (float i = 1.0; i <= numBlurPixelsPerSide; i++) { 
    avgValue += texture2D(texture, vertTexCoord.st - i * texOffset * 
                          blurMultiplyVec) * incrementalGaussian.x;         
    avgValue += texture2D(texture, vertTexCoord.st + i * texOffset * 
                          blurMultiplyVec) * incrementalGaussian.x;         
    coefficientSum += 2.0 * incrementalGaussian.x;
    incrementalGaussian.xy *= incrementalGaussian.yz;
  }

  gl_FragColor = avgValue / coefficientSum;
}
#define PROCESSING_TEXTURE_SHADER

uniform sampler2D texture;
varying vec4 vertTexCoord;

uniform vec4 o = vec4(0, 0, 0, -7.0); 
uniform lowp mat4 colorMatrix = mat4(1.0, 0.0, 0.0, 0.0, 
                                     0.0, 1.0, 0.0, 0.0, 
                                     0.0, 0.0, 1.0, 0.0, 
                                     0.0, 0.0, 0.0, 18.0);

void main() {
  vec4 pix = texture2D(texture, vertTexCoord.st);

  vec4 color = (pix * colorMatrix) + o;
  gl_FragColor = color;
}
问题:

颜色矩阵部分工作:更改RGB值确实会影响颜色,但更改alpha值(最后一行)不会

尝试将着色器与高斯过滤器组合时,即使我将alpha通道对比度设置为60(如codepen示例中),绘制的椭圆仍会保持模糊:

当我在@cansik的高斯模糊(来自PostFX库)中实现颜色矩阵时,也会发生同样的事情。我可以看到颜色变化,但无法看到alpha对比度:

blurFrag.glsl

uniform mat4 transform;
attribute vec4 position;
attribute vec4 color;
varying vec4 vertColor;

uniform vec4 o=vec4(0, 0, 0, -9); 
uniform lowp mat4 colorMatrix = mat4(1.0, 0.0, 0.0, 0.0, 
                                     0.0, 1.0, 0.0, 0.0, 
                                     0.0, 0.0, 1.0, 0.0, 
                                     0.0, 0.0, 0.0, 60.0);


void main() {
  gl_Position = transform * position; 
  vertColor = (color * colorMatrix) + o  ;
}
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif

varying vec4 vertColor;

void main() {
  gl_FragColor = vertColor;
}
/ Adapted from:
// <a href="http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html" target="_blank" rel="nofollow">http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html</a>

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

#define PROCESSING_TEXTURE_SHADER


uniform sampler2D texture;

uniform vec4 o=vec4(0, 0, 0, 0); 
uniform lowp mat4 colorMatrix = mat4(1, 0.0, 0.0, 0.0, 
                                     0.0, 1, 0.0, 0.0, 
                                     0.0, 0.0, 1, 0.0, 
                                     0, 0.0, 0.0, 60.0); //Alpha contrast set to 60


varying vec2 center;

// The inverse of the texture dimensions along X and Y
uniform vec2 texOffset;

varying vec4 vertColor;
varying vec4 vertTexCoord;

uniform int blurSize;       
uniform int horizontalPass; // 0 or 1 to indicate vertical or horizontal pass
uniform float sigma;        // The sigma value for the gaussian function: higher value means more blur
                            // A good value for 9x9 is around 3 to 5
                            // A good value for 7x7 is around 2.5 to 4
                            // A good value for 5x5 is around 2 to 3.5
                            // ... play around with this based on what you need <span class="Emoticon Emoticon1"><span>:)</span></span>

const float pi = 3.14159265;

void main() {  
  float numBlurPixelsPerSide = float(blurSize / 2); 

  vec2 blurMultiplyVec = 0 < horizontalPass ? vec2(1.0, 0.0) : vec2(0.0, 1.0);

  // Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889)
  vec3 incrementalGaussian;
  incrementalGaussian.x = 1.0 / (sqrt(2.0 * pi) * sigma);
  incrementalGaussian.y = exp(-0.5 / (sigma * sigma));
  incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;

  vec4 avgValue = vec4(0.0, 0.0, 0.0, 0.0);
  float coefficientSum = 0.0;

  // Take the central sample first...
  avgValue += texture2D(texture, vertTexCoord.st) * incrementalGaussian.x;
  coefficientSum += incrementalGaussian.x;
  incrementalGaussian.xy *= incrementalGaussian.yz;

  // Go through the remaining 8 vertical samples (4 on each side of the center)
  for (float i = 1.0; i <= numBlurPixelsPerSide; i++) { 
    avgValue += texture2D(texture, vertTexCoord.st - i * texOffset * 
                          blurMultiplyVec) * incrementalGaussian.x;         
    avgValue += texture2D(texture, vertTexCoord.st + i * texOffset * 
                          blurMultiplyVec) * incrementalGaussian.x;         
    coefficientSum += 2.0 * incrementalGaussian.x;
    incrementalGaussian.xy *= incrementalGaussian.yz;
  }
  gl_FragColor = (avgValue / coefficientSum )  * colorMatrix;
}
// Adapted from:
// <a href="http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html" target="_blank" rel="nofollow">http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html</a>

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


#define PROCESSING_TEXTURE_SHADER

uniform sampler2D texture;

// The inverse of the texture dimensions along X and Y
uniform vec2 texOffset;

varying vec4 vertColor;
varying vec4 vertTexCoord;

uniform int blurSize;       
uniform int horizontalPass; // 0 or 1 to indicate vertical or horizontal pass
uniform float sigma;        // The sigma value for the gaussian function: higher value means more blur
                            // A good value for 9x9 is around 3 to 5
                            // A good value for 7x7 is around 2.5 to 4
                            // A good value for 5x5 is around 2 to 3.5
                            // ... play around with this based on what you need <span class="Emoticon Emoticon1"><span>:)</span></span>

const float pi = 3.14159265;

void main() {  
  float numBlurPixelsPerSide = float(blurSize / 2); 

  vec2 blurMultiplyVec = 0 < horizontalPass ? vec2(1.0, 0.0) : vec2(0.0, 1.0);

  // Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889)
  vec3 incrementalGaussian;
  incrementalGaussian.x = 1.0 / (sqrt(2.0 * pi) * sigma);
  incrementalGaussian.y = exp(-0.5 / (sigma * sigma));
  incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;

  vec4 avgValue = vec4(0.0, 0.0, 0.0, 0.0);
  float coefficientSum = 0.0;

  // Take the central sample first...
  avgValue += texture2D(texture, vertTexCoord.st) * incrementalGaussian.x;
  coefficientSum += incrementalGaussian.x;
  incrementalGaussian.xy *= incrementalGaussian.yz;

  // Go through the remaining 8 vertical samples (4 on each side of the center)
  for (float i = 1.0; i <= numBlurPixelsPerSide; i++) { 
    avgValue += texture2D(texture, vertTexCoord.st - i * texOffset * 
                          blurMultiplyVec) * incrementalGaussian.x;         
    avgValue += texture2D(texture, vertTexCoord.st + i * texOffset * 
                          blurMultiplyVec) * incrementalGaussian.x;         
    coefficientSum += 2.0 * incrementalGaussian.x;
    incrementalGaussian.xy *= incrementalGaussian.yz;
  }

  gl_FragColor = avgValue / coefficientSum;
}
#define PROCESSING_TEXTURE_SHADER

uniform sampler2D texture;
varying vec4 vertTexCoord;

uniform vec4 o = vec4(0, 0, 0, -7.0); 
uniform lowp mat4 colorMatrix = mat4(1.0, 0.0, 0.0, 0.0, 
                                     0.0, 1.0, 0.0, 0.0, 
                                     0.0, 0.0, 1.0, 0.0, 
                                     0.0, 0.0, 0.0, 18.0);

void main() {
  vec4 pix = texture2D(texture, vertTexCoord.st);

  vec4 color = (pix * colorMatrix) + o;
  gl_FragColor = color;
}
问题:

  • 为什么alpha通道对比度不起作用?我怎样才能让它工作
  • 我实现颜色矩阵的方式有问题吗
  • 你知道一个更好的方法来实现这种粘性效应吗
任何帮助都将不胜感激


谢谢

不幸的是,我无法调试确切的问题,但我有一些想法,希望能帮助您取得一些进展:

  • 要获得更简单/更便宜的效果,您可以使用
  • 您可以找到其他代码并稍微调整代码,以便在处理过程中运行它
  • 例如:

    在处理过程中:

    PShader shader;
    
    void setup(){
      size(900,900,P2D);
    
      shader = loadShader("metaballs.glsl");
      shader.set("iResolution",(float)width/2,(float)height/2);
    }
    void draw(){
      shader.set("iTime", millis() * 0.001);
      shader(shader);
      rect(0,0,width,height);
    }
    
    PShader shader;
    PVector mouse = new PVector();
    void setup(){
      size(900,900,P2D);
    
      shader = loadShader("metaballs.glsl");
      shader.set("iResolution",(float)width/2,(float)height/2);
    }
    void draw(){
      mouse.set(mouseX,mouseY);
      shader.set("iMouse", mouse);
      shader.set("iTime", millis() * 0.001);
      shader(shader);
      rect(0,0,width,height);
    }
    

    @来自处理论坛的noahbuddy可以找到问题的解决方案,所以我将其发布在这里

    要保留透明度,无论是否使用着色器,请使用屏幕外的 缓冲区(PGraphics)。例如,将PNG图像保存为透明 背景

    我从@cansik的模糊着色器中删除了对比度矩阵,取而代之的是 将其放入单独的过滤器中

    blurfrag.glsl

    uniform mat4 transform;
    attribute vec4 position;
    attribute vec4 color;
    varying vec4 vertColor;
    
    uniform vec4 o=vec4(0, 0, 0, -9); 
    uniform lowp mat4 colorMatrix = mat4(1.0, 0.0, 0.0, 0.0, 
                                         0.0, 1.0, 0.0, 0.0, 
                                         0.0, 0.0, 1.0, 0.0, 
                                         0.0, 0.0, 0.0, 60.0);
    
    
    void main() {
      gl_Position = transform * position; 
      vertColor = (color * colorMatrix) + o  ;
    }
    
    #ifdef GL_ES
    precision mediump float;
    precision mediump int;
    #endif
    
    varying vec4 vertColor;
    
    void main() {
      gl_FragColor = vertColor;
    }
    
    / Adapted from:
    // <a href="http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html" target="_blank" rel="nofollow">http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html</a>
    
    #ifdef GL_ES
    precision mediump float;
    precision mediump int;
    #endif
    
    #define PROCESSING_TEXTURE_SHADER
    
    
    uniform sampler2D texture;
    
    uniform vec4 o=vec4(0, 0, 0, 0); 
    uniform lowp mat4 colorMatrix = mat4(1, 0.0, 0.0, 0.0, 
                                         0.0, 1, 0.0, 0.0, 
                                         0.0, 0.0, 1, 0.0, 
                                         0, 0.0, 0.0, 60.0); //Alpha contrast set to 60
    
    
    varying vec2 center;
    
    // The inverse of the texture dimensions along X and Y
    uniform vec2 texOffset;
    
    varying vec4 vertColor;
    varying vec4 vertTexCoord;
    
    uniform int blurSize;       
    uniform int horizontalPass; // 0 or 1 to indicate vertical or horizontal pass
    uniform float sigma;        // The sigma value for the gaussian function: higher value means more blur
                                // A good value for 9x9 is around 3 to 5
                                // A good value for 7x7 is around 2.5 to 4
                                // A good value for 5x5 is around 2 to 3.5
                                // ... play around with this based on what you need <span class="Emoticon Emoticon1"><span>:)</span></span>
    
    const float pi = 3.14159265;
    
    void main() {  
      float numBlurPixelsPerSide = float(blurSize / 2); 
    
      vec2 blurMultiplyVec = 0 < horizontalPass ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
    
      // Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889)
      vec3 incrementalGaussian;
      incrementalGaussian.x = 1.0 / (sqrt(2.0 * pi) * sigma);
      incrementalGaussian.y = exp(-0.5 / (sigma * sigma));
      incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;
    
      vec4 avgValue = vec4(0.0, 0.0, 0.0, 0.0);
      float coefficientSum = 0.0;
    
      // Take the central sample first...
      avgValue += texture2D(texture, vertTexCoord.st) * incrementalGaussian.x;
      coefficientSum += incrementalGaussian.x;
      incrementalGaussian.xy *= incrementalGaussian.yz;
    
      // Go through the remaining 8 vertical samples (4 on each side of the center)
      for (float i = 1.0; i <= numBlurPixelsPerSide; i++) { 
        avgValue += texture2D(texture, vertTexCoord.st - i * texOffset * 
                              blurMultiplyVec) * incrementalGaussian.x;         
        avgValue += texture2D(texture, vertTexCoord.st + i * texOffset * 
                              blurMultiplyVec) * incrementalGaussian.x;         
        coefficientSum += 2.0 * incrementalGaussian.x;
        incrementalGaussian.xy *= incrementalGaussian.yz;
      }
      gl_FragColor = (avgValue / coefficientSum )  * colorMatrix;
    }
    
    // Adapted from:
    // <a href="http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html" target="_blank" rel="nofollow">http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html</a>
    
    #ifdef GL_ES
    precision mediump float;
    precision mediump int;
    #endif
    
    
    #define PROCESSING_TEXTURE_SHADER
    
    uniform sampler2D texture;
    
    // The inverse of the texture dimensions along X and Y
    uniform vec2 texOffset;
    
    varying vec4 vertColor;
    varying vec4 vertTexCoord;
    
    uniform int blurSize;       
    uniform int horizontalPass; // 0 or 1 to indicate vertical or horizontal pass
    uniform float sigma;        // The sigma value for the gaussian function: higher value means more blur
                                // A good value for 9x9 is around 3 to 5
                                // A good value for 7x7 is around 2.5 to 4
                                // A good value for 5x5 is around 2 to 3.5
                                // ... play around with this based on what you need <span class="Emoticon Emoticon1"><span>:)</span></span>
    
    const float pi = 3.14159265;
    
    void main() {  
      float numBlurPixelsPerSide = float(blurSize / 2); 
    
      vec2 blurMultiplyVec = 0 < horizontalPass ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
    
      // Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889)
      vec3 incrementalGaussian;
      incrementalGaussian.x = 1.0 / (sqrt(2.0 * pi) * sigma);
      incrementalGaussian.y = exp(-0.5 / (sigma * sigma));
      incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;
    
      vec4 avgValue = vec4(0.0, 0.0, 0.0, 0.0);
      float coefficientSum = 0.0;
    
      // Take the central sample first...
      avgValue += texture2D(texture, vertTexCoord.st) * incrementalGaussian.x;
      coefficientSum += incrementalGaussian.x;
      incrementalGaussian.xy *= incrementalGaussian.yz;
    
      // Go through the remaining 8 vertical samples (4 on each side of the center)
      for (float i = 1.0; i <= numBlurPixelsPerSide; i++) { 
        avgValue += texture2D(texture, vertTexCoord.st - i * texOffset * 
                              blurMultiplyVec) * incrementalGaussian.x;         
        avgValue += texture2D(texture, vertTexCoord.st + i * texOffset * 
                              blurMultiplyVec) * incrementalGaussian.x;         
        coefficientSum += 2.0 * incrementalGaussian.x;
        incrementalGaussian.xy *= incrementalGaussian.yz;
      }
    
      gl_FragColor = avgValue / coefficientSum;
    }
    
    #define PROCESSING_TEXTURE_SHADER
    
    uniform sampler2D texture;
    varying vec4 vertTexCoord;
    
    uniform vec4 o = vec4(0, 0, 0, -7.0); 
    uniform lowp mat4 colorMatrix = mat4(1.0, 0.0, 0.0, 0.0, 
                                         0.0, 1.0, 0.0, 0.0, 
                                         0.0, 0.0, 1.0, 0.0, 
                                         0.0, 0.0, 0.0, 18.0);
    
    void main() {
      vec4 pix = texture2D(texture, vertTexCoord.st);
    
      vec4 color = (pix * colorMatrix) + o;
      gl_FragColor = color;
    }
    
    sketch.pde

    import ch.bildspur.postfx.builder.*;
    import ch.bildspur.postfx.pass.*;
    import ch.bildspur.postfx.*;
    import processing.opengl.*;
    import com.jogamp.opengl.*;
    
    PostFX fx;
    
    void setup() {
        size(200, 200, P2D);
        fx = new PostFX(this); 
    }
    
    void draw() {
        background(100);
        GL gl = ((PJOGL)beginPGL()).gl.getGL();
        gl.glEnable(GL.GL_BLEND);
        gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE);
        gl.glDisable(GL.GL_DEPTH_TEST);
    
        noStroke();
        fill(255, 30, 30);
        ellipse(width/2, height/2, 40, 40);
        fx.render().blur(80, 14).compose();
    }
    
    PShader contrast, blurry;
    PGraphics buf;
    
    void setup() {
      size(200, 200, P2D);
      buf = createGraphics(width, height, P2D);
    
      contrast = loadShader("colfrag.glsl");
      blurry = loadShader("blurFrag.glsl");
    
      // Don't forget to set these
      blurry.set("sigma", 4.5);
      blurry.set("blurSize", 9);
    }
    
    void draw() {
      background(100);
    
      buf.beginDraw();
        // Reset transparency
        // Note, the color used here will affect your edges
        // even with zero for alpha
        buf.background(100, 0); // set to match main background
    
        buf.noStroke();
        buf.fill(255, 30, 30);
        buf.ellipse(width/2, height/2, 40, 40);
        buf.ellipse(mouseX, mouseY, 40, 40);
    
        blurry.set("horizontalPass", 1);
        buf.filter(blurry);
        blurry.set("horizontalPass", 0);
        buf.filter(blurry);
      buf.endDraw();
    
      shader(contrast);
      image(buf, 0,0, width,height);
    }
    
    就我个人而言,我认为最佳点在于:

    • alpha对比度介于8和11之间
    • alpha偏移在-7和-9之间

      uniform vec4 o = vec4(0, 0, 0, -9.0); 
      uniform lowp mat4 colorMatrix = mat4(1.0, 0.0, 0.0, 0.0, 
                                           0.0, 1.0, 0.0, 0.0, 
                                           0.0, 0.0, 1.0, 0.0, 
                                           1.0, 1.0, 1.0, 11.0);
      
    • 10和15之间表示“西格玛”

    • 30和40表示“模糊尺寸”


    在使用有符号距离函数和marching square算法之前,我已经对2d元球进行了编码,但我发现这个解决方案是最有效的。就性能而言,我可以在800x600画布上以60 fps的速度显示多达4500个球(在入门级2012 imac桌面上使用Python模式进行测试)。

    这只解决了最后一个问题,但另一个选项是使用元球。感谢您的建议,我已经编写了元球。我想尝试一种新的(更快的)方法。好的!我以前没有使用过Metaball,但它们在待办事项列表中。这是刚刚添加的,谢谢@solub我不熟悉处理过程,也不熟悉您正在使用的软件包,但是:OpenGL中的Alpha通道仅在启用了
    GL_BLEND
    时使用,并且仅当
    glBlendFunc
    使用Alpha通道时使用,并且如果使用了源Alpha,则在创建上下文的像素格式时,您还必须具有Alpha缓冲区。所以我打赌你的模糊没有使用阿尔法。使用不同的着色器可能意味着不同的输入/输出布局和统一,所以您必须将CPU端代码与之匹配,否则着色器将无法正常工作。顺便说一句,也许你们可以用模具把模糊的图像转换成立体的somehow@solub无法在片段着色器中启用混合。你必须设置并启用这一功能,分享这种方法真是太好了。处理论坛上的某个人刚刚帮我调试了这个问题,所以我将发布他的解决方案,并将其作为答案接受,因为它专门解决了这个问题。