WebGPU 体积树冠光线步进实验

Magical Canopy

原作者及原始链接


WebGPU Currency

项目概述

Magical Canopy 是一个完全基于 Three.js TSL(Three.js Shading Language) 在 WebGPU 环境下实现体积树冠光线步进(volumetric tree canopy raymarching)的实验性 Web3D 作品。层层叠叠的树叶在风中轻轻摇曳,配合柔和阴影(soft shadows)与雾气(fog)效果,营造出梦幻的森林氛围。整个场景会响应鼠标指针的移动,产生动态变化的辉光(glow),使观者仿佛置身于魔法树冠之下。


WebGPU Ribbon Carousel

核心技术解析

该实验的核心亮点在于完全摒弃传统几何体建模,转而使用光线步进(raymarching) 技术在片元着色器(或计算着色器)中逐像素地计算体积密度,从而渲染出具有空间层次感的树冠。所有着色逻辑均通过 Three.js TSL 节点化语言编写,而非直接手写 GLSL/WGSL,这大幅提高了代码的可读性与可维护性,同时能够无缝切换到不同的图形后端(WebGPU 或 WebGL2)。


WebGPU Tile Field

3 个核心优化要点

1. 利用 TSL 节点化着色器构建,提升开发效率与跨后端兼容性

优化点:使用 Three.js TSL 替代手写 GLSL/WGSL,将复杂的光线步进逻辑抽象为可复用的节点图。这不仅避免了手动管理不同着色语言(WGSL 与 GLSL 语法差异)的负担,还允许在 WebGPU 与 WebGL 之间灵活切换渲染后端,确保更广泛的设备覆盖。

2. 以 raymarching 体积渲染替代几何体,大幅降低顶点压力

优化点:传统树冠若使用大量叶片网格(mesh)将带来高昂的顶点着色与光栅化开销。本实验通过体积光线步进直接在屏幕空间累加密度场,仅需一个全屏四边形(或少量代理几何体),就可以生成具有丰富内部结构的树冠效果。这样把计算压力从顶点处理转移到片元着色,更适合现代 GPU 的并行架构,同时有效控制 Draw Call 数量。

3. 软阴影与雾效的深度融合,以低成本增强视觉层次与交互反馈

优化点:软阴影并非通过多次采样高成本阴影贴图实现,而是在光线步进过程中基于体积密度累计遮挡信息,天然产生柔和过渡。雾气与辉光则作为后处理或步进终结条件的一部分,与指针交互参数联动,仅需在每一帧更新少量 uniform 变量即可实现场景对用户的动态响应,无需额外的几何体或纹理开销。


WebGPU Blob

GLSL / WebGL 专业术语检查

以下是本项目中涉及的关键术语及其标准中文译名:

英文术语中文译名说明
WebGPU网页图形处理单元新一代 Web 图形/计算 API,由浏览器暴露现代 GPU 能力
Three.js TSLThree.js 着色语言Three.js 提供的节点化着色器编写方式,可编译为 WGSL 或 GLSL
Raymarching光线步进 / 射线推进一种体绘制技术,逐步推进射线并采样距离场或密度场
Volumetric体积的 / 容积的描述具有内部空间分布效果的渲染方式
Soft shadows软阴影边缘柔和的阴影,通常由区域光源或多次采样产生
Fog雾效模拟大气散射,使远处物体逐渐融入背景色
Glow辉光 / 泛光高亮区域向周围扩散的视觉效果,常作为后处理
Pointer指针 / 鼠标指针用户输入设备,用于驱动交互式参数变化

注意:本项目基于 WebGPU 与 WGSL(WebGPU Shading Language),并非直接使用 GLSL。但 TSL 提供了抽象层,使得同样的着色逻辑可以在 WebGL(GLSL)后端运行。因此在术语理解上,光线步进、软阴影等概念与 GLSL 环境完全通用。


✦ Museo del Cosmos — El arte del universo

核心代码示意(基于 TSL 的重建)

由于原始展示页面未附带完整着色器源码,以下是根据项目描述重建的 Three.js TSL 光线步进核心逻辑示意,用于说明其结构:

// 示意:TSL 体积树冠光线步进核心(非原始代码)
import {
  uniform,
  vec3,
  vec4,
  mix,
  step,
  smoothstep,
  sin,
  time,
  positionWorld,
  cameraPosition,
  normalize,
  length,
  float,
  Fn,
} from "three/tsl";

export const canopyMaterial = new THREE.MeshBasicNodeMaterial();

const canopyDensity = Fn(([p]) => {
  // 多层叶片密度函数:使用噪声与正弦波模拟风动
  const wind = sin(p.y * 3.0 + time.mul(0.5)).mul(0.1);
  const layers = sin(p.y * 5.0 + p.x * 2.0 + wind)
    .add(1.0)
    .mul(0.5);
  const density = layers.mul(smoothstep(0.2, 0.0, length(p.xz)));
  return density;
});

const rayMarch = Fn(() => {
  const ro = cameraPosition;
  const rd = normalize(positionWorld.sub(ro));

  let t = float(0.0);
  let accumDensity = float(0.0);
  let light = float(0.0);

  // 步进循环(示意简化)
  for (let i = 0; i < 64; i++) {
    const pos = ro.add(rd.mul(t));
    const dens = canopyDensity(pos);
    accumDensity = accumDensity.add(dens);
    // 软阴影:沿光源方向二次采样密度
    // light = light.add( ... );
    t = t.add(0.05);
  }

  // 雾效与辉光混合
  const baseColor = vec3(0.1, 0.5, 0.2);
  const fogColor = vec3(0.7, 0.8, 0.9);
  const finalColor = mix(baseColor, fogColor, accumDensity.oneMinus());
  return vec4(finalColor, 1.0);
});

canopyMaterial.colorNode = rayMarch();

以上代码仅为技术结构示意,并非原始实验源码,但体现了 TSL 中体积步进、密度累积、软阴影与雾效融合的典型写法。


结语

Magical Canopy 是 WebGPU + Three.js TSL 在体积渲染方向上的优秀示范。它通过光线步进技术摆脱了传统树冠建模的几何负担,并借助 TSL 的高层抽象实现了跨 GPU 后端的优雅着色器开发流程。对于希望探索现代 Web3D 体积渲染与着色器优化的开发者而言,该项目提供了极具参考价值的实践思路。


版权声明:本文为技术深度解读,原始项目内容、截图与录屏版权归原作者 aengel 所有。