Skip to content

BabylonJS - 创建截图

将您的 Babylon.js 场景的当前视图捕获为图像文件是一个常见的需求。虽然可以通过操作系统级别的截图,但这可能无法提供所需的更高分辨率或仅捕获 canvas 内容。Babylon.js 提供了专门的工具,可以直接从渲染的场景创建高质量截图。

主要方法是 BABYLON.Tools.CreateScreenshotUsingRenderTarget。此函数提供了更多控制,并且通常比旧方法性能更好,尤其是在引擎的 preserveDrawingBuffer 选项被禁用时(建议为了性能考虑将其禁用)。

要进行截图,您通常需要提供 engine (引擎)、camera (相机) 和所需的尺寸,或指定一个 render target (渲染目标)。

import * as BABYLON from '@babylonjs/core';
// Assuming 'engine' and 'camera' are already initialized
const size = { width: 1920, height: 1080 }; // Desired screenshot dimensions
BABYLON.Tools.CreateScreenshotUsingRenderTarget(engine, camera, size, (data) => {
// 'data' contains the screenshot as a Base64 encoded data URL (e.g., "data:image/png;base64,...")
// 'data' 包含截图的 Base64 编码数据 URL(例如,“data:image/png;base64,...”)
// Example: Display the image on the page
// 示例:在页面上显示图像
const img = document.createElement("img");
img.src = data;
img.style.position = 'absolute';
img.style.bottom = '10px';
img.style.right = '10px';
img.style.width = '150px'; // Optional: resize for display
// 可选:调整显示尺寸
document.body.appendChild(img);
// Example: Trigger download
// 示例:触发下载
// const link = document.createElement('a');
// link.download = 'screenshot.png';
// link.href = data;
// link.click();
}, 'image/png', 8, true); // mimeType, samples, antialiasing, fileName (optional)
// mimeType, 采样数, 抗锯齿, 文件名(可选)

您可以将此调用包裹在一个按钮的点击处理程序中,以允许用户触发截图。

旧方法有时需要在引擎创建时设置 preserveDrawingBuffer: true 和 stencil: true。尽管 CreateScreenshotUsingRenderTarget 通常在不设置 preserveDrawingBuffer 的情况下工作,但请注意,启用它可能会对某些设备的性能产生负面影响。通常建议保持 preserveDrawingBuffer: false(默认值),并使用 CreateScreenshotUsingRenderTarget。

// Example engine creation (defaults are usually fine for screenshots with the modern method)
// 引擎创建示例(对于使用现代方法的截图,默认值通常即可)
const engine = new BABYLON.Engine(canvas, true); // 'true' enables anti-aliasing
// 'true' 启用抗锯齿

下面是一个完整的示例,演示如何设置场景并添加一个按钮来截图。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Babylon.js - Screenshot Demo</title>
<script src="https://cdn.babylonjs.com/babylon.js"></script>
<script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script> <!-- Optional: For loading textures -->
<!-- 可选:用于加载纹理 -->
<style>
html, body { overflow: hidden; width: 100%; height: 100%; margin: 0; padding: 0; }
#renderCanvas { width: 100%; height: 100%; touch-action: none; }
#screenshotBtn {
position: absolute;
top: 20px;
right: 20px;
padding: 10px 15px;
cursor: pointer;
}
</style>
</head>
<body>
<canvas id="renderCanvas"></canvas>
<button id="screenshotBtn">Take Screenshot (1920x1080)</button>
<!-- 截图按钮 -->
<script type="text/javascript">
const canvas = document.getElementById("renderCanvas");
const engine = new BABYLON.Engine(canvas, true, { /* preserveDrawingBuffer: false (default) */ });
// preserveDrawingBuffer: false (默认)
const createScene = function () {
const scene = new BABYLON.Scene(engine);
scene.clearColor = new BABYLON.Color4(0.2, 0.3, 0.4, 1.0);
const camera = new BABYLON.ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 2.5, 15, BABYLON.Vector3.Zero(), scene);
camera.attachControl(canvas, true);
const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0), scene);
light.intensity = 0.7;
const sphere = BABYLON.MeshBuilder.CreateSphere("sphere", { diameter: 2, segments: 32 }, scene);
sphere.position.y = 1;
const ground = BABYLON.MeshBuilder.CreateGround("ground", { width: 6, height: 6 }, scene);
// Optional: Add some materials
// 可选:添加一些材质
const sphereMat = new BABYLON.StandardMaterial("sphereMat", scene);
sphereMat.diffuseColor = new BABYLON.Color3(0.8, 0.3, 0.3);
sphere.material = sphereMat;
const groundMat = new BABYLON.StandardMaterial("groundMat", scene);
groundMat.diffuseColor = new BABYLON.Color3(0.5, 0.8, 0.5);
ground.material = groundMat;
return scene;
};
const scene = createScene();
engine.runRenderLoop(function () {
scene.render();
});
window.addEventListener("resize", function () {
engine.resize();
});
// Screenshot Button Logic
// 截图按钮逻辑
const screenshotBtn = document.getElementById("screenshotBtn");
screenshotBtn.addEventListener("click", function () {
const screenshotSize = { width: 1920, height: 1080 };
BABYLON.Tools.CreateScreenshotUsingRenderTarget(engine, scene.activeCamera, screenshotSize, (data) => {
// Trigger download
// 触发下载
const link = document.createElement('a');
link.download = 'babylonjs_screenshot.png';
link.href = data;
document.body.appendChild(link); // Required for Firefox
// Firefox 需要此行
link.click();
document.body.removeChild(link);
console.log("Screenshot taken!");
// 截图已生成!
}, 'image/png');
});
</script>
</body>
</html>

运行上面的代码将显示一个 3D 场景,其中有一个红色球体位于绿色地面上。一个标有“Take Screenshot (1920x1080)”的按钮将位于右上角。点击此按钮将生成一个 1920x1080 的 PNG 图像,内容为当前视图,并触发名为 babylonjs_screenshot.png 的文件下载。