This translation is community contributed and may not be up to date. We only maintain the English version of the documentation. Read this manual in English
基于物理渲染(Physically Based Rendering,PBR)是一种着色方法,它根据真实世界的物理原则模拟光线与表面的交互方式。它可以在不同环境中产生一致、逼真的光照效果,并让资源在各种光照条件下都能正确显示。
Defold 的 PBR 实现遵循 glTF 2.0 材质规范以及相关的 Khronos 扩展。当你把 glTF 资源导入 Defold 时,材质属性会被自动解析并保存为结构化材质数据,运行时可在着色器中访问这些数据。
PBR 材质可以包含金属反射、表面粗糙度、透射、清漆层、次表面散射、虹彩等效果。
Defold 目前会把 PBR 材质数据暴露给着色器,但还没有提供内置的 PBR 光照模型。你可以在自己的光照和反射着色器中使用这些数据来实现基于物理的渲染。默认 PBR 光照模型会在后续阶段加入 Defold。
Defold 目前不会自动分配 glTF 文件中的嵌入纹理。只有材质参数会暴露给着色器。你仍然可以手动把纹理分配给模型组件,并在着色器中对它们采样。
材质属性从分配给模型组件的 glTF 2.0 源文件中解析而来。并非所有属性都是标准属性。有些属性来自可选的 glTF 扩展,而这些扩展是否存在取决于导出 glTF 文件时使用的工具。下面会在属性名称后的括号中标出相关扩展。
这些属性中有一部分只是提示材质应如何渲染。属性数据(alpha cutoff、alpha mode、double sided 和 unlit)可以在着色器中访问,但不会影响 Defold 中材质的实际渲染方式。
PBR 材质数据会根据类型和命名约定暴露给着色器。PBR 材质系统通过名为 PbrMaterial 的结构化 uniform 块,把所有已解析的材质参数提供给着色器。每个受支持的 glTF 扩展都对应这个块中的一个结构体,并可使用 #define 标志进行条件编译。
uniform PbrMaterial
{
// Material properties
};
材质的各项功能在着色器中以固定结构体表示。由于 Defold 内部用 vec4 设置常量,数据会尽可能打包到 vec4 中。对于经过打包的数据,下面每个功能的着色器片段都会在注释中标出:
struct PbrMetallicRoughness
{
vec4 baseColorFactor;
// R: metallic (Default=1.0), G: roughness (Default=1.0)
vec4 metallicAndRoughnessFactor;
// R: use baseColorTexture, G: use metallicRoughnessTexture
vec4 metallicRoughnessTextures;
};
struct PbrSpecularGlossiness
{
vec4 diffuseFactor;
// RGB: specular (Default=1.0), A: glossiness (Default=1.0)
vec4 specularAndSpecularGlossinessFactor;
// R: use diffuseTexture, G: use specularGlossinessTexture
vec4 specularGlossinessTextures;
};
struct PbrClearCoat
{
// R: clearCoat (Default=0.0), G: clearCoatRoughness (Default=0.0)
vec4 clearCoatAndClearCoatRoughnessFactor;
// R: use clearCoatTexture, G: use clearCoatRoughnessTexture, B: use clearCoatNormalTexture
vec4 clearCoatTextures;
};
struct PbrTransmission
{
// R: transmission (Default=0.0)
vec4 transmissionFactor;
// R: use transmissionTexture
vec4 transmissionTextures;
};
struct PbrIor
{
// R: ior (Default=0.0)
vec4 ior;
};
struct PbrSpecular
{
// RGB: specularColor, A: specularFactor (Default=1.0);
vec4 specularColorAndSpecularFactor;
// R: use specularTexture, G: use specularColorTexture
vec4 specularTextures;
};
struct PbrVolume
{
// R: thicknessFactor (Default=0.0), RGB: attenuationColor
vec4 thicknessFactorAndAttenuationColor;
// R: attentuationDistance (Default=-1.0)
vec4 attenuationDistance;
// R: use thicknessTexture
vec4 volumeTextures;
};
struct PbrSheen
{
// RGB: sheenColor, A: sheenRoughnessFactor (Default=0.0)
vec4 sheenColorAndRoughnessFactor;
// R: use sheenColorTexture, G: use sheenRoughnessTexture
vec4 sheenTextures;
};
struct PbrEmissiveStrength
{
// R: emissiveStrength (Default=1.0)
vec4 emissiveStrength;
};
struct PbrIridescence
{
// R: iridescenceFactor (Default=0.0), G: iridescenceIor (Default=1.3), B: iridescenceThicknessMin (Default=100.0), A: iridescenceThicknessMax (Default=400.0)
vec4 iridescenceFactorAndIorAndThicknessMinMax;
// R: use iridescenceTexture, G: use iridescenceThicknessTexture
vec4 iridescenceTextures;
};
通用属性设置在材质 uniform 本身上(同样要注意数据会打包到 vec4 中)。
// Common textures
uniform sampler2D PbrMaterial_normalTexture;
uniform sampler2D PbrMaterial_occlusionTexture;
uniform sampler2D PbrMaterial_emissiveTexture;
uniform PbrMaterial
{
// Common properties:
// R: alphaCutoff (Default=0.5), G: doubleSided (Default=false), B: unlit (Default=false)
vec4 pbrAlphaCutoffAndDoubleSidedAndIsUnlit;
// R: use normalTexture, G: use occlusionTexture, B: use emissiveTexture
vec4 pbrCommonTextures;
// Other properties...
};
下面是一个包含所有功能的示例着色器,并给出了一套建议的纹理绑定命名方案(这些绑定仍然需要手动处理)。注意,你可以像下面示例中那样,在 PbrMaterial 的各个成员周围使用 define 来关闭功能:
// Feature flags, comment or remove these to slim down the shader.
#define PBR_METALLIC_ROUGHNESS
#define PBR_SPECULAR_GLOSSINESS
#define PBR_CLEARCOAT
#define PBR_TRANSMISSION
#define PBR_IOR
#define PBR_SPECULAR
#define PBR_VOLUME
#define PBR_SHEEN
#define PBR_EMISSIVE_STRENGTH
#define PBR_IRIDESCENCE
// Common
uniform sampler2D PbrMaterial_normalTexture;
uniform sampler2D PbrMaterial_occlusionTexture;
uniform sampler2D PbrMaterial_emissiveTexture;
// PbrMetallicRoughness
uniform sampler2D PbrMetallicRoughness_baseColorTexture;
uniform sampler2D PbrMetallicRoughness_metallicRoughnessTexture;
struct PbrMetallicRoughness
{
vec4 baseColorFactor;
// R: metallic (Default=1.0), G: roughness (Default=1.0)
vec4 metallicAndRoughnessFactor;
// R: use baseColorTexture, G: use metallicRoughnessTexture
vec4 metallicRoughnessTextures;
};
// PbrSpecularGlossiness
uniform sampler2D PbrSpecularGlossiness_diffuseTexture;
uniform sampler2D PbrSpecularGlossiness_specularGlossinessTexture;
struct PbrSpecularGlossiness
{
vec4 diffuseFactor;
// RGB: specular (Default=1.0), A: glossiness (Default=1.0)
vec4 specularAndSpecularGlossinessFactor;
// R: use diffuseTexture, G: use specularGlossinessTexture
vec4 specularGlossinessTextures;
};
// PbrClearCoat
uniform sampler2D PbrClearCoat_clearcoatTexture;
uniform sampler2D PbrClearCoat_clearcoatRoughnessTexture;
uniform sampler2D PbrClearCoat_clearcoatNormalTexture;
struct PbrClearCoat
{
// R: clearCoat (Default=0.0), G: clearCoatRoughness (Default=0.0)
vec4 clearCoatAndClearCoatRoughnessFactor;
// R: use clearCoatTexture, G: use clearCoatRoughnessTexture, B: use clearCoatNormalTexture
vec4 clearCoatTextures;
};
// PbrTransmission
uniform sampler2D PbrTransmission_transmissionTexture;
struct PbrTransmission
{
// R: transmission (Default=0.0)
vec4 transmissionFactor;
// R: use transmissionTexture
vec4 transmissionTextures;
};
struct PbrIor
{
// R: ior (Default=0.0)
vec4 ior;
};
// PbrSpecular
uniform sampler2D PbrSpecular_specularTexture;
uniform sampler2D PbrSpecular_specularColorTexture;
struct PbrSpecular
{
// RGB: specularColor, A: specularFactor (Default=1.0);
vec4 specularColorAndSpecularFactor;
// R: use specularTexture, G: use specularColorTexture
vec4 specularTextures;
};
// PbrVolume
uniform sampler2D PbrVolume_thicknessTexture;
struct PbrVolume
{
// R: thicknessFactor (Default=0.0), RGB: attenuationColor
vec4 thicknessFactorAndAttenuationColor;
// R: attentuationDistance (Default=-1.0)
vec4 attenuationDistance;
// R: use thicknessTexture
vec4 volumeTextures;
};
// PbrSheen
uniform sampler2D PbrSheen_sheenColorTexture;
uniform sampler2D PbrSheen_sheenRoughnessTexture;
struct PbrSheen
{
// RGB: sheenColor, A: sheenRoughnessFactor (Default=0.0)
vec4 sheenColorAndRoughnessFactor;
// R: use sheenColorTexture, G: use sheenRoughnessTexture
vec4 sheenTextures;
};
struct PbrEmissiveStrength
{
// R: emissiveStrength (Default=1.0)
vec4 emissiveStrength;
};
// PbrIridescence
uniform sampler2D PbrEmissive_iridescenceTexture;
uniform sampler2D PbrEmissive_iridescenceThicknessTexture;
struct PbrIridescence
{
// R: iridescenceFactor (Default=0.0), G: iridescenceIor (Default=1.3), B: iridescenceThicknessMin (Default=100.0), A: iridescenceThicknessMax (Default=400.0)
vec4 iridescenceFactorAndIorAndThicknessMinMax;
// R: use iridescenceTexture, G: use iridescenceThicknessTexture
vec4 iridescenceTextures;
};
uniform PbrMaterial
{
// Common properties
// R: alphaCutoff (Default=0.5), G: doubleSided (Default=false), B: unlit (Default=false)
vec4 pbrAlphaCutoffAndDoubleSidedAndIsUnlit;
// R: use normalTexture, G: use occlusionTexture, B: use emissiveTexture
vec4 pbrCommonTextures;
// Features
#ifdef PBR_METALLIC_ROUGHNESS
PbrMetallicRoughness pbrMetallicRoughness;
#endif
#ifdef PBR_SPECULAR_GLOSSINESS
PbrSpecularGlossiness pbrSpecularGlossiness;
#endif
#ifdef PBR_CLEARCOAT
PbrClearCoat pbrClearCoat;
#endif
#ifdef PBR_TRANSMISSION
PbrTransmission pbrTransmission;
#endif
#ifdef PBR_IOR
PbrIor pbrIor;
#endif
#ifdef PBR_SPECULAR
PbrSpecular pbrSpecular;
#endif
#ifdef PBR_VOLUME
PbrVolume pbrVolume;
#endif
#ifdef PBR_SHEEN
PbrSheen pbrSheen;
#endif
#ifdef PBR_EMISSIVE_STRENGTH
PbrEmissiveStrength pbrEmissiveStrength;
#endif
#ifdef PBR_IRIDESCENCE
PbrIridescence pbrIridescence;
#endif
};
如果材质结构体中找不到某些具体数据点,这些功能的数据就不会被设置。例如,如果材质结构体中没有 pbrClearCoat,就不会设置清漆层数据。如果找不到 uniform 块,渲染时就不会设置任何数据。
每个材质属性都对应 Defold 内部的一个渲染常量。你可以在材质资源本身上定义常量来覆盖默认值,命名模式为 pbrFeature.structMember。如果 glTF 材质中缺少匹配数据,这些值会自动应用。

要把这些材质数据用于基于物理的光照,请在片段着色器中使用 PbrMaterial 块提供的参数实现 BRDF。
另请参阅: