在 GL ES 中将片段着色器渐变结果从黑色转换为透明

Convert fragment shader gradient result from black to transparent in GL ES

我正在尝试为我正在开发的开源游戏生成逼真的星星。我正在使用 Chromium 引擎 (NW.js) 中涵盖的 here. I'm using the three.js 库的原理生成星星。我发现的问题是星光逐渐变成黑色而不是透明。

虽然单星看起来不错,

多颗星出现严重问题:


我的代码如下:

顶点着色器

attribute vec3 glow;
varying vec3 vGlow;

void main() {
  vGlow = glow;
  vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
  gl_PointSize = 100.0;
  gl_Position = projectionMatrix * mvPosition;
}

片段着色器

varying vec3 vGlow;

void main() {
  float starLuminosity  = 250.0;
  float invRadius = 60.0;
  float invGlowRadius = 2.5;

  // Get position relative to center.
  vec2 position = gl_PointCoord;
  position.x -= 0.5;
  position.y -= 0.5;

  // Airy disk calculation.
  float diskScale = length(position) * invRadius;
  vec3 glow = vGlow / pow(diskScale, invGlowRadius);
  glow *= starLuminosity;

  gl_FragColor = vec4(glow, 1.0);
}

我试过丢弃较暗的像素,但这并没有解决问题,它只是隐藏了一点:

if (gl_FragColor.r < 0.1 && gl_FragColor.g < 0.1 && gl_FragColor.b < 0.1) {
  discard;
}

我追求的实际效果如下,

但我不知道如何实现。

如有任何建议,我们将不胜感激。

您无法在片段着色器中实现此效果,因为您正在渲染多个网格或基元。您必须在渲染几何之前启用 Blending

gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

还要确保 Depth test 已禁用。

此外,您必须设置 Alpha 通道。例如:

gl_FragColor = vec4(glow, 1.0);

vec4(glow, (glow.r+glow.g.+glow.b)/3.0 * 1.1 - 0.1);