O Substrate introduz mudanças na forma como os dados de material são coletados, processados, armazenados e usados para iluminação. Esta página fornece uma visão geral rápida de como o sistema funciona para programadores.
Do ponto de vista da criação, um material pode continuar usando as entradas do nó raiz existente ou usar nós de material do Substrate (slabs, operadores) e conectá-los à entrada de Material frontal do nó raiz. Dentro de um shader de material, isso é traduzido por TEMPLATE_USES_SUBSTRATE==0 no primeiro caso e TEMPLATE_USES_SUBSTRATE==1 no último caso.
Ao usar iluminação diferida, os dados do material são armazenados em um armazenamento intermediário, chamado GBuffer. O Substrate tem dois modos de armazenamento do GBuffer:
GBuffer mesclável: semelhante ao formato de armazenamento existente do GBuffer.
GBuffer adaptativo: esse armazenamento é transformado em um fluxo de bits de dados, cujo formato muda de pixel para pixel.
Esse formato do GBuffer é configurado nas configurações do projeto e depende de se a plataforma-alvo é ou não compatível com o GBuffer adaptativo.
Para obter mais informações sobre o GBuffer e seu uso com o Substrate, confira a seção “GBuffer” de Visão geral de materiais Substrate.
Dados de textura da cena
Os dados de textura da cena continuam sendo consultados com SceneTextureLookup() para os formatos GBuffer mesclável e GBuffer adaptativo. Ao usar o GBuffer adaptativo, essa função retornará apenas os primeiros dados de fechamento.
Shader global
Quando os dados precisam ser acessados em um shader global, em uma renderização diferida (por exemplo, para fins de iluminação), você precisa declarar e vincular o parâmetro global do Substrate da seguinte maneira:
class FMyGlobasShaderCS : public FGlobalShader
{
DECLARE_SHADER_TYPE(FMyGlobasShaderCS, Global)
SHADER_USE_PARAMETER_STRUCT(FMyGlobasShaderCS, FGlobalShader);
using FPermutationDomain = TShaderPermutationDomain<>;
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
...
SHADER_PARAMETER_RDG_UNIFORM_BUFFER(FSubstrateGlobalUniformParameters, Substrate)
...
END_SHADER_PARAMETER_STRUCT()
FMyGlobasShaderCS::FParameters PassParameters;
PassParameters.Substrate = Substrate::BindSubstrateGlobalUniformParameters(View);No shader, os formatos de GBuffer mesclável e adaptativo precisam ser gerenciados.
Planejamos uma abstração melhor em uma versão futura para facilitar a manutenção.
#if SUBSTRATE_LOAD_FROM_MATERIALCONTAINER
// For Adaptive GBuffer
FSubstrateAddressing Addressing = GetSubstratePixelDataByteOffset(PixelPos, uint2(View.BufferSizeAndInvSize.xy), Substrate.MaxBytesPerPixel);
FSubstratePixelHeader Header = UnpackSubstrateHeaderIn(Substrate.MaterialTextureArray, Addressing, Substrate.TopLayerTexture);
#else
// For Blendable GBuffer
FSubstrateGBufferBSDF Data = SubstrateReadGBufferBSDF(GetScreenSpaceDataUint(PixelPos));
#endif
Shader de material
Em um shader de material, se o material tiver a entrada de Material frontal conectada, TEMPLATE_USES_SUBSTRATE==1 será definido, e os dados de fechamento poderão ser processados e recuperados da seguinte forma:
// Initialise a Substrate header with normal in registers
FSubstrateData SubstrateData = PixelMaterialInputs.GetFrontSubstrateData();
FSubstratePixelHeader Header = MaterialParameters.GetFrontSubstrateHeader();
Header.IrradianceAO.MaterialAO = GetMaterialAmbientOcclusion(PixelMaterialInputs);
if (Header.SubstrateTree.BSDFCount > 0)
{
FSubstrateIntegrationSettings Settings = InitSubstrateIntegrationSettings(false, true, 0, false);
float3 TotalTransmittancePreCoverage = 0;
Header.SubstrateUpdateTree(SubstrateData, V, Settings, TotalCoverage, TotalTransmittancePreCoverage);
Para materiais que não usam nós do Substrate, como as entradas do nó raiz legado, TEMPLATE_USES_SUBSTRATE==0 será definido e os dados podem ser recuperados como de costume, desta forma:
float3 BaseColor = GetMaterialBaseColor(PixelMaterialInputs);
float Metallic = GetMaterialMetallic(PixelMaterialInputs);
...Propriedades de material
Depois que um BSDFContext for recuperado (veja o código acima), você poderá acessar os dados de fechamento da seguinte forma:
SLAB_DIFFUSEALBEDO(BSDFContext.BSDF)
SLAB_F0(BSDFContext.BSDF);
SLAB_ROUGHNESS(BSDFContext.BSDF)Avaliação de iluminação
Para avaliar uma luz específica com iluminação diferida, use a seguinte função, localizada em Substrate\SubstrateDeferredLighting.ush:
FSubstrateDeferredLighting SubstrateDeferredLighting(...)Para avaliar toda a iluminação na renderização direta, use a seguinte função localizada em Substrate\SubstrateForwardLighting.ush:
float3 SubstrateForwardLighting(...)Além disso, há duas funções úteis para avaliação, respectivamente, de luzes analíticas e iluminação de ambiente, localizadas em Substrate/SubstrateEvaluation.ush:
// Analytical lighting
FSubstrateEvaluateResult SubstrateEvaluateBSDFCommon(...);
// Environment lighting
FSubstrateEnvLightResult SubstrateEvaluateForEnvLight(...);Arquivos de shader
Esta é uma lista dos arquivos de shader mais usados:
A API de shader atual está sujeita a alterações em versões futuras.
| Arquivos de shader | Descrição |
|---|---|
| Contém os principais structs de dados do Substrate, os acessadores de dados, bem como rotinas de leitura de dados para o GBuffer adaptativo. |
| Contém a lógica de leitura/descompactação para dados do GBuffer mesclável. |
| Contém a lógica principal de avaliação de sombreamento para luz analítica e luz de ambiente. |
| Contém a avaliação de sombreamento para o caminho de iluminação diferida. |
| Contém a avaliação de sombreamento para o caminho de iluminação direta. |
Recursos adicionais
Apresentação técnica do Substrate: Siggraph 2023 — Unreal Engine Substrate: Criando materiais que fazem a diferença
Apresentação de autoria do Substrate: Unreal Fest 2025 Estocolmo — Tudo o que você queria saber sobre o Substrate