经纬志
首页 / three.js / API 文档

WebGLRenderer

先看结论

把场景画到 canvas 的渲染器,负责 GPU 上下文、输出色彩、阴影与绘制统计。

最后验证 2026-11-03 · three.js 0.160.0 · 更新 2026-10-27 · 引用本文
new THREE.WebGLRenderer(parameters) → WebGLRenderer

构造参数

参数默认说明
canvas自动创建传入已有 canvas,便于与现有页面结构结合
context—传入已有 WebGL2 上下文
antialiasfalse多重采样抗锯齿。开启后边缘更平滑,显存与带宽开销增加
alphafalse画布是否透明,需与 scene.background = null 配合
depthtrue是否创建深度缓冲,三维场景必须开启
stencilfalse模板缓冲,裁剪与遮罩用到时开启
premultipliedAlphatrue预乘透明度,与合成方式有关
preserveDrawingBufferfalse为 true 才能直接读取 canvas 像素,代价是性能下降
powerPreference'default'可选 'high-performance',双显卡设备上优先独显
logarithmicDepthBufferfalse对数深度,缓解超大范围的深度冲突
failIfMajorPerformanceCaveatfalse为 true 时在软件渲染环境直接失败,避免用户看到卡顿画面

关键属性

属性说明
domElement渲染器持有的 canvas 元素,插入页面即可显示
outputColorSpace输出色彩空间,通常设为 SRGBColorSpace
toneMapping色调映射,常用 ACESFilmicToneMapping
toneMappingExposure曝光系数,配合色调映射调整整体亮度
shadowMap.enabled是否渲染阴影
shadowMap.typeBasicShadowMap、PCFShadowMap、PCFSoftShadowMap、VSMShadowMap
shadowMap.autoUpdate静态场景可关闭,改为按需更新
info.render.calls上一帧的绘制调用次数,性能排查的关键指标
info.render.triangles上一帧的三角面数量
capabilities查询最大纹理尺寸、各向异性上限等硬件能力
autoClear每帧渲染前是否自动清屏,多视口渲染时常关闭

常用方法

方法说明
setSize(width, height, updateStyle)设置绘制尺寸,默认同时改 canvas 的 CSS 尺寸
setPixelRatio(value)设置像素比,高分屏上建议封顶到 2
render(scene, camera, target?)渲染一帧,可选渲染到离屏目标
setAnimationLoop(fn)设置每帧回调,传 null 停止
setClearColor(color, alpha)设置清屏色
setViewport(x, y, w, h)设置绘制区域,坐标原点在左下角
setScissor(x, y, w, h) / setScissorTest(bool)裁剪区域,多视口分屏常用
compile(scene, camera)预编译材质着色器,减少首次出现的卡顿
dispose()释放渲染器占用的 GPU 资源
forceContextLoss()主动丢弃 WebGL 上下文,页面切换时可用

初始化与销毁

const stage = document.getElementById('stage');

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.setSize(stage.clientWidth, stage.clientHeight);
renderer.outputColorSpace = THREE.SRGBColorSpace;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1.1;

renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;

stage.appendChild(renderer.domElement);

// 页面卸载或组件销毁
function destroy() {
  renderer.setAnimationLoop(null);
  renderer.dispose();
  renderer.domElement.remove();
}

用统计信息定位瓶颈

每帧读取 renderer.info.render.calls 与 renderer.info.render.triangles,能快速判断问题在哪一侧: 调用数高而面数不高,是对象太碎;面数高而调用数低,是单个网格过密。 前者用实例化或合并几何体,后者用层级细节与裁剪。

注意 info 在每次 render 开始时重置,所以要在一帧渲染结束后读取, 或使用 info.autoReset = false 手动累加多趟渲染的统计。

多画布与离屏渲染

每个 WebGLRenderer 都会创建一个 WebGL 上下文。浏览器对同时存在的上下文数量有限制, 常见上限在十几个左右,超出后最旧的上下文会被丢弃,表现为某块画布突然变黑。 页面里需要多视图时,优先用一个渲染器配多个视口,而不是多个渲染器。

像素比不是越高越好。从 2 提到 3,像素数增加一倍多,画面锐度的提升却很有限。 在 GIS 场景里,把这些算力让给几何与阴影通常更划算。

引用本文

经纬志(2026)。《WebGLRenderer》。https://www.jingweizhi.com/three/api/webgl-renderer.html(访问日期 2026-11-03)。