GLSL 特性
PlayCanvas 使用的 GLSL 着色器必须满足一定要求,使引擎能够正确集成着色器,提供属性、uniform 和 varying 等资源。这些规则也让引擎在为 WebGPU 转译到 WGSL 时,自动处理略有不同的要求。
以下介绍为 PlayCanvas 编写 GLSL 的关键事项。
源码中不应包含 #version。PlayCanvas 根据目标是 WebGL2 还是 WebGPU 自动添加适当版本指令。
顶点属性
属性定义逐顶点输入,只能用于顶点着色器,必须使用以下语法声明:
attribute vec2 aUv0;
属性名必须与创建 ShaderMaterial 时 attributes 属性中的名称匹配。
不支持 GLSL 3.3+ 引入的 in 关键字。
Uniform
Uniform 将引擎资源传入着色器,数值和纹理均按标准方式声明:
uniform vec3 view_position;
引擎在前向渲染中提供内置 uniform 的值。自定义 uniform 需由应用代码设置,例如 material.setParameter()。
目前 uniform 系统只支持简单类型,包括 float、int、uint、向量和矩阵(例如 vec4、mat4)。暂不支持结构体,因此所有值都必须声明为独立的基本类型变量。
精度限定符
设备支持时,PlayCanvas 自动为以下类型设置 highp 精度:
floatint(也适用于uint)usampler2D(无符号整数纹理)isampler2D(有符号整数纹理)sampler2DShadowsamplerCubeShadowsampler2DArray
以下采样器类型不设置默认精度:
sampler2Dsampler3DsamplerCube
如果这些类型需要 highp,必须手动指定。采样 RGBA32F 等需要完整 32 位精度的浮点纹理时尤其重要,否则值可能丢失精度。默认不为标准采样器设置 highp,是因为可能影响移动 GPU 性能。
为某类型的全部采样器设置精度:
precision highp sampler2D;
uniform sampler2D hdrTextureA;
uniform sampler2D hdrTextureB;
为单个 uniform 设置精度:
uniform highp sampler2D hdrTexture;
uniform sampler2D ldrTexture;
Varying
Varying 将值从顶点着色器传到片元着色器,必须使用标准 GLSL 语法声明:
varying vec2 uv0;
不支持 GLSL 3.3+ 引入的 in/out 语法。
双源片元输出
材质混合状态使用第二源因子时,将主颜色写入 gl_FragColor,第二混合值写入 pcFragColorSecondary。在 WebGL 2 中,引擎自动启用 GL_EXT_blend_func_extended 并声明两个输出。
能力检测、跨平台代码和 BlendState 配置,参见双源混合。