2017-11-14 12 views
0

私は3js BufferGeometryで2つのパーティクルを作成しました。それぞれのパーティクルをクリックして、対応するイメージを表示します。BufferGeometryはパーティクルZインデックスを作成します

しかし、私が粒子をクリックすると、画像が表示され、別の粒子がそれを覆っていました。

階層のコントロールからパーティクルを取得し、クリックしたパーティクルを常に上に維持する方法を知りたいと思います。

コード: `

var scene, camera, renderer,controls; 
 
var points; 
 
var shaderMaterial; 
 

 
var particleCount = 2; 
 

 
function init() { 
 
     scene = new THREE.Scene(); 
 

 
     camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000); 
 
     camera.position.x = 15; 
 
     camera.position.y = 16; 
 
     camera.position.z = 35; 
 
     camera.lookAt(scene.position); 
 

 
     renderer = new THREE.WebGLRenderer(); 
 

 
     renderer.setClearColor(0x000000, 1.0); 
 

 
     renderer.setSize(window.innerWidth, window.innerHeight); 
 

 
     var light = new THREE.AmbientLight(0xcccccc); 
 

 
     scene.add(light); 
 

 
     document.body.appendChild(renderer.domElement); 
 

 
     createParticles(); 
 

 
     createGrid(); 
 

 
     render(); 
 

 
     document.querySelector('canvas').addEventListener('click', interactive, false); 
 

 
    } 
 

 
function createParticles() { 
 
    var geometry = new THREE.BufferGeometry(); 
 
    var positions = new Float32Array(particleCount * 3); 
 
    var sizes = new Float32Array(particleCount); 
 
    var pop = new Float32Array(particleCount); 
 

 
    for (var i = 0, i3 = 0; i < particleCount; i ++, i3 += 3) { 
 
     positions[i3 + 0] = i* 10; 
 
     positions[i3 + 1] = 0.1; 
 
     positions[i3 + 2] = 1; 
 

 
     sizes[i] = 15; 
 
     pop[i] = 0.0; 
 
    } 
 

 
    geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3)); 
 
    geometry.addAttribute('size', new THREE.BufferAttribute(sizes, 1)); 
 
    geometry.addAttribute('pop', new THREE.BufferAttribute(pop, 1)); 
 

 
    shaderMaterial = new THREE.ShaderMaterial({ 
 
     uniforms: { 
 
      'u_time': {type: 'f', value: 1.0}, 
 
      'u_texture_0': { value: new THREE.TextureLoader().load('https://avatars2.githubusercontent.com/u/5829050?s=256&v=4') }}, 
 
     vertexShader: document.getElementById('vs').textContent, 
 
     fragmentShader: document.getElementById('fs').textContent, 
 
     // blending:  THREE.AdditiveBlending, 
 
     depthTest:  false, 
 
     transparent: true 
 
    }); 
 
    shaderMaterial.uniforms['u_texture_0'].value.flipY = false; 
 

 
    points = new THREE.Points(geometry, shaderMaterial); 
 

 
    scene.add(points); 
 

 
} 
 
var raycaster = new THREE.Raycaster(); 
 
raycaster.params.Points.threshold = 5; 
 

 
var touch = new THREE.Vector2(); 
 
var intersects, INTERSECTED; 
 
var beforeIndex; 
 

 
function interactive (event) { 
 
    touch.x = (event.clientX/window.innerWidth) * 2 - 1; 
 
    touch.y = - (event.clientY/window.innerHeight) * 2 + 1; 
 
    points.geometry.computeBoundingSphere(); 
 
    camera.updateMatrixWorld(); 
 
    var vector = new THREE.Vector3(touch.x, touch.y, 0.5).unproject(camera); 
 
    raycaster.set(camera.position, vector.sub(camera.position).normalize()); 
 
    
 
    raycaster.setFromCamera(touch, camera); 
 

 
    intersects = raycaster.intersectObject(points); 
 
    if (intersects.length > 0) { 
 
     if (INTERSECTED != intersects[ 0 ].index) { 
 
      INTERSECTED = intersects[ 0 ].index; 
 
      if (beforeIndex != INTERSECTED) { 
 
       points.geometry.attributes.pop.array[ beforeIndex ] = 0.0; 
 
      } 
 
      points.geometry.attributes.pop.array[ INTERSECTED ] = 1.0; 
 

 
      beforeIndex = INTERSECTED; 
 

 
     } 
 
    } 
 

 
    points.geometry.attributes.size.needsUpdate = true; 
 
    points.geometry.attributes.pop.needsUpdate = true; 
 
} 
 
    
 
function createGrid() { 
 
    var helper = new THREE.GridHelper(100, 20, 0x303030, 0x303030); 
 
    scene.add(helper); 
 
} 
 
function render() { 
 

 
    renderer.render(scene, camera); 
 

 
    requestAnimationFrame(render); 
 
} 
 
    
 
init();
* { 
 
     margin: 0; 
 
     padding: 0; 
 
    } 
 
    html, body { 
 
     width: 100%; 
 
     height: 100%; 
 
     background: #000; 
 
    } 
 
    canvas { 
 
     display: block; 
 
    }
<script src="https://threejs.org/build/three.js"></script> 
 
<script id="fs" type="x-shader/x-fragment"> 
 
    precision highp float; 
 
    uniform sampler2D u_texture_0; 
 
    uniform float u_time; 
 
    varying float u_pop; 
 

 
    void main() { 
 
    vec2 uv = gl_PointCoord.xy; 
 
    vec4 rval = texture2D(u_texture_0,uv); 
 

 
    vec2 posToCenter = (uv - vec2(.5, .5)) * 2.0; 
 
    float distanceToCenter = length(posToCenter); 
 
    float fadeOpacity = 1. - smoothstep(0.8, 1., distanceToCenter); 
 
    float opacity = (1. - step(0.8, distanceToCenter)) + fadeOpacity; 
 

 
    vec3 bgColor = mix(vec3(255., 255., 255.), vec3(252., 222., 184.), distanceToCenter)/255.; 
 

 
    vec4 color = vec4(mix(bgColor, rval.rgb, u_pop), 1.); 
 
    color.a = opacity; 
 

 
    gl_FragColor = color; 
 
} 
 
</script> 
 
<script type="x-shader/x-vertex" id="vs"> 
 
    attribute float size; 
 
    attribute float pop; 
 

 
    varying float u_pop; 
 
    void main() { 
 
     vec4 mvPosition = modelViewMatrix * vec4(position, 1.0); 
 
     gl_PointSize = size * (300.0/-mvPosition.z); 
 
     gl_Position = projectionMatrix * mvPosition; 
 

 
     u_pop = pop; 
 
    } 
 
</script>

`

