【Laya】Camera 介绍
Laya.Camera是LayaAir 3D引擎的核心摄像机类,用于捕捉和渲染3D场景。它提供透视/正交两种投影模式,支持视野角度(FOV)、裁剪面、图层遮罩等参数配置,可自定义视口和渲染目标。摄像机还支持多种渲染效果,包括HDR、MSAA、FXAA等,并可通过视图矩阵和投影矩阵控制场景显示。作为3D场景的必备组件,Camera类为开发者提供了丰富的视觉控制选项。
Laya.Camera
概述
Laya.Camera 是 LayaAir 3D 引擎中的摄像机类,继承自 BaseCamera。摄像机用于捕捉 3D 场景并将其渲染到屏幕。每个 3D 场景至少需要一个摄像机才能显示内容。
继承关系
EventDispatcher → Node → Sprite3D → BaseCamera → Camera
↓
WebXRCamera
命名空间约定
必须使用 Laya. 前缀访问所有引擎类。
// ✅ 正确
const camera = new Laya.Camera();
camera.fieldOfView = 60;
// ❌ 错误
const camera = new Camera();
构造函数
constructor(aspectRatio: number = 0, nearPlane: number = 0.3, farPlane: number = 1000)
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| aspectRatio | number | 0 | 横纵比(0 为自动计算) |
| nearPlane | number | 0.3 | 近裁剪面距离 |
| farPlane | number | 1000 | 远裁剪面距离 |
// 创建默认摄像机
const camera = new Laya.Camera();
// 自定义裁剪面
const camera = new Laya.Camera(0, 0.1, 100);
// 设置横纵比
const camera = new Laya.Camera(16 / 9, 0.1, 100);
实例属性
视野和投影
fieldOfView
get fieldOfView(): number
set fieldOfView(value: number)
视野角度(FOV),单位为度。仅透视投影模式有效。
camera.fieldOfView = 60; // 60度视野
orthographic
get orthographic(): boolean
set orthographic(value: boolean)
是否使用正交投影。
// 透视投影(默认)
camera.orthographic = false;
// 正交投影
camera.orthographic = true;
orthographicVerticalSize
get orthographicVerticalSize(): number
set orthographicVerticalSize(value: number)
正交投影垂直尺寸。仅正交投影模式有效。
camera.orthographic = true;
camera.orthographicVerticalSize = 10;
aspectRatio
get aspectRatio(): number
set aspectRatio(value: number)
横纵比。
camera.aspectRatio = 16 / 9;
裁剪面
nearPlane
get nearPlane(): number
set nearPlane(value: number)
近裁剪面距离。小于此距离的对象不会被渲染。
camera.nearPlane = 0.1;
farPlane
get farPlane(): number
set farPlane(value: number)
远裁剪面距离。大于此距离的对象不会被渲染。
camera.farPlane = 500;
清除设置
clearFlag
clearFlag: CameraClearFlags
清除标志,定义如何清除渲染目标。
CameraClearFlags.SolidColor- 使用纯色清除CameraClearFlags.DepthOnly- 仅清除深度CameraClearFlags.Sky- 渲染天空盒
camera.clearFlag = Laya.CameraClearFlags.SolidColor;
clearColor
get clearColor(): Color
set clearColor(value: Color)
背景清除颜色。
camera.clearColor = new Laya.Color(0.2, 0.2, 0.2, 1.0);
图层遮罩
cullingMask
get cullingMask(): number
set cullingMask(value: number)
渲染图层遮罩,控制摄像机渲染哪些层的对象。
// 只渲染第0层
camera.cullingMask = 1 << 0;
// 渲染第0层和第1层
camera.cullingMask = (1 << 0) | (1 << 1);
// 渲染所有层
camera.addAllLayers();
渲染设置
enableRender
enableRender: boolean
是否允许渲染。
camera.enableRender = true;
enableHDR
get enableHDR(): boolean
set enableHDR(value: boolean)
是否开启 HDR(高动态范围渲染)。开启后对性能有一定影响。
camera.enableHDR = true;
msaa
get msaa(): boolean
set msaa(value: boolean)
多重采样抗锯齿。
camera.msaa = true;
fxaa
get fxaa(): boolean
set fxaa(value: boolean)
空间抗锯齿(FXAA)。
camera.fxaa = true;
opaquePass
get opaquePass(): boolean
set opaquePass(value: boolean)
OpaquePass 模式。
camera.opaquePass = false;
renderingOrder
get renderingOrder(): number
set renderingOrder(value: number)
渲染顺序。数值越小越先渲染。
camera.renderingOrder = 0;
矩阵
viewMatrix
get viewMatrix(): Matrix4x4
视图矩阵(只读)。
projectionMatrix
get projectionMatrix(): Matrix4x4
set projectionMatrix(value: Matrix4x4)
投影矩阵。
const projMatrix = camera.projectionMatrix;
projectionViewMatrix
get projectionViewMatrix(): Matrix4x4
视图投影矩阵(只读)。
视口
viewport
get viewport(): Viewport
set viewport(value: Viewport)
屏幕像素坐标的视口。
camera.viewport = new Laya.Viewport(0, 0, Laya.stage.width, Laya.stage.height);
normalizedViewport
get normalizedViewport(): Viewport
set normalizedViewport(value: Viewport)
归一化视口(0-1 范围)。
camera.normalizedViewport = new Laya.Viewport(0, 0, 0.5, 1.0); // 左半屏
clientWidth / clientHeight
get clientWidth(): number
get clientHeight(): number
视口宽度和高度(只读)。
渲染目标
renderTarget
get renderTarget(): RenderTexture
set renderTarget(value: RenderTexture)
自定义渲染目标。
const renderTexture = new Laya.RenderTexture(512, 512, Laya.RenderTargetFormat.R8G8B8A8, Laya.RenderTargetFormat.DEPTH_16);
camera.renderTarget = renderTexture;
depthTexture
set depthTexture(value: BaseTexture)
深度贴图。
camera.depthTexture = depthTexture;
depthTextureMode
get depthTextureMode(): DepthTextureMode
set depthTextureMode(value: DepthTextureMode)
深度贴图模式。
DepthTextureMode.None- 无深度贴图DepthTextureMode.Depth- 深度贴图DepthTextureMode.DepthNormals- 深度法线贴图
camera.depthTextureMode = Laya.DepthTextureMode.Depth;
depthTextureFormat
get depthTextureFormat(): RenderTargetFormat
set depthTextureFormat(value: RenderTargetFormat)
深度贴图格式。
camera.depthTextureFormat = Laya.RenderTargetFormat.DEPTH_16;
enableBlitDepth
get enableBlitDepth(): boolean
set enableBlitDepth(value: boolean)
是否使用内置深度贴图。
camera.enableBlitDepth = true;
后期处理
postProcess
get postProcess(): PostProcess
set postProcess(value: PostProcess)
后期处理。
const postProcess = new Laya.PostProcess();
// 配置后期处理效果...
camera.postProcess = postProcess;
其他属性
boundFrustum
get boundFrustum(): BoundFrustum
摄像机视锥体(只读)。
const frustum = camera.boundFrustum;
enableBuiltInRenderTexture
get enableBuiltInRenderTexture(): boolean
set enableBuiltInRenderTexture(value: boolean)
是否使用内置 RenderTexture 为 CommandBuffer 服务。
camera.enableBuiltInRenderTexture = true;
opaqueTextureSize
opaqueTextureSize: number
不透明纹理大小。
camera.opaqueTextureSize = 512;
useOcclusionCulling
useOcclusionCulling: boolean
是否使用遮挡剔除。
camera.useOcclusionCulling = true;
实例方法
坐标转换
viewportPointToRay()
计算从屏幕空间生成的射线。
viewportPointToRay(point: Vector2, out: Ray): void
const point = new Laya.Vector2(Laya.stage.mouseX, Laya.stage.mouseY);
const ray = new Laya.Ray(new Laya.Vector3(), new Laya.Vector3());
camera.viewportPointToRay(point, ray);
// 用于射线检测
const hitResult = new Laya.HitResult();
scene.physicsSimulation.rayCast(ray, hitResult);
normalizedViewportPointToRay()
计算从裁切空间(归一化坐标)生成的射线。
normalizedViewportPointToRay(point: Vector2, out: Ray): void
const point = new Laya.Vector2(0.5, 0.5); // 屏幕中心
const ray = new Laya.Ray();
camera.normalizedViewportPointToRay(point, ray);
worldToViewportPoint()
将一个点从世界空间转换到视口空间。
worldToViewportPoint(position: Vector3, out: Vector4): void
const worldPos = new Laya.Vector3(0, 0, 0);
const viewportPos = new Laya.Vector4();
camera.worldToViewportPoint(worldPos, viewportPos);
console.log(viewportPos.x, viewportPos.y); // 屏幕坐标
worldToNormalizedViewportPoint()
将一个点从世界空间转换到归一化视口空间。
worldToNormalizedViewportPoint(position: Vector3, out: Vector4): void
convertScreenCoordToOrthographicCoord()
转换 2D 屏幕坐标到 3D 正交投影下的坐标系统。仅正交投影模式下有效。
convertScreenCoordToOrthographicCoord(source: Vector3, out: Vector3): boolean
const screenPos = new Laya.Vector3(Laya.stage.mouseX, Laya.stage.mouseY, 0);
const worldPos = new Laya.Vector3();
camera.convertScreenCoordToOrthographicCoord(screenPos, worldPos);
sprite.transform.position = worldPos;
CommandBuffer
addCommandBuffer()
添加渲染命令缓存。
addCommandBuffer(event: CameraEventFlags, commandBuffer: CommandBuffer): void
const commandBuffer = new Laya.CommandBuffer();
// 配置命令缓冲...
camera.addCommandBuffer(Laya.CameraEventFlags.BeforeTransparent, commandBuffer);
removeCommandBuffer()
移除指定的渲染命令缓存。
removeCommandBuffer(event: CameraEventFlags, commandBuffer: CommandBuffer): void
camera.removeCommandBuffer(Laya.CameraEventFlags.BeforeTransparent, commandBuffer);
removeCommandBuffers()
移除指定事件的所有渲染命令缓存。
removeCommandBuffers(event: CameraEventFlags): void
camera.removeCommandBuffers(Laya.CameraEventFlags.BeforeTransparent);
图层管理
addAllLayers()
增加所有图层。
camera.addAllLayers();
removeAllLayers()
移除所有图层。
camera.removeAllLayers();
addLayer()
增加指定图层。
addLayer(layer: number): void
camera.addLayer(1);
removeLayer()
移除指定图层。
removeLayer(layer: number): void
camera.removeLayer(1);
渲染
render()
渲染场景。
render(scene: Scene3D): void
camera.render(scene);
投影矩阵
resetProjectionMatrix()
重新计算投影矩阵。
resetProjectionMatrix(): void
camera.resetProjectionMatrix();
克隆
clone()
克隆摄像机。
clone(): Camera
const newCamera = camera.clone();
scene.addChild(newCamera);
销毁
destroy()
销毁摄像机。
destroy(destroyChild: boolean = true): void
camera.destroy();
静态方法
drawRenderTextureByScene()
根据相机和场景信息获取场景某位置的渲染结果。
static drawRenderTextureByScene(
camera: Camera,
scene: Scene3D,
renderTexture: RenderTexture
): RenderTexture
drawTextureCubeByScene()
根据场景中的位置绘制立方体贴图。
static drawTextureCubeByScene(
camera: Camera,
position: Vector3,
scene: Scene3D,
renderCubeSize: number,
format: TextureFormat,
cullingMask: number = 0
): TextureCube
getTexturePixel()
获取纹理像素。
static getTexturePixel(texture: Texture2D): ArrayBufferView
getTexturePixelAsync()
异步获取纹理像素。
static getTexturePixelAsync(texture: Texture2D): Promise<ArrayBufferView>
使用示例
创建基础摄像机
export async function main() {
await Laya.init(0, 0);
const scene = new Laya.Scene3D();
Laya.stage.addChild(scene);
// 创建摄像机
const camera = new Laya.Camera();
camera.transform.position = new Laya.Vector3(0, 3, 10);
camera.transform.lookAt(new Laya.Vector3(0, 0, 0), new Laya.Vector3(0, 1, 0));
scene.addChild(camera);
// 设置视野
camera.fieldOfView = 60;
// 设置裁剪面
camera.nearPlane = 0.1;
camera.farPlane = 100;
}
设置背景颜色
export async function main() {
await Laya.init(0, 0);
const scene = new Laya.Scene3D();
Laya.stage.addChild(scene);
const camera = new Laya.Camera();
camera.transform.position = new Laya.Vector3(0, 3, 10);
scene.addChild(camera);
// 设置纯色背景
camera.clearFlag = Laya.CameraClearFlags.SolidColor;
camera.clearColor = new Laya.Color(0.2, 0.2, 0.2, 1.0);
}
正交投影摄像机
export async function main() {
await Laya.init(0, 0);
const scene = new Laya.Scene3D();
Laya.stage.addChild(scene);
// 创建正交投影摄像机
const camera = new Laya.Camera();
camera.orthographic = true;
camera.orthographicVerticalSize = 10;
camera.transform.position = new Laya.Vector3(0, 0, -10);
scene.addChild(camera);
}
射线检测(点击场景)
export async function main() {
await Laya.init(0, 0);
const scene = new Laya.Scene3D();
Laya.stage.addChild(scene);
const camera = new Laya.Camera();
camera.transform.position = new Laya.Vector3(0, 3, 10);
scene.addChild(camera);
// 监听鼠标点击
Laya.stage.on(Laya.Event.MOUSE_DOWN, this, () => {
const point = new Laya.Vector2(Laya.stage.mouseX, Laya.stage.mouseY);
const ray = new Laya.Ray(new Laya.Vector3(), new Laya.Vector3());
camera.viewportPointToRay(point, ray);
const hitResult = new Laya.HitResult();
scene.physicsSimulation.rayCast(ray, hitResult);
if (hitResult.succeeded) {
console.log("点击位置:", hitResult.point);
console.log("点击对象:", hitResult.collider.owner.name);
}
});
}
世界坐标转屏幕坐标
export async function main() {
await Laya.init(0, 0);
const scene = new Laya.Scene3D();
Laya.stage.addChild(scene);
const camera = new Laya.Camera();
camera.transform.position = new Laya.Vector3(0, 3, 10);
scene.addChild(camera);
const sprite = new Laya.Sprite3D("TestSprite");
sprite.transform.position = new Laya.Vector3(0, 0, 0);
scene.addChild(sprite);
// 将 3D 位置转换为屏幕坐标
const worldPos = sprite.transform.position;
const viewportPos = new Laya.Vector4();
camera.worldToViewportPoint(worldPos, viewportPos);
console.log("屏幕X:", viewportPos.x);
console.log("屏幕Y:", viewportPos.y);
console.log("深度:", viewportPos.z);
}
分屏渲染(多摄像机)
export async function main() {
await Laya.init(0, 0);
const scene = new Laya.Scene3D();
Laya.stage.addChild(scene);
const width = Laya.stage.width;
const height = Laya.stage.height;
// 左侧摄像机
const camera1 = new Laya.Camera();
camera1.transform.position = new Laya.Vector3(-5, 3, 10);
camera1.viewport = new Laya.Viewport(0, 0, width / 2, height);
camera1.clearColor = new Laya.Color(0.8, 0.8, 1.0, 1.0);
scene.addChild(camera1);
// 右侧摄像机
const camera2 = new Laya.Camera();
camera2.transform.position = new Laya.Vector3(5, 3, 10);
camera2.viewport = new Laya.Viewport(width / 2, 0, width / 2, height);
camera2.clearColor = new Laya.Color(1.0, 0.8, 0.8, 1.0);
scene.addChild(camera2);
}
使用图层遮罩
export async function main() {
await Laya.init(0, 0);
const scene = new Laya.Scene3D();
Laya.stage.addChild(scene);
// 主摄像机(渲染所有层)
const mainCamera = new Laya.Camera();
mainCamera.addAllLayers();
scene.addChild(mainCamera);
// 小地图摄像机(只渲染特定层)
const miniMapCamera = new Laya.Camera();
miniMapCamera.removeAllLayers();
miniMapCamera.addLayer(8); // 只渲染第8层
miniMapCamera.orthographic = true;
scene.addChild(miniMapCamera);
// 设置对象图层
const sprite = new Laya.Sprite3D();
sprite.layer = 8;
scene.addChild(sprite);
}
渲染到纹理
export async function main() {
await Laya.init(0, 0);
const scene = new Laya.Scene3D();
Laya.stage.addChild(scene);
const camera = new Laya.Camera();
camera.transform.position = new Laya.Vector3(0, 3, 10);
scene.addChild(camera);
// 创建渲染目标
const renderTexture = new Laya.RenderTexture(512, 512, Laya.RenderTargetFormat.R8G8B8A8, Laya.RenderTargetFormat.DEPTH_16);
camera.renderTarget = renderTexture;
// 使用渲染纹理...
}
常见问题
Q: 新建 Scene3D 后看不到任何内容?
A: 场景必须添加摄像机才能渲染显示:
const scene = new Laya.Scene3D();
Laya.stage.addChild(scene);
// 必须添加摄像机
const camera = new Laya.Camera();
scene.addChild(camera);
Q: 如何调整摄像机视野范围?
A: 通过 fieldOfView 属性调整:
camera.fieldOfView = 60; // 数值越大,视野越广
Q: 透视投影和正交投影有什么区别?
A:
- 透视投影: 近大远小,符合真实视觉,适用于 3D 游戏
- 正交投影: 无透视效果,大小不随距离变化,适用于 2D 游戏或编辑器
// 透视投影
camera.orthographic = false;
// 正交投影
camera.orthographic = true;
camera.orthographicVerticalSize = 10;
Q: 如何实现点击 3D 物体?
A: 使用射线检测:
Laya.stage.on(Laya.Event.MOUSE_DOWN, this, () => {
const point = new Laya.Vector2(Laya.stage.mouseX, Laya.stage.mouseY);
const ray = new Laya.Ray(new Laya.Vector3(), new Laya.Vector3());
camera.viewportPointToRay(point, ray);
const hitResult = new Laya.HitResult();
scene.physicsSimulation.rayCast(ray, hitResult);
if (hitResult.succeeded) {
console.log("点击了:", hitResult.collider.owner.name);
}
});
Q: 如何实现小地图?
A: 使用第二个摄像机配合正交投影和图层遮罩:
// 小地图摄像机
const miniMapCamera = new Laya.Camera();
miniMapCamera.orthographic = true;
miniMapCamera.orthographicVerticalSize = 50;
miniMapCamera.removeAllLayers();
miniMapCamera.addLayer(8);
scene.addChild(miniMapCamera);
Q: nearPlane 和 farPlane 如何设置?
A: 根据场景尺度设置:
// 室内小场景
camera.nearPlane = 0.1;
camera.farPlane = 100;
// 室外大场景
camera.nearPlane = 0.3;
camera.farPlane = 2000;
Q: Camera 与 BaseCamera 的区别?
A: Camera 继承自 BaseCamera,增加了更多渲染功能:
- HDR 支持
- 后期处理
- 深度贴图模式
- CommandBuffer 支持
- 自定义渲染目标
版本: v3.3.7
文档生成时间: 2026-01-19
更多推荐


所有评论(0)