【问题标题】:How to decide if a fragment's color is white or not?如何确定片段的颜色是否为白色?
【发布时间】:2012-12-11 04:35:06
【问题描述】:

我的场景中有很多相邻的圆圈(白色圆圈和不同颜色的圆圈)。我只想模糊白色圆圈。 (在我的例子中,白色表示 (1,1,1)。)

我的问题是:我应该如何仅使用片段着色器来选择和模糊白色片段?

我想在 GLSL 中做这样的事情:

if (my_current_fragment's_color == white)
{blur current fragment;}
else
{do not blur current fragment}

(我有一个有效的模糊效果,但它不恰当地模糊了整个场景,因为我无法根据片段的颜色在我的代码中做出决定。)

我应该怎么做?上述代码在 GLSL 语言中的精确匹配是什么? 如何确定片段的颜色是否为白色?你们有什么想法吗?


如果您可能需要,这是我的代码:

    vertexShader: [
        //"#define KERNEL_SIZE 25.0",
        "uniform vec2 uImageIncrement;",
        "varying vec2 vUv;",
        "void main() {",
        "vUv = uv - ( ( KERNEL_SIZE - 1.0 ) / 2.0 ) * uImageIncrement;",
        "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
        "}"
    ].join("\n"),
    fragmentShader: [
        //"#define KERNEL_SIZE 25",
        "uniform float cKernel[ KERNEL_SIZE ];",
        "uniform sampler2D tDiffuse;",
        "uniform vec2 uImageIncrement;",
        "varying vec2 vUv;",
        "void main() {",
            "vec2 imageCoord = vUv;",
            "vec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );",
            "for( int i = 0; i < KERNEL_SIZE; i ++ ) {",


            "sum += texture2D( tDiffuse, imageCoord ) * cKernel[ i ];",
            //THE ABOVE LINE SHOULD BE RUN FOR WHITE FRAGMENTS ONLY. BUT HOW?


            "imageCoord += uImageIncrement;",
            "}",
            "gl_FragColor = sum;",
        "}"

【问题讨论】:

  • 您可以在执行循环之前查找当前的 imageCoord 并将其组件与白色进行比较,问题是它可能会导致圆圈边界附近的像素出现一些锯齿。我将留给在该主题上有更多经验的人来正式确定答案。我也对你的着色器如何对模糊数据进行采样有点困惑。

标签: graphics opengl-es glsl webgl three.js


【解决方案1】:

这将非常困难,您将不得不做出一些妥协,除非您可以将白色圆圈渲染到不同的帧缓冲区。

假设你从这个开始。

如果你只对白色像素应用模糊内核,你会得到:

由于蓝色像素没有获得模糊内核,因此白色像素无法渗入蓝色。只有粉色和蓝色像素可以渗入白色。

因此您尝试将图像分为白色部分和非白色部分:

然后您可以单独模糊白色部分,然后重新组合(在多个步骤中,或全部在同一个着色器中)。但是你必须弄清楚用什么重新组合它。如果将其与原始图像重新组合,硬边白色仍然存在。如果你将它与只有非白色部分的图像重新组合,你会得到一个硬黑边。

解决方案

  • 您可以先将白色圆圈渲染为单独的纹理,然后对其进行模糊处理,然后将其叠加在其他所有纹理之上。

  • 您可以缩放内核,使内核“向外”模糊(膨胀),因此当您在黑色背景上模糊白色圆圈时,白色像素保持白色。这将消除边缘。

  • 您可以模糊图像中靠近但不完全等于白色圆圈的区域。例如,您可以使用模糊的白色圆圈作为 Alpha 蒙版,在模糊图像和清晰图像之间进行混合。

  • 您可以想办法让白色圆圈一开始就显得模糊。

【讨论】:

  • 是的,没错! MFlBm.png 是我要找的!你能告诉我一个 GLSL 示例如何做到这一点吗?如何将图像分成白色部分和非白色部分,并与原始图像重新组合?任何进一步的帮助或链接也将不胜感激!
  • @Fract:我在图像编辑器中制作了这些图片,而不是使用 GLSL。我将通过计算与白色dist 的距离将样本samp 分成白色和非白色分量,使用此数字计算0-1 范围内的alpha 值alpha,其中0 表示非白色,1 表示白色,然后samp * alpha 会给你白色部分,(1 - samp) * alpha 会给你非白色部分。
  • 在 GLSL 中有 一种方法来执行 if (color == white) { ... },但是,您不想这样做。你只是认为你想这样做。
  • @Fract:“与白色的距离”是颜色的距离,而不是屏幕上像素的距离。即,黑色远离白色,但浅灰色接近白色。颜色也是向量,所以它们有距离。
  • @Fract:不幸的是,我用于学习 GLSL 的大部分是 GLSL 规范,它有点密集。您可以使用dot(vec4(1.0, 1.0, 1.0, 0.0), color) 计算与白色的距离——这将为您提供白色 3.0 和黑色 0.0。
猜你喜欢
  • 2012-04-04
  • 2021-07-19
  • 1970-01-01
  • 2011-04-11
  • 2011-04-25
  • 1970-01-01
  • 1970-01-01
  • 2017-03-31
  • 1970-01-01
相关资源
最近更新 更多