由於瀏覽器是一個2d視口,而在里面顯示three.js的內容是3d場景,所以,現在有一個問題就是如何將2d視口的x和y坐標轉換成three.js場景中的3d坐標。好在three.js已經有了解決相關問題的方案,那就是THREE.Raycaster射線,用於鼠標拾取(計算出鼠標移過的三維空間中的對象)。
我們一般都會設置三維場景的顯示區域,如果,指明當前顯示的2d
坐標給THREE.Raycaster
的話,它將生成一條從顯示的起點到終點的一條射線。也就是說,我們再屏幕上點擊了一個點,在three.js
里面獲取的則是一條直線。
鼠標在屏幕上點擊的時候,得到二維坐標p(x, y),再加上深度坐標的范圍(0, 1), 就可以形成兩個三位坐標A(x1, y1, 0), B(x2, y, 1), 由於它們的Z軸坐標是0和1,則轉變到投影坐標系的話,一定分別是前剪切平面上的點和后剪切平面上的點,也就是說,在投影坐標系中,A點一定在能看見的所有模型的最前面,B點一定在能看見的所有的模型的最后邊,將AB點連成線,AB線穿過的物體就是被點擊的物體。而 Three.js提供一個射線類Raycasting來拾取場景里面的物體。更方便的使用鼠標來操作3D場景。(不過在實際代碼中我們組成射線的兩個點是攝像機所在視點與屏幕上點擊的點連接而成的射線)
思路:先通過當前點擊位置的坐標和相機計算出raycaster
線,然后計算出相交的所有模型,修改模型的紋理。
代碼實現:
var raycaster = new THREE.Raycaster() var mouse = new THREE.Vector2() function onMouseClick(event){ //將鼠標點擊位置的屏幕坐標轉換成threejs中的標准坐標
mouse.x = (event.clientX / window.innerWidth) * 2 - 1 mouse.y = (event.clientY/window.innerHeight) *2 + 1
// 通過鼠標點的位置和當前相機的矩陣計算出raycaster
raycaster.setFromCamera( mouse, camera ); // 獲取raycaster直線和所有模型相交的數組集合
var intersects = raycaster.intersectObjects( scene.children ); console.log(intersects); //將所有的相交的模型的顏色設置為紅色for ( var i = 0; i < intersects.length; i++ ) { intersects[ i ].object.material.color.set( 0xff0000 ); } } window.addEventListener( 'click', onMouseClick, false );