如何解决在Three.js THREE.Points对象中逐个索引隐藏
我遇到了一个包含许多点的对象的问题(使用THREE.Points
创建)。一个示例为https://threejs.org/examples/?q=points#webgl_interactive_points
。现在,如果要单击某个特定点,我将尝试隐藏它。使用“相交-method I'm able to enlarge these or change their color: using
particles.geometry.attributes.size.array [INDEX] and setting
。needsUpdate`。但是,我完全看不见。目的是通过“缓冲区几何”中的索引隐藏点。您可以在下面找到该示例的代码段。
var vertices = new THREE.BoxGeometry( 200,200,16,16 ).vertices;
var positions = new Float32Array( vertices.length * 3 );
var colors = new Float32Array( vertices.length * 3 );
var sizes = new Float32Array( vertices.length );
var vertex;
var color = new THREE.Color();
for ( var i = 0,l = vertices.length; i < l; i ++ ) {
vertex = vertices[ i ];
vertex.toArray( positions,i * 3 );
color.setHSL( 0.01 + 0.1 * ( i / l ),1.0,0.5 );
color.toArray( colors,i * 3 );
sizes[ i ] = PARTICLE_SIZE * 0.5;
}
var geometry = new THREE.BufferGeometry();
geometry.setAttribute( 'position',new THREE.BufferAttribute( positions,3 ) );
geometry.setAttribute( 'customColor',new THREE.BufferAttribute( colors,3 ) );
geometry.setAttribute( 'size',new THREE.BufferAttribute( sizes,1 ) );
//
var material = new THREE.ShaderMaterial( {
uniforms: {
color: { value: new THREE.Color( 0xffffff ) },pointTexture: { value: new THREE.TextureLoader().load( "textures/sprites/disc.png" ) }
},vertexShader: document.getElementById( 'vertexshader' ).textContent,fragmentShader: document.getElementById( 'fragmentshader' ).textContent,alphaTest: 0.9
} );
//
particles = new THREE.Points( geometry,material );
scene.add( particles );
更改悬停时的“大小”的操作如下:
// function render() {
particles.rotation.x += 0.0005;
particles.rotation.y += 0.001;
var geometry = particles.geometry;
var attributes = geometry.attributes;
raycaster.setFromCamera( mouse,camera );
intersects = raycaster.intersectObject( particles );
if ( intersects.length > 0 ) {
if ( INTERSECTED != intersects[ 0 ].index ) {
attributes.size.array[ INTERSECTED ] = PARTICLE_SIZE;
INTERSECTED = intersects[ 0 ].index;
attributes.size.array[ INTERSECTED ] = PARTICLE_SIZE * 1.25;
attributes.size.needsUpdate = true;
}
我已经看过着色器(以我的观点认为这太复杂了,无法完成此任务),并尝试创建透明材质。有什么被忽略吗?
非常感谢。
解决方法
作为一种选择,使用附加的缓冲区属性来提高可见性并在着色器中对其进行处理,可以达到以下目的:
body {
overflow: hidden;
margin: 0;
}
<script type="module">
import * as THREE from "https://threejs.org/build/three.module.js";
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60,innerWidth / innerHeight,1,100);
camera.position.set(0,10);
let renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0x444444);
renderer.setSize(innerWidth,innerHeight);
document.body.appendChild(renderer.domElement);
let g = new THREE.PlaneBufferGeometry(10,10,10);
g.index = null;
let pos = g.getAttribute("position");
let colors = [];
let color = new THREE.Color();
let sizes = [];
let visibility = [];
for(let i = 0; i < pos.count; i++){
color.set( Math.random() * 0x888888 + 0x888888);
colors.push(color.r,color.g,color.b);
sizes.push( Math.random() * 0.5 + 0.5);
visibility.push(1);
}
g.setAttribute("color",new THREE.Float32BufferAttribute(colors,3));
g.setAttribute("sizes",new THREE.Float32BufferAttribute(sizes,1));
g.setAttribute("visibility",new THREE.Float32BufferAttribute(visibility,1));
let m = new THREE.PointsMaterial({
vertexColors: true,onBeforeCompile: function(shader){
shader.vertexShader = `
attribute float sizes;
attribute float visibility;
varying float vVisible;
${shader.vertexShader}`
.replace(
`gl_PointSize = size;`,`gl_PointSize = size * sizes;
vVisible = visibility;
`
);
shader.fragmentShader = `
varying float vVisible;
${shader.fragmentShader}`
.replace(
`#include <clipping_planes_fragment>`,`
if (vVisible < 0.5) discard;
#include <clipping_planes_fragment>`
)
}
});
let p = new THREE.Points(g,m);
scene.add(p);
let oldIndex = 0;
setInterval(function(){
let newIndex = THREE.Math.randInt(0,pos.count - 1);
g.attributes.visibility.setX(oldIndex,1);
g.attributes.visibility.setX(newIndex,0);
oldIndex = newIndex;
g.attributes.visibility.needsUpdate = true;
},500);
renderer.setAnimationLoop(animate);
function animate(){
renderer.render(scene,camera);
}
</script>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。