使用着色器移除黑色颜色
Remove Black Color with Shaders

原始链接: https://yuanchuan.dev/remove-black-color-with-shaders

这篇帖子详细介绍了一个CSS-doodle编码挑战的巧妙解决方案:重现CBC标志。最初,作者使用了堆叠的形状,依靠黑色背景来“隐藏”标志中的黑色元素。虽然可行,但这限制了可用性。为了避免CSS蒙版过于复杂,作者最近发现了一个使用CSS-doodle中的着色器(shaders)的简单修复方法。 CSS-doodle允许实时生成图像,可用作着色器中的纹理。通过应用着色器,作者现在可以选择性地移除黑色,使标志透明并适应任何背景。着色器代码计算亮度并使用它来控制透明度。 作者还提到了使用“差值”(difference)混合模式进行图案创建,通常使用白色以获得可预测的黑白结果。最终,着色器解决方案提供了一种更通用和令人满意的实现所需效果的方法,突出了着色器在颜色操作方面的强大功能。

黑客新闻新 | 过去 | 评论 | 提问 | 展示 | 招聘 | 提交登录 移除黑色与着色器 (yuanchuan.dev) 8 分,由 surprisetalk 1小时前发布 | 隐藏 | 过去 | 收藏 | 讨论 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请YC | 联系 搜索:
相关文章

原文

A while back, I coded the CBC (Canadian Broadcasting Corporation) logo with a quick css-doodle implementation. There are certainly better ways to do it, but I chose to stack several black boxes and circles, because the background color was black, those black boxes ended up becoming "invisible" as desired.

You can see how it works by using a different background other than black.

I couldn't find an elegant way to not use the black color, and I was reluctant to use CSS masks since it would require more calculations.

One solution

It just hit me tonight that I could use shaders to get rid of the black color, and it's so simple.

In css-doodle, code can generate images in real time, which can be used as textures and fed into shaders for additional effects.

background: @shaders(
  texture_0 {
    /* css-doodle code */
  }

  fragment {
    /* glsl code */
  }
)

This is the old implementation.

@grid: 13x1 / 240px;
@place: center;
@size: 30%;

background: #000 @svg(
  viewBox: -1 -1 2 2;
  circle { r: .9; fill: red }
);

translate: @pn(
  -75% 0, 75% 0, 0 -75%, 0 75%,
  -50% 50%, 50% 50%, 50% -50%, -50% -50%,
  -50% 0, 50% 0, 0 -50%, 0 50%,
  0 0
);

Turn it into a texture and mask out all the black pixels.

@grid: 1 / 240px / @shaders(
  texture_0 {
    @grid: 13x1 / 100%;
    @place: center;
    @size: 30%;
    background: #000 @svg(
      viewBox: -1 -1 2 2;
      circle { r: .9; fill: red }
    );
    translate: @pn(
      -75% 0, 75% 0, 0 -75%, 0 75%,
      -50% 50%, 50% 50%, 50% -50%, -50% -50%,
      -50% 0, 50% 0, 0 -50%, 0 50%,
      0 0
    );
  }
  fragment {
    void main() {
      vec2 uv = gl_FragCoord.xy / u_resolution.xy;
      vec4 c = texture(texture_0, uv);
      float b = length(c.rgb);
      float alpha = smoothstep(0.0, 1.0, b);
      FragColor = vec4(c.rgb, c.a * alpha);
    }
  }
);

The difference blending mode

I often use blend modes to create some combinations of shapes. The tricky part, though, is working with color. While there are some predictable patterns, the results of different color combinations can be hard to anticipate. So most of the time, I just use white color with the difference blend mode, which produces black-and-white patterns.

@grid: 8x1 / 240px / #f90 +.8; @place: @plot(r: .5); background: #fff; border-radius: 50%; mix-blend-mode: difference; @size: 50%;
@grid: 8x1 / 240px / #f90 +.8;
@place: @plot(r: .5);
@size: 50%;
background: #fff;
border-radius: 50%;
mix-blend-mode: difference;

Now I can directly remove the black color and make the pattern transparent, it becomes much more usable.

@grid: 1 / 240px / #f90;
background: @shaders(
  texture_0 {
    @grid: 8x1 / 100% +.8;
    @place: @plot(r: .5);
    @size: 50%;
    background: #fff;
    border-radius: 50%;
    mix-blend-mode: difference;
  }
  fragment {
    void main() {
      vec2 uv = gl_FragCoord.xy / u_resolution.xy;
      vec4 c = texture(texture_0, uv);
      float b = length(c.rgb);
      float alpha = smoothstep(0.0, 2.0, b);
      FragColor = vec4(c.rgb, c.a * alpha);
    }
  }
);

This approach isn’t anything special, after all, shaders are naturally good at handling colors, but it still brings me joy.

联系我们 contact @ memedata.com