700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Three.js-光线投射(raycaster)

Three.js-光线投射(raycaster)

时间:2022-04-03 13:16:54

相关推荐

Three.js-光线投射(raycaster)

目录

1.光线投射Raycaster

1.1 构造器

1.2 属性

1.3方法

2. 示例:点击变换颜色

1.光线投射Raycaster

这个类用于进行raycasting(光线投射)。 光线投射用于进行鼠标拾取(在三维空间中计算出鼠标移过了什么物体)。

1.1 构造器

Raycaster( origin :Vector3, direction :Vector3, near :Float, far :Float)

origin—— 光线投射的原点向量。

direction—— 向射线提供方向的方向向量,应当被标准化。

near—— 返回的所有结果比near远。near不能为负值,其默认值为0。

far—— 返回的所有结果都比far近。far不能小于near,其默认值为Infinity(正无穷。)

1.2 属性

.far:Float

raycaster的远距离因数(投射远点)。这个值表明哪些对象可以基于该距离而被raycaster所丢弃。 这个值不应当为负,并且应当比near属性大。

.near:Float

raycaster的近距离因数(投射近点)。这个值表明哪些对象可以基于该距离而被raycaster所丢弃。 这个值不应当为负,并且应当比far属性小。

.camera:Camera

对依赖于视图的对象(例如Sprites等广告牌对象)进行光线投射时使用的相机。该字段可以手动设置,也可以在调用“setFromCamera”时设置。默认为空。

.layers:Layers

Raycaster 在执行相交测试时使用它来选择性地忽略 3D 对象。以下代码示例确保Raycaster 实例 仅支持第1层上的 3D 对象。

raycaster.layers.set( 1 );object.layers.enable( 1 );

.params:Object

具有以下属性的对象:

{Mesh: {},Line: { threshold: 1 },LOD: {},Points: { threshold: 1 },Sprite: {}}

其中threshold是光线投射器在与对象相交时的精度,以世界单位为单位。

.ray:Ray

用于进行光线投射的Ray(射线)。

1.3方法

.set( origin :Vector3, direction :Vector3) :undefined

origin—— 光线投射的原点向量。

direction—— 为光线提供方向的标准化方向向量。

使用一个新的原点和方向来更新射线。

.setFromCamera( coords :Vector2, camera :Camera) :undefined

coords—— 在标准化设备坐标中鼠标的二维坐标 —— X分量与Y分量应当在-1到1之间。

camera—— 射线所来源的摄像机。

使用一个新的原点和方向来更新射线。

.intersectObject( object :Object3D, recursive :Boolean, optionalTarget :Array) :Array

object—— 检查与射线相交的物体。

recursive—— 若为true,则同时也会检查所有的后代。否则将只会检查对象本身。默认值为true。

optionalTarget— (可选)设置结果的目标数组。如果不设置这个值,则一个新的Array会被实例化;如果设置了这个值,则在每次调用之前必须清空这个数组(例如:array.length = 0;)。

检测所有在射线与物体之间,包括或不包括后代的相交部分。返回结果时,相交部分将按距离进行排序,最近的位于第一个。

该方法返回一个包含有交叉部分的数组:

[ { distance, point, face, faceIndex, object }, ... ]

distance—— 射线投射原点和相交部分之间的距离。

point—— 相交部分的点(世界坐标)

face—— 相交的面

faceIndex—— 相交的面的索引

object—— 相交的物体

uv—— 相交部分的点的UV坐标。

uv2—— Second set of U,V coordinates at point of intersection

instanceId– The index number of the instance where the ray intersects the InstancedMesh

当计算这条射线是否和物体相交的时候,Raycaster将传入的对象委托给raycast方法。 这将可以让mesh对于光线投射的响应不同于lines和pointclouds。

请注意:对于网格来说,面必须朝向射线的原点,以便其能够被检测到。 用于交互的射线穿过面的背侧时,将不会被检测到。如果需要对物体中面的两侧进行光线投射, 你需要将material中的side属性设置为THREE.DoubleSide

.intersectObjects( objects :Array, recursive :Boolean, optionalTarget :Array) :Array

objects—— 检测和射线相交的一组物体。

recursive—— 若为true,则同时也会检测所有物体的后代。否则将只会检测对象本身的相交部分。默认值为true。

optionalTarget—— (可选)设置结果的目标数组。如果不设置这个值,则一个新的Array会被实例化;如果设置了这个值,则在每次调用之前必须清空这个数组(例如:array.length = 0;)。

检测所有在射线与这些物体之间,包括或不包括后代的相交部分。返回结果时,相交部分将按距离进行排序,最近的位于第一个),相交部分和.intersectObject所返回的格式是相同的。

2. 示例:点击变换颜色

import * as THREE from "three";// 导入轨道控制器import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";// 目标:raycaster// 1、创建场景const scene = new THREE.Scene();// 2、创建相机const camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,300);const textureLoader = new THREE.TextureLoader();const particlesTexture = textureLoader.load("./textures/particles/1.png");// 设置相机位置camera.position.set(0, 0, 20);scene.add(camera);const cubeGeometry = new THREE.BoxBufferGeometry(1, 1, 1);const material = new THREE.MeshBasicMaterial({wireframe: true,});const redMaterial = new THREE.MeshBasicMaterial({color: "#ff0000",});// 1000立方体let cubeArr = [];for (let i = -5; i < 5; i++) {for (let j = -5; j < 5; j++) {for (let z = -5; z < 5; z++) {const cube = new THREE.Mesh(cubeGeometry, material);cube.position.set(i, j, z);scene.add(cube);cubeArr.push(cube);}}}// 创建投射光线对象const raycaster = new THREE.Raycaster();// 鼠标的位置对象const mouse = new THREE.Vector2();// 监听鼠标的点击位置window.addEventListener("click", (event) => {// console.log(event);mouse.x = (event.clientX / window.innerWidth) * 2 - 1;mouse.y = -((event.clientY / window.innerHeight) * 2 - 1);raycaster.setFromCamera(mouse, camera);let result = raycaster.intersectObjects(cubeArr);// console.log(result);// result[0].object.material = redMaterial;result.forEach((item) => {item.object.material = redMaterial;});});// 初始化渲染器const renderer = new THREE.WebGLRenderer();// 设置渲染的尺寸大小renderer.setSize(window.innerWidth, window.innerHeight);// 开启场景中的阴影贴图renderer.shadowMap.enabled = true;renderer.physicallyCorrectLights = true;// console.log(renderer);// 将webgl渲染的canvas内容添加到bodydocument.body.appendChild(renderer.domElement);// // 使用渲染器,通过相机将场景渲染进来// renderer.render(scene, camera);// 创建轨道控制器const controls = new OrbitControls(camera, renderer.domElement);// 设置控制器阻尼,让控制器更有真实效果,必须在动画循环里调用.update()。controls.enableDamping = true;// 添加坐标轴辅助器const axesHelper = new THREE.AxesHelper(5);scene.add(axesHelper);// 设置时钟const clock = new THREE.Clock();function render() {let time = clock.getElapsedTime();controls.update();renderer.render(scene, camera);// 渲染下一帧的时候就会调用render函数requestAnimationFrame(render);}render();// 监听画面变化,更新渲染画面window.addEventListener("resize", () => {// console.log("画面变化了");// 更新摄像头camera.aspect = window.innerWidth / window.innerHeight;// 更新摄像机的投影矩阵camera.updateProjectionMatrix();// 更新渲染器renderer.setSize(window.innerWidth, window.innerHeight);// 设置渲染器的像素比renderer.setPixelRatio(window.devicePixelRatio);});

实现效果:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。