关于 threejs-core-renderer
threejs-core-renderer 是面向 Three.js 开发者的渲染器参考技能,涵盖 WebGLRenderer、相机、渲染循环与资源清理。它还整理颜色管理、阴影、渲染目标和着色器编译的配置要点。
主要功能
- 01配置 WebGLRenderer 与颜色管理
- 02设置阴影、视口和裁剪平面
- 03管理相机、尺寸调整与渲染循环
- 04使用渲染目标及编译着色器
- 05清理并释放渲染器资源
适用场景
- 01初始化 Three.js WebGL 渲染场景
- 02为窗口调整相机和渲染器尺寸
- 03配置阴影、色调映射和颜色空间
- 04卸载场景时释放 WebGL 资源
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ impertio-studio/ three.js-claude-skill-package --skill threejs-core-renderer安装后在 Claude Code 中输入/threejs-core-renderer确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
.gitkeepreferences/anti-patterns.mdexamples.mdmethods.md详细介绍
threejs-core-renderer
快速参考
标准初始化模式
import {
WebGLRenderer, SRGBColorSpace, ACESFilmicToneMapping,
PCFSoftShadowMap, PerspectiveCamera, Scene
} from 'three';
const renderer = new WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.outputColorSpace = SRGBColorSpace;
renderer.toneMapping = ACESFilmicToneMapping;
renderer.toneMappingExposure = 1.0;
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = PCFSoftShadowMap;
document.body.appendChild(renderer.domElement);
const scene = new Scene();
const camera = new PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000);
renderer.setAnimationLoop((time) => {
renderer.render(scene, camera);
});
构造函数参数
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
canvas | HTMLCanvasElement | new canvas | 现有画布元素 |
context | WebGLRenderingContext | new context | 现有 WebGL 上下文 |
precision | 'highp' | 'mediump' | 'lowp' | 'highp' | 着色器精度 |
alpha | boolean | false | 画布背景是否透明 |
premultipliedAlpha | boolean | true | 预乘 Alpha 混合 |
antialias | boolean | false | MSAA 抗锯齿 |
stencil | boolean | true | 模板缓冲区 |
preserveDrawingBuffer | boolean | false | 截图所需 |
powerPreference | 'high-performance' | 'low-power' | 'default' | 'default' | GPU 选择提示 |
failIfMajorPerformanceCaveat | boolean | false | 使用软件渲染器时失败 |
depth | boolean | true | 深度缓冲区 |
logarithmicDepthBuffer | boolean | false | 修复大型场景中的 Z 冲突 |
切勿在构造后更改 antialias——创建后无法修改。
关键属性
| 属性 | 类型 | 默认值 | 描述 |
|---|---|---|---|
domElement | HTMLCanvasElement | -- | 画布。务必添加到 DOM |
shadowMap.enabled | boolean | false | 要使用任何阴影,必须设为 true |
shadowMap.type | ShadowMapType | PCFShadowMap | 阴影过滤算法 |
toneMapping | ToneMapping | NoToneMapping | HDR 色调映射算法 |
toneMappingExposure | number | 1 | 色调映射曝光度 |
outputColorSpace | string | SRGBColorSpace | 输出色彩空间 |
autoClear | boolean | true | 每次渲染调用前清除 |
sortObjects | boolean | true | 自动排序绘制顺序 |
clippingPlanes | Plane[] | [] | 全局裁剪平面 |
localClippingEnabled | boolean | false | 启用逐材质裁剪 |
info | object | -- | 渲染统计信息(调用次数、三角形数、内存) |
重要警告
切勿忘记限制像素比——在 3x 及以上屏幕上,不受限制的 devicePixelRatio 会导致像素负载增加 9 倍以上。务必使用 Math.min(window.devicePixelRatio, 2)。
切勿在首次渲染后更改 shadowMap.type——这会强制重新编译所有着色器。务必在初始化时设置一次。
切勿在生产环境的渲染循环中使用 preserveDrawingBuffer: true——这会禁用缓冲区交换优化。仅在需要截图时启用。
切勿将摄像机的 near: 0——这会导致各处出现 Z 冲突。务必将 far / near 比率保持在 10,000 以下。
切勿在修改 fov、aspect、near、far 或 zoom 后忘记调用 camera.updateProjectionMatrix()——投影矩阵不会自动更新。
切勿在 Three.js r160+ 中直接使用 requestAnimationFrame——务必使用 renderer.setAnimationLoop(),它会自动处理 WebXR 会话。
切勿在清理时跳过 renderer.dispose()——否则会泄漏 WebGL 上下文、程序、纹理和帧缓冲区。
色彩管理
Three.js r160+ 使用线性工作流,并在输出时自动进行 sRGB 转换。
色彩空间规则
| 纹理类型 | colorSpace | 示例 |
|---|---|---|
| 颜色 / 反照率 | SRGBColorSpace | 漫反射贴图、自发光贴图 |
| 数据 | LinearSRGBColorSpace | 法线贴图、粗糙度、金属度、AO、位移 |
规则: 颜色纹理始终使用 SRGBColorSpace。数据纹理始终使用 LinearSRGBColorSpace。混淆二者会导致渲染结果褪色或过饱和。
色调映射决策树
| 常量 | 使用场景 |
|---|---|
NoToneMapping | 非写实渲染、UI 叠加、无光照场景 |
LinearToneMapping | 基本的 HDR 限幅,色彩变换最少 |
ReinhardToneMapping | 通用场景,能很好地保留色相 |
CineonToneMapping | 电影胶片效果 |
ACESFilmicToneMapping | PBR 的默认选择。 行业标准的电影感曲线 |
AgXToneMapping | 对高饱和度颜色的处理优于 ACES。可避免 ACES 对明亮蓝色/红色造成的色相偏移。(r160+) |
NeutralToneMapping | 对色彩准确度要求极高、艺术化变换最少的场景 |
PBR 工作流中始终使用 ACESFilmicToneMapping 或 AgXToneMapping。如果必须准确保留高饱和度颜色,优先选择 AgXToneMapping。
阴影贴图配置
import { PCFSoftShadowMap } from 'three';
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = PCFSoftShadowMap;
| 类型 | 质量 | 性能 | 说明 |
|---|---|---|---|
BasicShadowMap | 低(硬边缘) | 最快 | 不进行滤波 |
PCFShadowMap | 中 | 中 | 默认值。百分比渐近滤波 |
PCFSoftShadowMap | 高(软边缘) | 较慢 | 双线性 PCF。最常用的选择 |
VSMShadowMap | 高(非常柔和) | 最慢 | 可能出现光线渗漏伪影 |
渲染循环与调整大小
setAnimationLoop(首选)
renderer.setAnimationLoop((time) => {
// time is DOMHighResTimeStamp in milliseconds
renderer.render(scene, camera);
});
// Stop the loop
renderer.setAnimationLoop(null);
窗口调整大小处理器
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
在调用 setSize() 前,始终更新 camera.aspect 并调用 updateProjectionMatrix()。
摄像机系统
PerspectiveCamera
import { PerspectiveCamera } from 'three';
const camera = new PerspectiveCamera(
50, // fov (vertical, degrees)
window.innerWidth / window.innerHeight, // aspect ratio
0.1, // near
1000 // far
);
camera.position.set(0, 5, 10);
camera.lookAt(0, 0, 0);
修改 fov、aspect、near、far 或 zoom 后,必须调用 camera.updateProjectionMatrix()。
OrthographicCamera
import { OrthographicCamera } from 'three';
const frustumSize = 10;
const aspect = window.innerWidth / window.innerHeight;
const camera = new OrthographicCamera(
-frustumSize * aspect / 2, // left
frustumSize * aspect / 2, // right
frustumSize / 2, // top
-frustumSize / 2, // bottom
0.1, 1000
);
调整大小时,始终更新视锥体的全部六个参数(left、right、top、bottom、near、far),然后调用 updateProjectionMatrix()。
ArrayCamera
在一次 render() 调用中渲染多个视口。每个子摄像机都有 camera.viewport = new Vector4(x, y, width, height)。用于分屏和 VR 立体渲染。
CubeCamera
将场景从全部 6 个方向渲染到 WebGLCubeRenderTarget 中。用于动态环境贴图。对于静态环境,绝不要每帧调用 cubeCamera.update()——每次调用都会渲染场景 6 次。
渲染目标
import { WebGLRenderTarget } from 'three';
const renderTarget = new WebGLRenderTarget(1024, 1024);
renderer.setRenderTarget(renderTarget);
renderer.render(scene, camera);
renderer.setRenderTarget(null); // restore default framebuffer
// renderTarget.texture is now usable as a regular Texture
不再需要时,始终调用 renderTarget.dispose()。
着色器编译
// Synchronous -- blocks the thread
renderer.compile(scene, camera);
// Asynchronous -- non-blocking, prevents frame drops (r160+)
await renderer.compileAsync(scene, camera);
加载资源后、首次可见渲染前,始终调用 compileAsync(),以避免即时着色器编译造成卡顿。
视口与裁剪
// Render to a sub-region of the canvas
renderer.setViewport(x, y, width, height);
renderer.setScissor(x, y, width, height);
renderer.setScissorTest(true);
renderer.render(scene, camera);
// Reset to full canvas
renderer.setScissorTest(false);
renderer.setViewport(0, 0, canvas.width, canvas.height);
裁剪平面
import { Plane, Vector3 } from 'three';
// Global clipping (affects all objects)
renderer.clippingPlanes = [new Plane(new Vector3(0, -1, 0), 1)];
// Per-material clipping (MUST enable localClippingEnabled)
renderer.localClippingEnabled = true;
material.clippingPlanes = [plane];
material.clipIntersection = false; // false = union, true = intersection
material.clipShadows = true; // also clip shadow geometry
清理与释放
renderer.setAnimationLoop(null);
renderer.dispose();
renderer.domElement.remove();
移除渲染器时,始终调用 dispose()。这会释放 WebGL 上下文、所有已编译的着色器程序、纹理和帧缓冲区。
WebGPU 渲染器
Three.js 包含一个实验性的 WebGPURenderer,它使用基于 TSL(Three Shading Language)节点的材质。如需 WebGPU 专项指南,请参阅 threejs-impl-webgpu 技能。
参考链接
- references/methods.md -- 完整的 WebGLRenderer 和 Camera API 签名
- references/examples.md -- 可运行的代码示例
- references/anti-patterns.md -- 不应采用的做法