You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Three.js:如何设置自定义分辨率并导出指定尺寸PNG图片?

解决Three.js WebGLRenderer导出自定义分辨率PNG的问题

嘿,我刚好碰到过类似的问题,这就来帮你搞定这个自定义分辨率导出的bug!

你遇到的核心问题是:直接修改尺寸后没有让渲染器用新分辨率重新渲染场景,而且可能没同步更新相机参数,导致导出的还是原来画布的尺寸内容。下面是完整的解决思路和修改后的代码:

关键解决步骤

  1. 保存原始渲染状态:导出前先记录当前渲染器的尺寸、像素比,还有相机的宽高比,导出后要恢复回来,不然页面上的3D视图会变形。
  2. 映射自定义分辨率:把你选择的尺寸选项(比如's'/'m'/'l')对应到具体的宽高数值。
  3. 更新渲染器参数:设置新的像素尺寸,注意不要修改canvas的CSS样式(避免页面元素乱跑),同时调整像素比保证导出图片清晰。
  4. 同步相机参数:更新相机的宽高比并重新计算投影矩阵,防止场景拉伸变形。
  5. 重新渲染场景:这是最关键的一步!必须让渲染器用新尺寸重新绘制一次场景,才能得到对应分辨率的图像。
  6. 导出并恢复原始状态:导出图片后,把渲染器和相机恢复到原来的设置,保证页面正常显示。

修改后的完整代码示例

// 假设你已经定义了scene和camera变量
var width, height, renderer3D, scene, camera; 
renderer3D = new THREE.WebGLRenderer({ 
    antialias: true,
    preserveDrawingBuffer: true 
});

this.ExportImage = function(){
    var imgSize = document.getElementById('imageSizeOption').value;
    
    // 定义尺寸选项对应的具体宽高(你可以根据需求修改)
    const sizeMapping = {
        's': { width: 800, height: 600 },
        'm': { width: 1200, height: 900 },
        'l': { width: 1920, height: 1080 },
        'xl': { width: 2560, height: 1440 }
    };
    
    // 获取目标尺寸,默认用当前画布尺寸
    const targetSize = sizeMapping[imgSize] || { 
        width: renderer3D.domElement.width, 
        height: renderer3D.domElement.height 
    };

    // 保存原始渲染参数,用于后续恢复
    const originalWidth = renderer3D.domElement.width;
    const originalHeight = renderer3D.domElement.height;
    const originalPixelRatio = renderer3D.getPixelRatio();
    const originalCameraAspect = camera.aspect;

    try {
        // 设置渲染器的新像素尺寸(第三个参数false:不修改canvas的CSS样式)
        renderer3D.setSize(targetSize.width, targetSize.height, false);
        // 设置像素比,用设备像素比保证导出图片清晰,也可以自定义比如2
        renderer3D.setPixelRatio(window.devicePixelRatio);

        // 更新相机宽高比并重新计算投影矩阵
        camera.aspect = targetSize.width / targetSize.height;
        camera.updateProjectionMatrix();

        // 关键!用新尺寸重新渲染场景
        renderer3D.render(scene, camera);

        // 导出PNG图片
        const dataURL = renderer3D.domElement.toDataURL('image/png');
        // 创建下载链接并触发下载
        const downloadLink = document.createElement('a');
        downloadLink.download = `threejs-export-${imgSize}.png`;
        downloadLink.href = dataURL;
        downloadLink.click();
    } finally {
        // 恢复原始渲染参数,保证页面上的3D视图正常显示
        renderer3D.setSize(originalWidth, originalHeight, false);
        renderer3D.setPixelRatio(originalPixelRatio);
        camera.aspect = originalCameraAspect;
        camera.updateProjectionMatrix();
        renderer3D.render(scene, camera);
    }
};

重点注意事项

  • 必须重新渲染:如果跳过renderer3D.render(scene, camera)这一步,导出的还是修改尺寸前的画布内容,分辨率自然不会变。
  • 相机参数同步:相机的宽高比必须和渲染器尺寸匹配,否则导出的图片会出现拉伸或压缩的情况。
  • 恢复原始状态:一定要在finally块里恢复原始设置,不然导出后页面上的3D视图会变成导出的尺寸,影响用户体验。

内容的提问来源于stack exchange,提问作者karthick187

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:39:25