2016-03-02 51 views
1

该行为仅在Firefox上发生。 (我使用开发版)。Three.js添加非透明立方体时使用着色器材质的透明度点云消失

我有一些点云需要使用着色器激活透明度。

当我将CubeGeometry添加到没有透明度的场景时,它使点云消失。

我还注意到,使用PointMaterial的点云按预期工作,但在我的程序中,我需要使用着色器。

如果你在这部分代码在立方体使用shaderMaterial:

mesh = new THREE.Mesh(geometry, material); 
//mesh = new THREE.Mesh(geometry, shaderMaterial); 

云中正确显示为好,但我当然需要与其他一些材料比的着色器的非透明立方体云。

我正在使用three.js r74

感谢您的帮助!

var $ = document.querySelector.bind(document); 
 
var camera, scene, renderer, geometry, material, mesh; 
 

 
init(); 
 
animate(); 
 

 
function init() { 
 

 
    scene = new THREE.Scene(); 
 

 
    camera = new THREE.PerspectiveCamera(50, window.innerWidth/window.innerHeight, 1, 10000); 
 
    camera.position.z = 500; 
 
    scene.add(camera); 
 

 
    var pointMaterial = new THREE.PointsMaterial(); 
 

 
    var vShader = $('#vertexshader'); 
 
    var fShader = $('#fragmentshader'); 
 
    var shaderMaterial = 
 
     new THREE.ShaderMaterial({ 
 
     vertexShader: vShader.text, 
 
     fragmentShader: fShader.text 
 
     }); 
 

 
    shaderMaterial.transparent = true; 
 
    shaderMaterial.vertexColors = THREE.VertexColors; 
 
    shaderMaterial.depthWrite = true; 
 

 
    geometry = new THREE.Geometry(); 
 

 
    particleCount = 20000; 
 

 
    for (i = 0; i < particleCount; i++) { 
 

 
    var vertex = new THREE.Vector3(); 
 
    vertex.x = Math.random() * 2000 - 1000; 
 
    vertex.y = Math.random() * 2000 - 1000; 
 
    vertex.z = Math.random() * 2000 - 1000; 
 

 
    geometry.vertices.push(vertex); 
 
    } 
 

 
    parameters = [ 
 
    [ 
 
     [1, 1, 0.5], 5 
 
    ], 
 
    [ 
 
     [0.95, 1, 0.5], 4 
 
    ], 
 
    [ 
 
     [0.90, 1, 0.5], 3 
 
    ], 
 
    [ 
 
     [0.85, 1, 0.5], 2 
 
    ], 
 
    [ 
 
     [0.80, 1, 0.5], 1 
 
    ] 
 
    ]; 
 
    parameterCount = parameters.length; 
 

 
    for (i = 0; i < parameterCount; i++) { 
 

 
    color = parameters[i][0]; 
 
    size = parameters[i][1]; 
 

 
    //If we use pointMaterial instead of ShaderMaterial the cloud is visible 
 
    particles = new THREE.Points(geometry, shaderMaterial); 
 
    particles.sizeAttenuation = true; 
 
    particles.sortParticles = true; 
 
    particles.colorsNeedUpdate = true; 
 
    particles.scale.set(1, 1, 1); 
 

 
    particles.rotation.x = Math.random() * 6; 
 
    particles.rotation.y = Math.random() * 6; 
 
    particles.rotation.z = Math.random() * 6; 
 

 
    scene.add(particles); 
 
    } 
 

 
    geometry = new THREE.CubeGeometry(200, 200, 200); 
 

 
    //POINT CLOUD DISAPPEARS WHEN USING NON TRANSPARENT MATERIAL 
 
    material = new THREE.MeshBasicMaterial({color: 0x00ff00}); 
 

 
    mesh = new THREE.Mesh(geometry, material); 
 
    //mesh = new THREE.Mesh(geometry, shaderMaterial); 
 

 
    scene.add(mesh); 
 

 
    renderer = new THREE.WebGLRenderer(); 
 
    renderer.setSize(window.innerWidth, window.innerHeight); 
 

 
    document.body.appendChild(renderer.domElement); 
 

 
} 
 

 
function animate() { 
 
    requestAnimationFrame(animate); 
 
    render(); 
 
} 
 

 
function render() { 
 
    mesh.rotation.x += 0.01; 
 
    mesh.rotation.y += 0.02; 
 

 
    renderer.render(scene, camera); 
 
}
<script type="x-shader/x-vertex" id="vertexshader"> 
 

 
void main() 
 
{ 
 
    gl_PointSize = 5.0; 
 
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0); 
 
} 
 

 
</script> 
 

 
<script type="x-shader/x-fragment" id="fragmentshader"> 
 

 
precision highp float; 
 

 
void main() 
 
{ 
 
    gl_FragColor \t = vec4(1.0,0.0,1.0,1.0); 
 
} 
 

 
</script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r74/three.js"></script>

回答

0

目前尚不清楚你想要达到

什么样的影响你想看到里面的点向立方体?

你的着色器返回不透明的紫色

gl_FragColor = vec4(1.0,0.0,1.0,1.0); 

所以你的粒子不会是透明的,无论在材料上的transparent设置。

你的立方体是非透明的,所以立方体内的点当然会消失。这就是非透明的定义。

将立方体设置为透明也不能解决问题。处理透明度很困难。你通常需要从前到后画东西。要做到这一点,three.js需要每个对象都可以单独绘制,因此它可以先绘制立方体后面的所有粒子,然后绘制立方体的后面,然后绘制立方体内部的粒子,然后绘制立方体的前部,然后立方体前面的粒子。

要做到这一点,需要将立方体拆分为6个平面,并将每个粒子放入其自己的场景对象中。

有办法伪造它。关闭depthTest有时可以用作替代品,但它不会完全正确。

+0

在Firefox上,我们无法看到多维数据集外部或内部的点云。基本上我只看到没有点和黑色背景的立方体。 – Sim