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