我在third.js
中创建了两个绘制线条的示例,一个使用不同的geometry
和material
,另一个仅使用一种 >几何体
和一种 Material
。 fiddle 的链接是:https://jsfiddle.net/sounakgarai/6reawwot/4/和 https://jsfiddle.net/sounakgarai/2xL70me3/分别。
我可以将鼠标悬停在第一个示例中的线条上,并可以看到它们在鼠标悬停时更改 Material
颜色
。在第二个示例中,当我悬停时,整个 lineMesh
的 color
会发生变化,因为只有一种 material
。
现在我想做的是仅使用一个几何图形
,如第二个示例中所示。但我想看到第一个示例中看到的效果:(第二个示例的)LineSegment
的所有不同部分我希望看到它们以某种方式悬停,以便我可以识别这些很明显(但我不想为此使用不同的几何图形
)。
可以实现吗?
重要的是,当我使用多个几何图形
时,它会使浏览器在渲染具有大量成员的大型模型时挂起并变慢。我还想将来在页面的不同 div 元素中渲染
多个 Three.js
模型。因此,它可能会使浏览器在渲染它们时变得更慢。
最佳答案
带有 THREE.BufferGeometry()
、THREE.LineSegments()
和 .vertexColors = THREE.VertexColors
的选项:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 10);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var points = [
new THREE.Vector3(-5, 5, 0),
new THREE.Vector3(),
new THREE.Vector3(),
new THREE.Vector3(5, 5, 0),
new THREE.Vector3(5, 5, 0),
new THREE.Vector3(5, -5, 0)
];
var geom = new THREE.BufferGeometry().setFromPoints(points);
geom.addAttribute("color", new THREE.BufferAttribute(new Float32Array([1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, .5, .5, .5, 1, 0, 1]), 3)); // we'll change this color attribute
geom.addAttribute("colorBase", new THREE.BufferAttribute(new Float32Array([1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, .5, .5, .5, 1, 0, 1]), 3)); // this attribute contains original colors for restoring
var mat = new THREE.LineBasicMaterial({
vertexColors: THREE.VertexColors
});
var line = new THREE.LineSegments(geom, mat);
scene.add(line);
// all of those variables are for re-use
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var intersects = [];
var oldIndex = -1;
var col = new THREE.Color();
window.addEventListener("mousemove", onMouseMove, false);
function onMouseMove(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
intersects = raycaster.intersectObject(line);
if (intersects.length === 0) return;
let idx = intersects[0].index;
if (idx !== oldIndex) highlightSegment(idx, 0xFFFF00);
}
function highlightSegment(idx, color) {
setColor(idx, color);
if (oldIndex !== -1) {
restoreColor();
}
line.geometry.attributes.color.needsUpdate = true;
oldIndex = idx; // save current index as an old one
}
function setColor(idx, color) { // change color for the current segment
let idxNear = idx % 2 === 0 ? idx + 1 : idx - 1; //
// if 'idx' is an index of the start point in a segment, then its pair will be idx + 1,
// otherwise is idx - 1.
col.set(color);
let colors = line.geometry.attributes.color;
colors.setXYZ(idx, col.r, col.g, col.b); // a very useful method of 'THREE.BufferAttribute()'
colors.setXYZ(idxNear, col.r, col.g, col.b);
}
function restoreColor() { // restore the original color for the old segment
let oldIndexNear = oldIndex % 2 === 0 ? oldIndex + 1 : oldIndex - 1;
let colors = line.geometry.attributes.color;
let colorBase = line.geometry.attributes.colorBase;
colors.copyAt(oldIndex, colorBase, oldIndex); // another useful method of 'THREE.BufferAttribute()'
colors.copyAt(oldIndexNear, colorBase, oldIndexNear);
}
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three@0.122.0/build/three.min.js"></script>
关于javascript - 是否可以在 Three.js 中清晰地悬停在 LineSegment 的各个部分上,以识别那些只有一种几何形状的部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48315571/