Pie*_*nry 5 javascript 3d three.js depth-testing
免责声明:一般来说,我对three.js、WegGL 和3D 图形比较陌生。
我正在使用 Three.js 以 3D 形式显示 GPS 轨迹中的点。我们必须能够可视化的数据集可能非常大(数十万个点),因此性能非常重要。
我使用一个Points对象,我用一个BufferGeometry包含所有点的对象填充该对象。这些点是按照曲目的顺序添加的,所以按时间顺序。
然后,我们使用PointsMaterial带有 2D 纹理(精灵)的 a 将点表示为一个圆,圆外的区域是透明的。因为颜色是动态的,所以 2D 纹理是动态绘制到画布上的。
问题是,如果我们看轨迹方向上的点,即离相机较远的点是在较近的点之后渲染的点,在点重叠的地方会出现伪影,较近点的透明部分被绘制在更远的点上:
当我们从另一个方向看轨道时,即从后向前渲染的点,问题就消失了:
我尝试了以下两个选项来解决该问题:
alphaTest0和1之间的一个数值,它样的作品
depthWrite: false的材料的点,它呈现漂亮,但随后近点总是绘制在旧的无论相机的方向,它看起来奇怪,是错误的实际渲染深度 顺序中的点从最远的开始到最近的结束的解决方案是什么?
以下是代码的相关部分。
几何的构建。该timeline3d对象包含所有点并来自 XHR 请求:
const particlesGeometry = new BufferGeometry();
const vertices = [];
for (let i = 0; i < timeline3d.points.length; i++) {
const coordinates = timeline3d.points[i].sceneCoordinates;
vertices.push(coordinates[0], coordinates[1], coordinates[2]);
}
particlesGeometry.addAttribute('position', new Float32BufferAttribute(vertices, 3));
return new Points(particlesGeometry, buildTimelinePointsMaterial(timeline3d));
Run Code Online (Sandbox Code Playgroud)
材料:
function buildTimelinePointsMaterial (timeline) {
const pointTexture = new CanvasTexture(drawPointSprite(POINT_SPRITE_RADIUS, timeline.color));
return new PointsMaterial({
size: POINT_SIZE,
sizeAttenuation: true,
map: pointTexture,
transparent: true,
alphaTest: 0.4
});
}
Run Code Online (Sandbox Code Playgroud)
这是渲染点时 WebGL 的一个限制。就像上面提到的@ScieCode 一样,我个人一直在通过更改材质的混合模式来解决这个问题。有了它,每个点都像透明的 Photoshop 图层一样混合在另一个点上,并消除了重叠效果。通常,如果您有浅色背景,您会想要使用THREE.MultiplyBlending,如果您有深色背景,您会使用THREE.AdditiveBlending,但这完全取决于品味。
还有是多数民众赞成实施更加复杂的解决方案在这个例子中,通过深入每帧一次排序的所有顶点。如果您查看其源代码,您会看到它sortPoints()在渲染循环中被调用,它将相机矩阵与几何体的世界矩阵相乘,以查看每个顶点深度并按顺序排序。
| 归档时间: |
|
| 查看次数: |
917 次 |
| 最近记录: |