three.js透明贴图问题

10

我正在创建大量的粒子(确切地说是 80,000 个),并且已经设置了一个透明的贴图,但是,并不是所有的粒子都是透明的。

我使用了一个透明的 PNG 图像:particle.png (它几乎看不见,但是确实存在)作为材质贴图,然而它显示了黑色背景,如下所示:

particles

如果你仔细观察,一些粒子可以很好地混合在一起(没有重叠的黑色边缘),但是有些则不能。这可能是因为有太多重叠的透明对象,或者这不应该是问题吗?

这是生成我的粒子的代码片段:

// load the texture
var map = THREE.ImageUtils.loadTexture('img/particle.png');

// create temp variables
var geometry, material;

// create an array with ParticleSystems (I need multiple systems because I have different colours, thus different materials)
var systems = [];

// Loop through every colour
for(var i = 0; i < colors.length; i++) {
    // Create a new geometry
    geometry = new THREE.Geometry();

    // create a new material
    material = new THREE.ParticleBasicMaterial({
        color: colors[i],
        size: 20,
        map: map, // set the map here
        transparent: true // transparency is enabled!!!
    });

    // create a new particle system
    systems[i] = new THREE.ParticleSystem(geometry, material);

    // add the system to the scene
    scene.add(systems[i]);
}

// vertices are added to the ParticleSystems' geometry here

为什么一些粒子有黑色背景?


我有一个非常相似的问题,旨在删除背景。链接如下:http://stackoverflow.com/questions/20742809/three-js-invisible-background-for-background-and-png-particles - gronaz
4个回答

20

您可以设置材质的alphaTest属性来代替透明度。例如:

material.alphaTest = 0.5;
material.transparent = false;

three.js不再对粒子进行排序;它们按照缓冲区中的顺序呈现。

three.js r.85


1
这个特定问题的实际解决方案在其他答案的评论中,但是你的解决方案也很棒!在我的情况下,我不得不使用它,因为我正在处理如此多的粒子。然而,“正确”的方法确实会让我的FPS崩溃,尽管在大多数情况下我仍然会推荐它作为答案。非常感谢! - Tim S.
使用您提供的解决方案,我在有100k个粒子时保持60fps,而在Roest答案评论中提供的解决方案中只能得到30fps。 - Tib
我也对这个答案感到兴奋,谢谢! - Andy

12

那些带有黑色边角的粒子会在任何后面的东西之前被渲染。因此,GL不知道后面还有其他内容需要混合。为了使其看起来正确,您需要按照粒子的z坐标从后向前的顺序进行渲染。


我该如何告诉THREE.WebGLRenderer从后往前渲染?这是一个可以移动的3D环境,因此z-index将是可变的。 - Tim S.
说实话,我不知道three.js是否能为您添加一些魔法来完成这个任务。我的回答通常是关于渲染透明对象的,是的,在3D环境中,如果相机移动,您需要转换坐标并重新排序对象。另一种选择是使用深度剥离等其他透明技术。 - Roest
15
我必须将材质的 depthWrite 属性设置为 false - Tim S.
10
好的,我会尽力为您进行翻译。原文是“哦,我还需要将ParticleSystem.sortParticles属性设置为true”。 - Tim S.
1
你可以发一个链接给我们展示你的代码完整工作样例吗?那会非常有帮助。谢谢! - Stemkoski

1

在材质上禁用depthWrite属性。

// create a new material
material = new THREE.ParticleBasicMaterial({
    color: colors[i],
    size: 20,
    map: map,
    transparent: true,
    depthWrite: false,
});

0

试试webgl_particles_billboards.html。 如果我没记错的话,它做的是你期望的相同的事情。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接