Additive blending on transparent canvas

First of all: a big thank you to everyone on the forum. I’ve been lurking for the past two months or so while building the globe over at GitHub: Where the world builds software · GitHub, and the forum has been immensely helpful. Now that we’ve launched I’m finally free to post and join the discussion :tada:

I’m working on adding some more flares to the globe, and as part of that experiment I’m trying to make the webgl context transparent. It works as expected except for one object: the halo effect (a sphere placed behind the globe) doesn’t blend as I expect it to, and so instead of its black pixels disappearing with its blending set to AdditiveBlending, as soon as I set alpha: true on the WebGLRenderer, the halo is basically rendered as if its blending was set to NormalBlending (you can see how a black sphere appears behind the globe):

Is it possible to maintain the Additive blending effect on a transparent canvas? Or should I go about this in a different way?

For context, the renderer’s clearColor is unchanged/set to the default, and the halo’s setup looks like so:

const haloMaterialBlue = new ShaderMaterial({
  uniforms: {
    "c":   { type: "f", value: 0.7 },
    "p":   { type: "f", value: 15.0 },
    glowColor: { type: "c", value: new Color(COLORS.HALO_BLUE) },
    viewVector: { type: "v3", value: new Vector3(0, 0, CAMERA_Z) }
  },
  vertexShader: haloVert,
  fragmentShader: haloFrag,
  side: BackSide,
  blending: AdditiveBlending,
  transparent: true,
  dithering: true
});

It’s then just placed behind the globe and tilted to its side to enhance the effect in the top left corner.

Vertex shader:

uniform vec3 viewVector;
uniform float c;
uniform float p;
varying float intensity;
void main() 
{
  vec3 vNormal = normalize( normalMatrix * normal );
  vec3 vNormel = normalize( normalMatrix * viewVector );
  intensity = pow( c - dot(vNormal, vNormel), p );
  
  gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}

Fragment shader:

uniform vec3 glowColor;
varying float intensity;
void main() 
{
  vec3 glow = glowColor * intensity;
  gl_FragColor = vec4( glow, 1.0 );
}

Appreciate any help :heart:

2 Likes