0

I have a scene where I use points, like so

        <points ref={gPoints} position={position}>
            <bufferGeometry attach="geometry">
                <bufferAttribute
                    attach="attributes-position"
                    count={positions.length / 3}
                    array={positions}
                    itemSize={3}
                    usage={THREE.DynamicDrawUsage}
                />
                // ... bunch of attributes
            </bufferGeometry>
            <shaderMaterial
                depthWrite={false}
                depthTest={false}
                fragmentShader={fragmentShader}
                vertexShader={vertexShader}
                uniforms={uniforms}
                blending={THREE.AdditiveBlending}
            />
        </points>

Where I use a fragment shader to give a blur effect

uniform float uResolutionWidth;
uniform float uResolutionHeight;

varying vec3 vColor;
varying vec4 vRealPosition;
varying float vDistance;

  void main() {

    float d = length(gl_PointCoord.xy - 0.5);

    float alpha = smoothstep(0.5, 0.15, d);

    gl_FragColor = vec4( vColor, alpha );
  }

And in the vertex shader I am mostly updating positions, but here is how I set vColor

#define PI 3.14159265358979323846


uniform float uTime;
uniform float uRadius;


attribute float pointSizes;
attribute float randomX;
attribute float randomY;
attribute float randomZ;
attribute float randomW;


varying vec3 vColor;
  

void main() {

  // set the vertex color
  float d = length(abs(position) / vec3(96.0, 22.0, 96.0));
  d = clamp(d, 0.0, 1.0);

  float d2 = abs(position.y);

  vColor = mix(vec3(244.0, 131.0, 12.0), vec3(82.0, 27.0, 255.0), d2/22.0) / 255.;
}

Here is a picture of what it looks like without depth writing

no depth writing

But when I enable depth writing like so

<shaderMaterial
    depthWrite={true}
    depthTest={true}
    fragmentShader={fragmentShader}
    vertexShader={vertexShader}
    uniforms={uniforms}
    blending={THREE.AdditiveBlending}
    transparent={true}  // I also tried with and without transparent setting
/>

Each point now has a rectangular black background depth writing enabled

I then tried to discard the points where the alpha is too low

uniform float uResolutionWidth;
uniform float uResolutionHeight;

varying vec3 vColor;
varying vec4 vRealPosition;
varying float vDistance;

void main() {
  float d = length(gl_PointCoord.xy - 0.5);
  float alpha = smoothstep(0.5, 0.15, d);

  // Discard fragments that are fully transparent
  if (alpha < 0.001) {
    discard;
  }

  gl_FragColor = vec4(vColor * alpha, alpha);
}

And this is what it looks like

discarded points version

Does anyone know what is the cause of the black background and how to fix it? It's only a problem if using depth writing, any helps appreciated <3

1 Answer 1

0

What ended up working for me is disabling depth writing in ThreeJS

<shaderMaterial
  transparent={true}
  depthWrite={false}
  depthTest={true}
  fragmentShader={fragmentShader}
  vertexShader={vertexShader}
  uniforms={uniforms}
  blending={THREE.AdditiveBlending}
/>

And in the fragment shader I changed smoothstep calculation

void main() {
  vec2 cxy = 2.0 * gl_PointCoord - 1.0;
  float r = dot(cxy, cxy);
  float alpha = 1.0 - smoothstep(0.0, 1.0, r);
  vec3 brightColor = vColor * alpha;
  gl_FragColor = vec4(brightColor, alpha);
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.