图形学前沿

用生活化的比喻,让你理解光线追踪、WebGPU、PBR 等图形学前沿技术及其对 H5 游戏的影响

前置知识:2_2_h5-rendering-mastery(GPU渲染管线)、线性代数基础


阅读指南(初学者必看)

为什么你需要了解图形学前沿?

你可能觉得光线追踪、WebGPU 这些离 H5 游戏很远。但 WebGPU 已经开始在浏览器中落地,PBR 已经是 Cocos Creator 3.x 和 Three.js 的默认材质。了解这些前沿技术,能让你:

  1. 在选择技术方案时有更长远的眼光
  2. 理解引擎底层在做什么,写出更好的 Shader
  3. 为未来 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-微信小游戏开发