webGL中主要有6種座標系.接下來看看如何在以下三種座標系之間進行座標數據的轉換:屏幕座標系,標準座標系,世界座標系.
- 屏幕座標系和標準設備座標系
先來了解一下這兩個座標系的定義,具體如下圖所示:
可以看到屏幕座標系的起始點(0,0)在左上角,而標準座標系的起始點在canvas中心處.
- 假設3D畫布的大小填滿window
假如我們要通過鼠標來操控3D畫布內的場景對象,需要將鼠標的座標位置轉換爲3D世界座標,具體流程爲屏幕座標->標準座標->世界座標,
具體代碼示例如下:
import {Vector3} from 'three';
onMouseClicked() {
const mouseX = event.clientX;//鼠標單擊座標X
const mouseY = event.clientY;//鼠標單擊座標Y
// 屏幕座標轉標準設備座標
const x = ( mouseX / window.innerWidth ) * 2 - 1;
const y = -( mouseY / window.innerHeight ) * 2 + 1;
//標準設備座標(z=0.5這個值並沒有一個具體的說法)
const stdVector = new Vector3(x, y, 0.5);
// 通過unproject方法,可以將標準設備座標轉世界座標
const worldVector = stdVector.unproject(camera);
// 進行剩下操作,比如判斷鼠標是否選中某個物體
}
// 窗口鼠標單擊
// window.addEventListener('click',onMouseClicked);
反過來,如果要求出物體響應的屏幕座標,世界座標->標準座標->屏幕座標,那麼可以這樣:
// const box = ...
const worldVector = new Vector3(
box.position.x,
box.position.y,
box.position.z
);
//世界座標轉標準設備座標
const stdVector = worldVector.project(camera);
const a = window.innerWidth / 2;
const b = window.innerHeight / 2;
//標準設備座標轉屏幕座標x,y
const x = Math.round(stdVector.x * a + a);
const y = Math.round(-stdVector.y * b + b);
- 假設3D畫布的只是window中的一個窗口,比如某個div內的canvas
這時候只要獲取到canvas所在的div的寬高及左上位移數據就可以計算了,具體如下:
const mouseX = event.clientX;//鼠標單擊座標X
const mouseY = event.clientY;//鼠標單擊座標Y
const rect = someDiv.getBoundingClientRect();
const x = ((mouseX - rect.left) / someDiv.clientWidth) * 2 - 1;
const y = - ((mouseY - rect.top) / someDiv.clientHeight) * 2 + 1;
const stdVector = new Vector3(x, y, 0.5);
// 通過unproject方法,可以將標準設備座標轉世界座標
const worldVector = stdVector.unproject(camera);