在 ThreeJS 中使用点时,如果使用深度书写,每个点上都会有黑色背景

问题描述 投票:0回答:1

我有一个使用的场景,就像这样

        <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>

我使用片段着色器来提供模糊效果

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 );
  }

在顶点着色器中,我主要更新位置,但这是我设置的方式

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.;
}

这是没有深度写作的情况下的样子的图片

no depth writing

但是当我像这样启用深度写作时

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

现在每个点都有一个矩形黑色背景 depth writing enabled

然后我尝试丢弃 alpha 太低的点

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);
}

这就是它的样子

discarded points version

有谁知道黑色背景的原因是什么以及如何解决它?如果使用深度写作,这只是一个问题,任何帮助都值得赞赏<3

reactjs three.js shader fragment-shader vertex-shader
1个回答
0
投票

最终对我有用的是禁用 ThreeJS 中的深度写入

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

在片段着色器中我更改了 smoothstep 计算

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);
}
© www.soinside.com 2019 - 2024. All rights reserved.