| name | webgl-3d-object |
| description | 创建一个真实的 3D WebGL 对象,具备几何网格深度、基于物理的材质、方向光与环境光、透视相机、微妙旋转与漂浮运动。当页面需要一个多面 3D 主视觉对象或类产品视觉、且要真实光照而非 CSS transform 技巧时使用。 |
WebGL 3D 对象
何时使用
- 主视觉、特性区块或产品时刻需要一个有力的 3D 对象。
- 视觉应展现真实几何、光照、高光与边缘。
- 一个多面网格应在 web 布局中微妙漂浮或旋转。
- CSS transform、SVG 错觉或扁平渐变已不够用。
准则
- 使用真实 3D 几何:
IcosahedronGeometry、DodecahedronGeometry、BoxGeometry、自定义 BufferGeometry 或 glTF 网格。
- 使用透视相机,让对象有深度与尺度感。
- 使用 PBR 材质:
MeshStandardMaterial 或 MeshPhysicalMaterial。
- 调节
metalness、roughness 与 emissive 以匹配品牌情绪。
- 至少用一盏方向光加环境光或半球补光来照亮对象。
- 仅动画化 transform:微妙旋转、上下浮动或视差。
- 处理 resize,并在拆卸时 dispose 几何/材质/渲染器。
HTML 与 CSS
<div class="webgl-object-shell">
<canvas class="webgl-object-canvas" data-webgl-3d-object></canvas>
</div>
.webgl-object-shell {
position: relative;
width: min(100%, 720px);
aspect-ratio: 1 / 1;
}
.webgl-object-canvas {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
display: block;
}
Three.js 对象食谱
import * as THREE from "three";
function initWebGL3DObject(canvas, options = {}) {
if (!canvas) return () => {};
const renderer = new THREE.WebGLRenderer({
canvas,
antialias: true,
alpha: true,
});
renderer.setClearColor(0x000000, 0);
renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, options.maxDpr || 1.75));
renderer.outputColorSpace = THREE.SRGBColorSpace;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = options.exposure || 1.05;
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
const scene = new THREE.Scene();
camera = .(, , , );
camera..(, , );
geometry = .(options. || , options. || );
material = .({
: options. || ,
: options. ?? ,
: options. ?? ,
: options. || ,
: options. ?? ,
: ,
});
object = .(geometry, material);
object. = ;
object. = ;
scene.(object);
ambient = .(, );
scene.(ambient);
key = .(, );
key..(, , );
key. = ;
key...(, );
scene.(key);
rim = .(options. || , );
rim..(-, , -);
scene.(rim);
shadowPlane = .(
.(, ),
.({ : })
);
shadowPlane..(, -, );
shadowPlane.. = -. / ;
shadowPlane. = ;
scene.(shadowPlane);
reduceMotion = .().;
rafId = ;
() {
width = .(, canvas.);
height = .(, canvas.);
renderer.(.(. || , options. || ));
renderer.(width, height, );
camera. = width / height;
camera.();
}
() {
t = time * ;
object.. = - + .(t * ) * ;
object.. = t * ;
object.. = .(t * ) * ;
object.. = reduceMotion ? : .(t * ) * ;
renderer.(scene, camera);
(!reduceMotion) rafId = (render);
}
() {
(rafId);
();
();
}
();
();
.(, handleResize);
{
(rafId);
.(, handleResize);
geometry.();
material.();
shadowPlane..();
shadowPlane..();
renderer.();
};
}
cleanupObject = (
.(),
{
: ,
: ,
: ,
: ,
: ,
}
);
材质默认值
- 高端金属:
metalness: 0.45-0.7、roughness: 0.25-0.45。
- 柔和陶瓷:
metalness: 0.0-0.15、roughness: 0.38-0.62。
- 辉光染色科技对象:低
emissive 搭配 emissiveIntensity: 0.12-0.35。
- 多面对象:设
flatShading: true;光滑产品对象:设为 false。
光照默认值
- 主光:方向光,高前侧角度,最强光源。
- 环境补光:低强度,让阴影保持可见。
- 边缘光:品牌染色或冷色,从背后照射以显现边缘。
- 阴影:仅在对象需要落地深度时启用;贴图尺寸保持适中。
动效默认值
- 旋转:缓慢、连续,且从属于页面内容。
- 漂浮:Y 轴
0.04 到 0.12 个单位。
- 减弱动效:渲染一个静止帧,或只允许直接交互。
- 除非对象是主要交互,否则避免相机运动。
避免
- 用 CSS 3D transform 假装成 WebGL。
- 在要求真实光照与深度时使用 unlit 材质。
- 用带渐变的扁平平面替代真实几何。
- 用强烈 bloom 或粒子掩盖形体。
- 在移动端用高 DPR、巨大阴影贴图或过多光照。
- 让对象与前景文案或 CTA 争夺注意力。
快速检查
- 对象有可见的形体、边缘、高光与阴影。
- 材质使用
metalness、roughness 与可选的 emissive。
- 方向光与环境光同时存在。
- 相机是透视,而非意外用成正交。
- resize 不会拉伸对象。
- 几何、材质、事件监听器、RAF 与渲染器都已清理。