着色器变体 - Variants
对于开发者而言,同样一段着色器代码可能会面临多种使用环境,可能需要根据环境加载不同的变量或代码模块。我们内置了以下两个自定义 API 帮助开发者生成不同的着色器变体:
- 设定不同的宏定义
setDefine()
; - 设定不同的常量
setConst()
;
比如,要创建两个材质球 shader
,一个接受光,一个不接受光,除此之外所有代码相同,我们就可以通过定义 USE_LIGHT
宏变量来灵活的加载不同的 shader
代码:
具有 LIGHT
数据的模型,其材质球需要设定宏 setDefine("USE_LIGHT", true)
;
ts
// 同样的wgsl代码
ShaderLib.register('vsCode', '....')
ShaderLib.register('fsCode', '....')
class shader1 extends Material{
constructor() {
super();
// 创建RenderShaderPass实例
let renderShader = new RenderShaderPass('vsCode','fsCode');
// 创建材质Shader实例
let shader = new Shader();
// 添加RenderShaderPass实例
shader.addRenderPass(renderShader);
// 通过定义 USE_LIGHT 加载灯光模块
shader.setDefine("USE_LIGHT", true);
// 将材质Shader实例关联到当前材质对象上
this.shader = shader;
}
}
class shader2 extends Material{
constructor() {
super();
// 创建RenderShaderPass实例
let renderShader = new RenderShaderPass('vsCode','fsCode');
// 创建材质Shader实例
let shader = new Shader();
// 添加RenderShaderPass实例
shader.addRenderPass(renderShader);
//通过定义 USE_LIGHT 加载其他模块
shader.setDefine("USE_LIGHT", false);
// 将材质Shader实例关联到当前材质对象上
this.shader = shader;
}
}
同样一段着色器代码,会因为宏定义不同而生成不同的变体。从而可以生成具有不同功能的RenderShader
被用于不同的材质球中。
wgsl
// 加载全局 shader
#include `GlobalUniform`
// 根据宏定义 USE_LIGHT 选择加载 不同的 shader
#if USE_LIGHT
// ... 处理光的代码
#else
// ... 不处理光的代码
#endif
// 其他代码
...