javascript - 是否可以在 Three.js 中清晰地悬停在 LineSegment 的各个部分上,以识别那些只有一种几何形状的部分?

标签 javascript three.js

我在third.js中创建了两个绘制线条的示例,一个使用不同的geometrymaterial,另一个仅使用一种 >几何体和一种 Material 。 fiddle 的链接是:https://jsfiddle.net/sounakgarai/6reawwot/4/https://jsfiddle.net/sounakgarai/2xL70me3/分别。

我可以将鼠标悬停在第一个示例中的线条上,并可以看到它们在鼠标悬停时更改 Material 颜色。在第二个示例中,当我悬停时,整个 lineMeshcolor 会发生变化,因为只有一种 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/

相关文章:

javascript - Three.js 鼠标滚轮用于向上/向下移动相机而不是放大/缩小

javascript - InstancedBufferGeometry 的 PhongMaterial

javascript - Three.JS 动画在 Chrome v61 Mac OS X Sierra 上不显示

javascript - 固定地板立方体的动态高度

javascript - 在 Javascript 中捕获不同操作系统上的撤消、重做和其他关键事件

javascript - 返回的对象未定义

javascript - Raphael.js 相当于 JQuerys $(this) 选择器的是什么?

javascript - FBX动画使用三个js无法正常运行

javascript - GruntJS glob 作为源

javascript - jQuery 在页面加载时工作 3/4 次