图形学前沿
用生活化的比喻,让你理解光线追踪、WebGPU、PBR 等图形学前沿技术及其对 H5 游戏的影响
前置知识:2_2_h5-rendering-mastery(GPU渲染管线)、线性代数基础
阅读指南(初学者必看)
为什么你需要了解图形学前沿?
你可能觉得光线追踪、WebGPU 这些离 H5 游戏很远。但 WebGPU 已经开始在浏览器中落地,PBR 已经是 Cocos Creator 3.x 和 Three.js 的默认材质。了解这些前沿技术,能让你:
- 在选择技术方案时有更长远的眼光
- 理解引擎底层在做什么,写出更好的 Shader
- 为未来 WebGPU 普及做好准备
学完本章,你能回答:
- 光线追踪和光栅化有什么区别?为什么光线追踪更逼真?
- WebGPU 比 WebGL 强在哪?Compute Shader 能做什么?
- PBR 的核心原则是什么?为什么游戏引擎都在转向 PBR?
本文结构
第一部分:光线追踪 vs 光栅化(两种渲染路线对比)
第二部分:WebGPU(下一代浏览器图形 API)
第三部分:PBR 物理渲染(更真实的材质系统)
第四部分:VR/AR 技术(WebXR)
一、光线追踪 vs 光栅化
生活类比:光栅化就像"投影画"——把3D物体投影到2D屏幕上填色。光线追踪就像"追踪光的旅程"——从眼睛出发,沿着光的路往回走,看它从哪来、经过了什么。
光栅化(当前H5游戏用的):
- 把三角形投影到屏幕,逐像素算颜色
- 快!但阴影/反射/折射不真实
光线追踪:
- 从相机发射光线,碰到物体计算反射/折射
- 递归追踪光的路径
- 慢!但效果逼真
实时光线追踪(RTX):
- GPU RT Core 加速,每秒数十亿条光线
- WebGPU 未来可能支持
1.1 光栅化 vs 光线追踪详细对比
| 维度 | 光栅化 | 光线追踪 |
|---|---|---|
| 原理 | 把三角形投影到屏幕 | 从相机发射光线求交 |
| 速度 | 快(GPU高度优化) | 慢(每像素可能多次求交) |
| 阴影 | 需要Shadow Map(有锯齿) | 自然准确 |
| 反射 | 需要CubeMap(不真实) | 自然准确(多次弹射) |
| 折射 | 难以实现 | 自然准确 |
| 全局光照 | 需要额外技术(GI、AO) | 天然支持 |
| 硬件要求 | 任何GPU | 需要RT Core |
| H5现状 | ✅ WebGL/WebGPU | ❌ 暂不支持 |
1.2 光线追踪的过程
光线追踪过程(简化版):
1. 从相机发射一条光线到屏幕上的一个像素
2. 光线碰到最近的物体 → 计算直接光照
3. 如果物体是反射的 → 发射反射光线 → 递归
4. 如果物体是折射的 → 发射折射光线 → 递归
5. 如果光线没碰到任何物体 → 返回背景色
6. 把所有光贡献加起来 → 像素颜色
递归深度通常限制在 3~5 层(否则指数爆炸)
光线追踪的"慢"在哪?
- 每个像素要发射1条主光线
- 主光线可能弹射3~5次
- 每次弹射都要和场景所有三角形求交
- 1920×1080 = 200万像素 × 5次弹射 × 1万三角形 = 千亿次计算!
生活类比:想象你站在房间里看一面镜子。光栅化是"画"出镜子的样子,但镜子里反射的东西是贴上去的(不真实)。光线追踪是真的追踪光线从你眼睛→镜子→窗外→太阳的完整路径,所以反射是真实的。
二、WebGPU
WebGL vs WebGPU:
| | WebGL | WebGPU |
|---|---|---|
| API风格 | 状态机 | 对象化 |
| Compute Shader | ❌ | ✅ |
| 多线程 | 有限 | ✅ |
| 性能 | 基准 | 2~3倍 |
WebGPU 核心改进:
1. Compute Shader ── 通用GPU计算(粒子/物理/AI)
2. 更低开销 ── 预编译Pipeline,高效资源绑定
3. 现代架构 ── 类似Vulkan/Metal的显式API
生活类比:WebGPU就像从自动挡升级到手动挡。
WebGL(自动挡):
- 简单易用
- 但性能有上限
- 驾驶员控制有限
WebGPU(手动挡):
- 需要更多知识
- 性能潜力更大
- 驾驶员完全控制
2.1 WebGPU 初始化
class WebGPUDevice {
constructor() {
this.device = null;
this.context = null;
this.format = null;
}
async init(canvas) {
if (!navigator.gpu) throw new Error('WebGPU not supported');
let adapter = await navigator.gpu.requestAdapter();
if (!adapter) throw new Error('No GPU adapter found');
this.device = await adapter.requestDevice();
this.context = canvas.getContext('webgpu');
this.format = navigator.gpu.getPreferredCanvasFormat();
this.context.configure({ device: this.device, format: this.format, alphaMode: 'premultiplied' });
return this.device;
}
createBuffer(data, usage) {
let buffer = this.device.createBuffer({
size: data.byteLength, usage, mappedAtCreation: true
});
new Float32Array(buffer.getMappedRange()).set(data);
buffer.unmap();
return buffer;
}
createShaderModule(code) {
return this.device.createShaderModule({ code });
}
submit(commands) {
this.device.queue.submit(commands);
}
}
2.2 Compute Shader 的游戏价值
Compute Shader = 通用GPU计算
以前 GPU 只能做图形渲染:
顶点 → 光栅化 → 片元着色 → 像素
现在 GPU 可以做任意并行计算:
粒子更新、物理模拟、图像处理、AI推理……
Compute Shader 在游戏中的应用:
| 应用 | 原来怎么做 | Compute Shader怎么做 |
|------|-----------|---------------------|
| 粒子系统 | CPU逐个更新,或用Transform Feedback hack | GPU并行更新10万+粒子 |
| 物理模拟 | CPU物理引擎 | GPU并行碰撞检测 |
| 图像处理 | Canvas像素操作(慢) | GPU并行处理每个像素 |
| AI寻路 | CPU A*算法 | GPU并行多单位寻路 |
| 纹理生成 | 预生成 | 实时程序化生成 |
2.3 WebGPU vs WebGL 代码对比
// WebGL:状态机风格(全局状态)
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(0);
gl.useProgram(shaderProgram);
gl.drawArrays(gl.TRIANGLES, 0, vertexCount);
// WebGPU:对象化风格(显式资源绑定)
const pass = encoder.beginRenderPass({ colorAttachments: [...] });
pass.setPipeline(renderPipeline); // 预编译的Pipeline
pass.setBindGroup(0, bindGroup); // 预绑定的资源组
pass.setVertexBuffer(0, vertexBuffer); // 显式指定slot
pass.draw(vertexCount);
pass.end();
2.4 WebGPU 生态现状
| 维度 | 现状 | 预期 |
|---|---|---|
| 浏览器支持 | Chrome 113+、Edge 113+ | 2026年主流浏览器支持 |
| 引擎支持 | Three.js(实验)、Babylon.js | Cocos Creator 计划支持 |
| Compute Shader | ✅ 可用 | 粒子/物理将大量使用 |
| 光线追踪 | ❌ 尚未支持 | 未来 WebGPU 可能暴露 RT Core |
| 移动端 | Android Chrome 113+ | iOS 尚未支持 |
三、PBR(物理渲染)
PBR核心原则:
1. 能量守恒:反射光 ≤ 入射光
2. 微面元理论:表面由微小镜面组成
3. 菲涅尔效应:掠射角反射更强
PBR材质参数:Albedo/Metalness/Roughness/Normal/AO
和H5游戏的关系:
- Cocos Creator 3.x 默认PBR
- Three.js MeshStandardMaterial 支持PBR
- 学PBR能帮你写出更好的Shader
3.1 PBR 三大原则详解
生活类比:PBR 就像"物理正确的画法"。以前的材质是"看着像就行",PBR 是"符合物理规律"。
1. 能量守恒:
入射光 = 反射光 + 折射光 + 吸收光
粗糙表面:光分散到各方向,每个方向看到的反射都弱
光滑表面:光集中在反射方向,反射方向很强
2. 微面元理论:
放大看,任何表面都不是光滑的,而是由无数微小的"镜面"组成
粗糙度(Roughness)= 微面元朝向的混乱程度
- Roughness = 0:所有微面元朝向一致 → 镜面反射
- Roughness = 1:微面元朝向随机 → 漫反射
3. 菲涅尔效应:
水面从正上方看是透明的(透射为主)
从远处看水面是反光的(反射为主)
这就是菲涅尔效应:掠射角反射更强
3.2 PBR 材质参数
| 参数 | 含义 | 取值范围 | 生活类比 |
|---|---|---|---|
| Albedo | 基础颜色 | RGB | 物体的"本色" |
| Metalness | 金属度 | 0~1 | 0=非金属,1=金属 |
| Roughness | 粗糙度 | 0~1 | 0=镜面,1=毛玻璃 |
| Normal | 法线贴图 | RGB | 表面凹凸细节 |
| AO | 环境遮蔽 | 0~1 | 缝隙和角落的暗影 |
3.3 金属 vs 非金属
| 特性 | 非金属(Dielectric) | 金属(Metal) |
|---|---|---|
| 反射率 | 2%~5%(低) | 50%~100%(高) |
| 反射颜色 | 无色(白色) | 有色(金=黄色,铜=红棕色) |
| 折射光 | 被吸收后重新发射=漫反射 | 被吸收=没有漫反射 |
| Albedo | 表面颜色 | 反射颜色 |
| Metalness | 0 | 1 |
常见材质的参数:
| 材质 | Metalness | Roughness | Albedo |
|------|-----------|-----------|--------|
| 塑料 | 0.0 | 0.3~0.5 | 彩色 |
| 木材 | 0.0 | 0.7~0.9 | 棕色 |
| 大理石 | 0.0 | 0.2~0.4 | 白色 |
| 黄金 | 1.0 | 0.1~0.3 | RGB(1.0, 0.76, 0.34) |
| 银色 | 1.0 | 0.1~0.3 | RGB(0.97, 0.97, 0.97) |
| 铜色 | 1.0 | 0.2~0.4 | RGB(0.95, 0.64, 0.54) |
| 生锈铁 | 0.5~0.8 | 0.6~0.9 | 暗红棕色 |
四、VR/AR 技术(WebXR)
4.1 WebXR 基础
class WebXRManager {
constructor() {
this.session = null;
this.referenceSpace = null;
this.renderer = null;
this.scene = null;
this.camera = null;
}
async isSupported() {
return navigator.xr && navigator.xr.isSessionSupported('immersive-vr');
}
async startSession() {
if (!await this.isSupported()) throw new Error('WebXR not supported');
this.session = await navigator.xr.requestSession('immersive-vr', {
optionalFeatures: ['local-floor', 'bounded-floor']
});
this.referenceSpace = await this.session.requestReferenceSpace('local-floor');
this.session.addEventListener('end', () => { this.session = null; });
return this.session;
}
async startARSession() {
if (!navigator.xr || !navigator.xr.isSessionSupported('immersive-ar')) {
throw new Error('AR not supported');
}
this.session = await navigator.xr.requestSession('immersive-ar', {
optionalFeatures: ['local-floor', 'dom-overlay'],
domOverlay: { root: document.body }
});
this.referenceSpace = await this.session.requestReferenceSpace('local');
return this.session;
}
render(frame) {
let pose = frame.getViewerPose(this.referenceSpace);
if (pose) {
for (let view of pose.views) {
let viewport = this.session.renderState.baseLayer.getViewport(view);
this.renderer.setViewport(viewport.x, viewport.y, viewport.width, viewport.height);
this.camera.projectionMatrix.fromArray(view.projectionMatrix);
this.camera.matrixWorld.fromArray(view.transform.matrix);
this.renderer.render(this.scene, this.camera);
}
}
}
endSession() {
if (this.session) { this.session.end(); this.session = null; }
}
}
4.2 VR 控制器
class VRController {
constructor(index) {
this.index = index;
this.position = { x: 0, y: 0, z: 0 };
this.rotation = { x: 0, y: 0, z: 0, w: 1 };
this.buttons = [];
this.axes = [];
}
update(inputSource, frame, referenceSpace) {
if (!inputSource.gripSpace) return;
let pose = frame.getPose(inputSource.gripSpace, referenceSpace);
if (pose) {
this.position = {
x: pose.transform.position.x,
y: pose.transform.position.y,
z: pose.transform.position.z
};
this.rotation = {
x: pose.transform.orientation.x,
y: pose.transform.orientation.y,
z: pose.transform.orientation.z,
w: pose.transform.orientation.w
};
}
if (inputSource.gamepad) {
this.buttons = inputSource.gamepad.buttons;
this.axes = inputSource.gamepad.axes;
}
}
}
实践:
- 用 Three.js 实现简易光线追踪
- 学习 WebGPU Compute Shader
- 实现 PBR 材质调节工具
自问自答
Q:H5 游戏需要光线追踪吗? A:目前不需要。浏览器还不支持实时光线追踪,而且移动端 GPU 算力不够。但了解原理有助于理解阴影、反射等技术的实现原理。未来 WebGPU 可能支持 RT Core。
Q:WebGPU 什么时候能用在生产环境? A:桌面端 Chrome 113+ 已经可用,但移动端 iOS 尚未支持。如果你的游戏只面向桌面浏览器,现在就可以尝试。如果面向移动端,建议再等1~2年。
Q:PBR 和传统材质有什么区别? A:传统材质(Phong/Blinn-Phong)是"经验公式",参数调起来像玄学。PBR 是"物理公式",参数有明确的物理含义。PBR 材质在不同光照下表现更一致,也更容易在团队间共享。
Q:Roughness 和 Smoothness 是同一个东西吗? A:是的,Roughness = 1 - Smoothness。不同引擎用的术语不同:Unreal 用 Roughness,Unity 以前用 Smoothness 现在也支持 Roughness,Three.js 用 Roughness。
Q:为什么 PBR 要区分金属和非金属? A:因为它们对光的物理行为完全不同。非金属的反射是无色的、弱的,漫反射是彩色的;金属的反射是有色的、强的,几乎没有漫反射。用 Metalness 统一插值,比分别设置两个材质模型更简单。
Q:VR/AR 开发难吗? A:WebXR 降低了门槛,但性能优化是挑战。需要3D基础,且要考虑不同设备的适配。H5 游戏中 VR/AR 目前还处于探索阶段,了解即可。
实践任务
- 任务1:用 Three.js 实现简易光线追踪(Ray Marching),渲染球体和阴影
- 任务2:学习 WebGPU Compute Shader,实现 GPU 粒子系统(10000+ 粒子)
- 任务3:在 Three.js 中用 MeshStandardMaterial 创建不同 PBR 材质(塑料、金属、木材),调节参数观察变化
- 任务4:对比 WebGL 和 WebGPU 的 API 风格差异,写一份简要对比笔记
- 任务5:用 PBR 参数还原一个真实物体(如你桌上的水杯),对比截图和渲染结果
- 任务6:体验 WebXR(如有 VR 设备),了解 VR 游戏的基本交互方式
与其他章节的关联
| 本章内容 | 关联章节 | 关联点 |
|---|---|---|
| WebGPU Compute Shader | 第01章 WebAssembly深度 | Wasm 处理逻辑计算,Compute Shader 处理并行计算 |
| 光线追踪 | 第02章 云游戏与边缘计算 | 云端渲染可用光线追踪,串流传给客户端 |
| PBR 材质 | 2_2_h5-rendering-mastery | 渲染管线中的材质系统 |
| GPU 并行计算 | 第03章 AI与游戏 | Compute Shader 可加速 AI 推理 |
| WebGPU | 第05章 微信小游戏开发 | 小游戏引擎未来会支持 WebGPU |
上一章:03-AI与游戏 | 下一章:05-微信小游戏开发