经纬志
首页 / luma.gl / API 文档

ShaderModule

先看结论

ShaderModule 在 v9 里是一个类型,不是可以用 new 创建的类。 模块就是普通对象,由 shadertools 在组装阶段把片段拼进着色器; 编译成 GPU 对象的是 Shader,链接成可绘制对象的是 RenderPipeline。

最后验证 2026-11-03 · luma.gl 9.4 · 更新 2026-10-28 · 引用本文
type ShaderModule = { name, vs?, fs?, uniformTypes?, inject? }

luma.ShaderModule 在运行期是 undefined, 按 v8 的写法 new ShaderModule(...) 会直接抛错。 下面的字段来自 @luma.gl/shadertools 的类型声明。

字段

字段说明
name模块名,用于依赖解析与调试输出
vs / fsGLSL 顶点或片元片段,拼在对应阶段的最前面
sourceWGSL 片段
uniformTypesuniform 字段的类型表,顺序必须与着色器声明一致
defaultUniformsuniform 默认值
getUniforms由 props 生成 uniform 与绑定的函数
defines模块贡献的预处理宏
inject注入点与注入代码,键形如 fs:#main-end
dependencies依赖的其它模块,组装时自动带上
bindingLayout模块声明的绑定组归属
firstBindingSlotWGSL 自动绑定的起始槽位

写一个模块

片段会拼进主着色器,注入代码放在钩子处。下面的模块在片元阶段加入一个函数, 并在 main 末尾改写输出颜色,因此主要求声明 out vec4 fragColor 与 in vec2 vUV。

const waveModule = {
  name: 'wave',
  fs: `
float wave(float x, float freq) {
  return sin(x * freq) * 0.5 + 0.5;
}
`,
  inject: {
    'fs:#main-end': 'fragColor.rgb *= wave(vUV.x, 6.0);'
  }
};

交给 Model

const model = new Model(device, {
  vs: vsSource,
  fs: fsSource,
  modules: [waveModule],
  attributes: { positions: positions },
  bufferLayout: [
    { name: 'positions', stepMode: 'vertex', format: 'float32x3' }
  ],
  vertexCount: 3,
  topology: 'triangle-list'
});

Model 内部调用着色器组装器,把 vs、fs、 模块片段与宏定义合并成最终源码,再分别交给 device.createShader。 模块的注入元数据由 initializeShaderModules 补齐; 手工组装着色器时先调用它,可以避免注入点没有被识别的情况。

模块编译后的形态

组装结果的每个阶段各是一个 Shader 对象,这就是 v8 里 「一个 Program 带一对源码」在 v9 的对应写法:源码被拆成阶段、 逐阶段编译,最后交给管线链接。

const vs = device.createShader({ stage: 'vertex', source: assembledVS });
const fs = device.createShader({ stage: 'fragment', source: assembledFS });

const pipeline = device.createRenderPipeline({
  vs: vs,
  fs: fs,
  topology: 'triangle-list',
  bufferLayout: [
    { name: 'positions', stepMode: 'vertex', format: 'float32x3' }
  ]
});
成员说明
stagevertex、fragment 或 compute
source编译时的源码
compilationStatuspending、success、error
asyncCompilationStatus编译状态的 Promise,供异步后端等待
getCompilationInfo()异步取编译器日志
getCompilationInfoSync()同步取编译器日志,仅 WebGL
getTranslatedSource()取后端翻译后的源码,便于排查驱动改写

相关运行时 API

API作用
device.createShader(props)编译单个阶段的着色器
initializeShaderModules(modules)初始化模块的注入与校验元数据
getShaderModuleUniforms(module, props)由 props 生成 uniform 对象
ShaderAssembler.assembleGLSLShaderPair(props)手动组装一对 GLSL 着色器,返回源码与 uniform 取值函数
ShaderAssembler.assembleWGSLShader(props)组装统一的 WGSL 着色器,返回源码与绑定表

模块片段必须能独立编译。拼接后的源码是一个整体, 变量名重复、缺少 precision 声明、注入点不存在,都会让最终链接失败。 先用最小模块验证注入点,再逐步加内容。

引用本文

经纬志(2026)。《ShaderModule》。https://www.jingweizhi.com/lumagl/api/shader-module.html(访问日期 2026-11-03)。