文章目錄
- 1. 引言:為什么相機是 3D 場景的“眼睛”?
- 1.1 相機的核心作用
- 1.2 常見相機類型概覽
- 2. 相機基礎參數解析
- 2.1 通用屬性
- 2.2 相機坐標系
- 3. 詳解常用相機類型
- 3.1 自由相機(FreeCamera)
- 3.2 弧形旋轉相機(ArcRotateCamera)
- 3.3 跟隨相機(FollowCamera)
- 3.4 其他相機類型(快速概覽)
- 4. 視角交互實戰技巧
- 4.1 多相機切換
- 4.2 自定義輸入控制
- 4.3 相機動畫與過渡
- 5. 相機性能優化與調試
- 5.1 視錐剔除(Frustum Culling)
- 5.2 避免過度繪制
- 5.3 使用調試工具
- 6. 實戰任務
- 任務 1:構建可切換的相機系統
- 任務 2:實現“物體聚焦”功能
- 7. 常見問題解答
- 8. 總結與下一章預告
- 8.1 關鍵知識點回顧
- 8.2 下一章預告
1. 引言:為什么相機是 3D 場景的“眼睛”?
- 上一章簡單介紹了場景中如何添加標準形狀的物體,并且介紹了如何調整物體屬性,包括位置、旋轉、縮放,以及父級關系的設置。
- 這一章詳細介紹一下Babylon中,相機相關的知識。涵蓋相機類型、交互配置及實戰技巧。
1.1 相機的核心作用
- 定義用戶視角:觀察場景的位置、方向、視野范圍。
- 交互基礎:通過鼠標/鍵盤/觸控控制視角移動。
1.2 常見相機類型概覽
- 自由相機(
FreeCamera
) - 弧形旋轉相機(
ArcRotateCamera
) - 跟隨相機(
FollowCamera
) - 第一人稱相機(
UniversalCamera
)
2. 相機基礎參數解析
2.1 通用屬性
- 位置(Position):
camera.position = new BABYLON.Vector3(x, y, z)
。 - 目標(Target):
camera.setTarget(new BABYLON.Vector3(x, y, z))
。 - 視野(FOV):
camera.fov = 0.8
(弧度制,影響廣角效果)。 - 近裁面與遠裁面(Clipping Planes):
camera.minZ = 0.1; // 近裁面(避免渲染過近物體)camera.maxZ = 1000; // 遠裁面(避免渲染過遠物體)
2.2 相機坐標系
- 局部坐標系:相機的移動方向基于自身朝向。
- 世界坐標系:相機的移動方向基于全局坐標軸。
3. 詳解常用相機類型
3.1 自由相機(FreeCamera)
- 特點:類似第一人稱射擊游戲的自由移動視角。
- 代碼創建:
const freeCamera= new BABYLON.FreeCamera("freeCamera", new BABYLON.Vector3(0, 5, -10), scene);freeCamera.setTarget(BABYLON.Vector3.Zero());
- 控制配置:
- 鍵盤移動:默認 WASD 控制前后左右,QE 控制升降。
- 鼠標控制視角:
camera.attachControl(canvas, true)
。 - 靈敏度調整:
freeCamera.speed = 0.5; // 移動速度freeCamera.angularSensibility = 2000; // 鼠標靈敏度(值越大越遲鈍)
- 其他相機配置參數:
// 相機反轉freeCamera.invertRotation = true;// 相機轉動速度freeCamera.inverseRotationSpeed = 3;// 相機y軸角度freeCamera.rotation.y = (rotation * Math.PI) / 180;// 添加滾輪輸入freeCamera.inputs.addMouseWheel();// 開啟觸摸控制freeCamera.inputs.attached.mouse.touchEnabled = true;// 鼠標輸入靈敏度。(默認值為2000.0)值越高,靈敏度越低。freeCamera.angularSensibility = 1300;// 定義攝像頭可以看到的最小距離 太小會閃面freeCamera.minZ = 10;// 定義攝像頭可以看到的最大距離freeCamera.maxZ = 20000;// 廣角freeCamera.fov = 1.6;// 定義相機的默認慣性。這有助于使相機運動平穩freeCamera.inertia = 0.8// 設置相機每個窗口的大小freeCamera.viewport = new BABYLON.Viewport(0, 0, 1, 1);
3.2 弧形旋轉相機(ArcRotateCamera)
- 特點:圍繞目標點旋轉、縮放,適合展示物體。
- 代碼創建:
const arcRotatecamera = new BABYLON.ArcRotateCamera("arcCam", alpha, beta, radius, // 初始角度(弧度)、半徑target, // 目標點(Vector3)scene);arcRotatecamera.attachControl(canvas, true);
- 其他相機配置參數:
// 最大移動距離arcRotatecamera.upperRadiusLimit = 50000;// 最小移動距離arcRotatecamera.lowerRadiusLimit = 10000;// 角度靈敏度XarcRotatecamera.angularSensibilityX = 5000;// 角度靈敏度YarcRotatecamera.angularSensibilityY = 5000;// 平移靈敏度arcRotatecamera.panningSensibility = 8000;// Beta角上限arcRotatecamera.upperBetaLimit = 0;// Beta角上限arcRotatecamera.lowerBetaLimit = 0;// 縱軸最大角度,限制攝影機在場景中的移動arcRotatecamera.upperAlphaLimit = 0;// 縱軸最小角度arcRotatecamera.lowerAlphaLimit = 0;// 允許上下顛倒arcRotatecamera.allowUpsideDown = false;// 滾輪精度arcRotatecamera.wheelPrecision = 0.01;// 指針捏合精度arcRotatecamera.pinchPrecision = 0.01;// 使用自然捏縮放arcRotatecamera.useNaturalPinchZoom = false;// 廣角arcRotatecamera.fov = 0.5;// 照相機渲染的最大距離arcRotatecamera.maxZ = 100000;// 照相機渲染的最小距離 太小會閃面arcRotatecamera.minZ = 5;// 讓視圖相機傾斜一點角度arcRotatecamera.alpha = 0;arcRotatecamera.beta = 0;// 設置相機每個窗口的大小arcRotatecamera.viewport = new BABYLON.Viewport(0, 0, 1, 1);
這里將 弧形旋轉相機 和 自由相機 做對比,對于同一個場景,可見 自由相機 對場景有拉伸效果,甚至對場景的顯示效果都有影響。
因此,選擇適合自己的相機格外重要。
- 關鍵參數:
- 限制旋轉角度:
camera.lowerBetaLimit = 0.1; camera.upperBetaLimit = Math.PI/2
。 - 限制縮放范圍:
camera.lowerRadiusLimit = 5; camera.upRadiusLimit = 20
。
- 限制旋轉角度:
- 交互優化:
- 啟用慣性效果:
camera.inertia = 0.9
(拖拽后平滑停止)。
- 啟用慣性效果:
3.3 跟隨相機(FollowCamera)
- 特點:跟隨某個物體移動,適合角色扮演游戲。
- 代碼創建:
const camera = new BABYLON.FollowCamera("followCam", new BABYLON.Vector3(0, 5, -10), // 初始位置scene);camera.radius = 10; // 跟隨距離camera.heightOffset = 2; // 垂直偏移camera.lockedTarget = playerMesh; // 綁定目標物體
3.4 其他相機類型(快速概覽)
- 第一人稱相機(UniversalCamera):針對移動端優化的自由相機。
- VR 設備相機(WebXRCamera):通過 WebXR 支持 VR 頭顯。
4. 視角交互實戰技巧
4.1 多相機切換
- 代碼示例:
const camera1 = new BABYLON.FreeCamera(...);const camera2 = new BABYLON.ArcRotateCamera(...);scene.activeCamera = camera1; // 切換活動相機
4.2 自定義輸入控制
- 覆蓋默認按鍵事件:
camera.keysUp = [87]; // W 鍵前進camera.keysDown = [83]; // S 鍵后退camera.keysLeft = [65]; // A 鍵左移camera.keysRight = [68]; // D 鍵右移
- 添加鼠標滾輪縮放(適用于
ArcRotateCamera
):
camera.wheelPrecision = 50; // 滾輪靈敏度
4.3 相機動畫與過渡
- 平滑移動相機到新位置:
BABYLON.Animation.CreateAndStartAnimation("camMove", camera, "position",30, 120, // 幀率、總幀數camera.position, // 起始位置new BABYLON.Vector3(10, 5, 0), // 目標位置BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT);
5. 相機性能優化與調試
5.1 視錐剔除(Frustum Culling)
- 原理:只渲染相機視野內的物體。
- Babylon.js 默認啟用,可通過
mesh.isVisible = false
手動控制。
5.2 避免過度繪制
- 調整
maxZ
值,減少遠處物體渲染。
5.3 使用調試工具
- 顯示相機視錐:
camera.showFrustum = true; // 顯示視錐線框
- 實時調試參數:通過
scene.debugLayer
調整相機屬性。
6. 實戰任務
任務 1:構建可切換的相機系統
- 場景中放置兩個相機:自由相機(默認)和弧形旋轉相機。
- 按空格鍵切換相機,并添加過渡動畫。
我這里添加了兩個按鈕,用來切換相機,其中使用 弧形旋轉相機 ArcRotateCamera 模擬了上帝視角。
任務 2:實現“物體聚焦”功能
- 點擊場景中的物體,弧形旋轉相機自動對準該物體并調整距離。
mesh.actionManager = new BABYLON.ActionManager(scene);mesh.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger,() => {arcCamera.setTarget(mesh.position);arcCamera.radius = mesh.getBoundingInfo().diagonalLength * 2;}));
7. 常見問題解答
- Q1:相機看不到物體?
- 檢查相機位置與目標點是否在物體附近。
- 確認物體的位置未被其他物體遮擋。
- Q2:移動端觸控不靈敏?
- 調整
angularSensibility
和wheelPrecision
。 - 使用
UniversalCamera
替代FreeCamera
。
- 調整
8. 總結與下一章預告
8.1 關鍵知識點回顧
- 自由相機、弧形旋轉相機的適用場景與控制優化。
- 多相機切換與自定義交互邏輯。
8.2 下一章預告
- 《燈光與陰影:讓場景栩栩如生的關鍵》:學習點光源、方向光與陰影渲染技術。