mcpField
T
threejs-core-renderer

threejs-core-renderer

github.com/impertio-studio开发23143 次安装30 周前更新
代码仓库

关于 threejs-core-renderer

threejs-core-renderer 是面向 Three.js 开发者的渲染器参考技能,涵盖 WebGLRenderer、相机、渲染循环与资源清理。它还整理颜色管理、阴影、渲染目标和着色器编译的配置要点。

主要功能

  1. 01配置 WebGLRenderer 与颜色管理
  2. 02设置阴影、视口和裁剪平面
  3. 03管理相机、尺寸调整与渲染循环
  4. 04使用渲染目标及编译着色器
  5. 05清理并释放渲染器资源

适用场景

  1. 01初始化 Three.js WebGL 渲染场景
  2. 02为窗口调整相机和渲染器尺寸
  3. 03配置阴影、色调映射和颜色空间
  4. 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 外,安装时一起下载的参考资料和脚本。

.gitkeep
references/
anti-patterns.md
examples.md
methods.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);
});
构造函数参数
参数类型默认值描述
canvasHTMLCanvasElementnew canvas现有画布元素
contextWebGLRenderingContextnew context现有 WebGL 上下文
precision'highp' | 'mediump' | 'lowp''highp'着色器精度
alphabooleanfalse画布背景是否透明
premultipliedAlphabooleantrue预乘 Alpha 混合
antialiasbooleanfalseMSAA 抗锯齿
stencilbooleantrue模板缓冲区
preserveDrawingBufferbooleanfalse截图所需
powerPreference'high-performance' | 'low-power' | 'default''default'GPU 选择提示
failIfMajorPerformanceCaveatbooleanfalse使用软件渲染器时失败
depthbooleantrue深度缓冲区
logarithmicDepthBufferbooleanfalse修复大型场景中的 Z 冲突

切勿在构造后更改 antialias——创建后无法修改。

关键属性
属性类型默认值描述
domElementHTMLCanvasElement--画布。务必添加到 DOM
shadowMap.enabledbooleanfalse要使用任何阴影,必须设为 true
shadowMap.typeShadowMapTypePCFShadowMap阴影过滤算法
toneMappingToneMappingNoToneMappingHDR 色调映射算法
toneMappingExposurenumber1色调映射曝光度
outputColorSpacestringSRGBColorSpace输出色彩空间
autoClearbooleantrue每次渲染调用前清除
sortObjectsbooleantrue自动排序绘制顺序
clippingPlanesPlane[][]全局裁剪平面
localClippingEnabledbooleanfalse启用逐材质裁剪
infoobject--渲染统计信息(调用次数、三角形数、内存)
重要警告

切勿忘记限制像素比——在 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电影胶片效果
ACESFilmicToneMappingPBR 的默认选择。 行业标准的电影感曲线
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 技能。


参考链接

官方来源

评论

支持 Markdown