答えて

2

あなたはそのため、あなたは間違った概念や用語を使用し、3Dがどのように機能するかについて誤解しています。 3Dには「Z-インデックス」はありません。レンダーの視点(カメラ、仮想オブザーバー)からのオブジェクトの距離を反映するZ-buffer or Depth-buffer(2つの名前、同じもの)があります。 Naturarlyでは、デプステストを行うデプスバッファの目的は、最も近いオブジェクトを最も近いオブジェクトの前にレンダリングしないようにすることです(これにより、見えないピクセルが計算されないように最適化することもできます)。

また、エンジンが意図的にそのような機能を実装していない限り、フォアグラウンドの背景表示はどの階層によっても制御されません。オブジェクトは単に供給される順序でレンダリングされます。デプステストが無効になっている場合、最新のレンダリングされたオブジェクトは、以前レンダリングされたすべてのオブジェクトの前に表示されます。 3Dシーンでは、階層は表示順序ではなく、変換に関連しています(オブジェクトが深度テストなしでシーンの階層順にレンダリングされない限り)。

堅牢な方法で実現するには、深度送りを無効にし、レンダリングされるスプライトの順序を手動で制御し、最後にレンダリングされるもの1。これは非常に低レベルの操作であり、Three.JSがあなたがそれを制御することを許可しない限り、あなたはおそらくあなたの戦術を変えなければならないか、独自のWebGLエンジンを実装する必要があります。

+0

3つはベクトルの配列を並べ替えることができ、属性を高水準のインターフェイスで更新することができます。 – pailhead

関連する問題