three.js 点云、BufferGeometry 和不正确的透明度
three.js point clouds, BufferGeometry and incorrect transparency
问题:我有一个包含大量数据点(大约一百万)的点云。当我对渲染点应用透明度时,透明度不知何故不显示渲染点后面的内容
正如你在标记点的例子中看到的,它没有显示它应该显示的内容,好像缓冲有问题。
我使用 three.js 使用以下 "setup" 创建点云:
渲染器:
this.renderer = new THREE.WebGLRenderer({
canvas: this.canvas,
antialias: true
});
material:
this.pointMaterial = new THREE.ShaderMaterial( {
uniforms: {
time: { type: "f", value: 1.0 }
},
vertexShader: document.getElementById('vertexShader').textContent,
fragmentShader: document.getElementById('fragmentShader').textContent,
transparent: true
});
顶点着色器:
attribute float size;
attribute float opacity;
attribute vec3 color;
varying vec3 vColor;
varying float vOpacity;
void main() {
vColor = color;
vOpacity = opacity;
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
gl_PointSize = size * (500.0 / length(mvPosition.xyz));
gl_Position = projectionMatrix * mvPosition;
}
片段着色器:
uniform float time;
varying vec3 vColor;
varying float vOpacity;
void main() {
gl_FragColor = vec4(vColor, vOpacity);
}
几何图形(我省略了填充数组的部分):
var bufferGeometry = new THREE.BufferGeometry();
var vertices = new Float32Array(vertexPositions.length * 3);
var colors = new Float32Array(vertexColors.length * 3);
var sizes = new Float32Array(vertexSizes.length);
var opacities = new Float32Array(vertexOpacities.length);
bufferGeometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
bufferGeometry.addAttribute('color', new THREE.BufferAttribute(colors, 3));
bufferGeometry.addAttribute('size', new THREE.BufferAttribute(sizes, 1));
bufferGeometry.addAttribute('opacity', new THREE.BufferAttribute(opacities, 1));
this.points = new THREE.Points(bufferGeometry, this.pointMaterial);
this.scene.add(this.points);
我用内置点 material 尝试了这个,同样的情况发生了
this.pointMaterial = new THREE.PointsMaterial({
size: this.pointSize,
vertexColors: THREE.VertexColors,
transparent: true,
opacity: 0.25
});
这是预期的行为还是我做错了什么?
alpha 混合方程式的工作方式是后面的几何体的源颜色被前面的几何体的目标颜色覆盖。这意味着您需要按从后到前的排序顺序渲染透明几何体,以便前面的几何体与后面的几何体正确混合。
如果您只有透明几何体,那么您只需禁用深度测试,以相反的深度排序顺序渲染,它就会起作用。如果您也有不透明几何体,那么您需要首先正常渲染所有不透明几何体,然后禁用深度写入(不是测试)并以相反的深度排序顺序渲染透明几何体,然后重新启用深度写入。
Here are some answers to 如果您有兴趣了解更多,请提问。
问题:我有一个包含大量数据点(大约一百万)的点云。当我对渲染点应用透明度时,透明度不知何故不显示渲染点后面的内容
正如你在标记点的例子中看到的,它没有显示它应该显示的内容,好像缓冲有问题。
我使用 three.js 使用以下 "setup" 创建点云:
渲染器:
this.renderer = new THREE.WebGLRenderer({
canvas: this.canvas,
antialias: true
});
material:
this.pointMaterial = new THREE.ShaderMaterial( {
uniforms: {
time: { type: "f", value: 1.0 }
},
vertexShader: document.getElementById('vertexShader').textContent,
fragmentShader: document.getElementById('fragmentShader').textContent,
transparent: true
});
顶点着色器:
attribute float size;
attribute float opacity;
attribute vec3 color;
varying vec3 vColor;
varying float vOpacity;
void main() {
vColor = color;
vOpacity = opacity;
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
gl_PointSize = size * (500.0 / length(mvPosition.xyz));
gl_Position = projectionMatrix * mvPosition;
}
片段着色器:
uniform float time;
varying vec3 vColor;
varying float vOpacity;
void main() {
gl_FragColor = vec4(vColor, vOpacity);
}
几何图形(我省略了填充数组的部分):
var bufferGeometry = new THREE.BufferGeometry();
var vertices = new Float32Array(vertexPositions.length * 3);
var colors = new Float32Array(vertexColors.length * 3);
var sizes = new Float32Array(vertexSizes.length);
var opacities = new Float32Array(vertexOpacities.length);
bufferGeometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
bufferGeometry.addAttribute('color', new THREE.BufferAttribute(colors, 3));
bufferGeometry.addAttribute('size', new THREE.BufferAttribute(sizes, 1));
bufferGeometry.addAttribute('opacity', new THREE.BufferAttribute(opacities, 1));
this.points = new THREE.Points(bufferGeometry, this.pointMaterial);
this.scene.add(this.points);
我用内置点 material 尝试了这个,同样的情况发生了
this.pointMaterial = new THREE.PointsMaterial({
size: this.pointSize,
vertexColors: THREE.VertexColors,
transparent: true,
opacity: 0.25
});
这是预期的行为还是我做错了什么?
alpha 混合方程式的工作方式是后面的几何体的源颜色被前面的几何体的目标颜色覆盖。这意味着您需要按从后到前的排序顺序渲染透明几何体,以便前面的几何体与后面的几何体正确混合。
如果您只有透明几何体,那么您只需禁用深度测试,以相反的深度排序顺序渲染,它就会起作用。如果您也有不透明几何体,那么您需要首先正常渲染所有不透明几何体,然后禁用深度写入(不是测试)并以相反的深度排序顺序渲染透明几何体,然后重新启用深度写入。
Here are some answers to