阅读:671回复:1
Three.js raycaster 填坑
Three.js中raycaster是射线,用于拾取物体的。
通过 THREE.Raycaster 实现模型选中与信息显示。 这是官方例子: var raycaster = new THREE.Raycaster(); var mouse = new THREE.Vector2(); function onMouseMove( event ) { mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1; mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1; } function render() { raycaster.setFromCamera( mouse, camera ); var intersects = raycaster.intersectObjects( scene.children ); for ( var i = 0; i < intersects.length; i++ ) { intersects[ i ].object.material.color.set( 0xff0000 ); } renderer.render( scene, camera ); } window.addEventListener( 'mousemove', onMouseMove, false ); window.requestAnimationFrame(render); 简单讲解下原理: webgl把中心点设置为0,然后把世界坐标分成高(-1,1)之间,宽也如此,所以首先把鼠标点击的位置转换成(-1,1)之间,然后从相机所在位置到鼠标点击的位置的连线画一条射线,射线穿过的物体就会被拾取。 重点是: 很多教程里,计算mouse.x和mouse.y的时候都是认为canvas占据整个屏幕计算的,所以用的window.innerWidth和window.innerHeight。但是: mouse.x和mouse.y是相对绘制的canvas计算,也就是说canvas的中心是(0,0),canvas的高和宽被分成(-1,1),所以如果你的canvas不是整个屏幕,用上述代码是无法正确拾取物体的。 下面直接上修改后的代码: <canvas width="600" height="600" id="canvas-dom-2">您的浏览器不支持canvas!</canvas> var mainCanvas = document.getElementById("canvas-dom-2"); renderer = new THREE.WebGLRenderer({ canvas: mainCanvas, antialias:true, //设置抗锯齿 alpha:true, //背景透明 }); renderer.setClearColor(0x000000,0.0); //设置渲染器背景颜色 renderer.setSize(mainCanvas.offsetWidth,mainCanvas.offsetHeight); mainCanvas.addEventListener( 'click', onDocumentClick, false ); ———————————————— function onDocumentClick(event){ event.preventDefault(); //console.log(mainCanvas.offsetWidth+"+"+mainCanvas.offsetHeight); mouse.x = ( (event.clientX - mainCanvas.getBoundingClientRect().left) / mainCanvas.offsetWidth ) * 2 - 1; mouse.y = - ( (event.clientY - mainCanvas.getBoundingClientRect().top) / mainCanvas.offsetHeight ) * 2 + 1; raycaster.setFromCamera( mouse, camera ); var intersects = raycaster.intersectObjects( object ); for ( var i = 0; i < intersects.length; i++ ) { console.log(intersects[ i ].object.userData.uid); } } 注意上面计算mouse的x和y的代码 https://blog.csdn.net/u013090676/article/details/77188088 |
|
沙发#
发布于:2024-07-07 12:52
首先,解释一下三种坐标系的概念:场景坐标系(世界坐标系)、屏幕坐标系、视点坐标系。
场景坐标 通过three.js构建出来的场景,都具有一个固定不变的坐标系(无论相机的位置在哪),并且放置的任何物体都要以这个坐标系来确定自己的位置,也就是(0,0, 0)坐标。例如我们创建一个场景并添加箭头辅助。 ———————————————— 屏幕坐标 在显示屏上的坐标就是屏幕坐标系。 如下图所示,其中的clientX和clientY的最值由,window.innerWidth,window.innerHeight决定。 视点坐标 视点坐标系就是以相机的中心点为原点,但是相机的位置,也是根据世界坐标系来偏移的,webGL会将世界坐标先变换到视点坐标,然后进行裁剪,只有在视线范围(视见体)之内的场景才会进入下一阶段的计算 射线检测 若想获取鼠标点击的物体,name就需要把屏幕坐标系转换为three.js中的三维坐标系。 three.js提供了一个类THREE.Raycaster可以用来解决这个问题。 看个示例图 THREE.Raycaster对象从屏幕上的点击位置向场景中发射一束光线。 // 计算出鼠标经过的3d空间中的对象 Raycaster( origin, direction, near, far ) { } origin — 射线的起点向量。 direction — 射线的方向向量,应该归一化。 near — 所有返回的结果应该比 near 远。Near不能为负,默认值为0。 far — 所有返回的结果应该比 far 近。Far 不能小于 near,默认值为无穷大。 & …… https://blog.csdn.net/ithanmang/article/details/80897888 |
|