서브스트레이트에서는 라이팅을 위해 머티리얼 데이터를 수집, 처리, 저장 및 사용하는 방식이 변경되었습니다. 이 페이지는 프로그래머가 이 같은 시스템의 작동 방식을 빠르게 살펴볼 수 있게 해줍니다.
제작의 관점에서, 머티리얼은 기존 루트 노드의 입력을 계속 사용하거나 서브스트레이트 머티리얼 노드(슬랩, 오퍼레이터)를 사용하여 루트 노드의 정면 머티리얼 입력에 연결할 수 있습니다. 머티리얼 셰이더 내에서 전자는 TEMPLATE_USES_SUBSTRATE==0, 후자는 TEMPLATE_USES_SUBSTRATE==1 로 변환됩니다.
디퍼드 라이팅을 사용하는 경우, 머티리얼 데이터는 GBuffer라는 중간 스토리지에 저장됩니다. 서브스트레이트에는 다음과 같은 두 가지 GBuffer 스토리지 모드가 있습니다.
블렌더블 GBuffer: 기존 GBuffer 스토리지 포맷과 유사합니다.
어댑티브 GBuffer: 이 스토리지는 데이터 비트스트림으로 변경되며, 포맷이 픽셀별로 바뀝니다.
이 GBuffer 포맷은 프로젝트 세팅에서 환경설정되며, 의도한 타깃 플랫폼의 적응형 GBuffer 지원 여부에 따라 달라집니다.
GBuffer 개요 및 서브스트레이트와 함께 사용하는 방법에 대한 자세한 내용은 서브스트레이트 머티리얼 개요의 'GBuffer' 섹션을 참고하세요.
씬 텍스처 데이터
씬 텍스처 데이터는 블렌더블 Gbuffer 및 어댑티브 GBuffer 포맷 양쪽에서 SceneTextureLookup()으로 계속 쿼리됩니다. 어댑티브 GBuffer를 사용하는 경우, 이 함수는 첫 번째 클로저 데이터만 반환합니다.
글로벌 셰이더
디퍼드 렌더링 시 라이팅을 위해 글로벌 셰이더에서 데이터에 액세스해야 하는 경우에는 다음과 같이 서브스트레이트 글로벌 파라미터를 선언하고 바인딩해야 합니다.
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);셰이더에서 블렌더블 및 어댑티브 GBuffer 포맷을 모두 처리해야 합니다.
관리를 용이하게 하기 위해 향후 출시 버전에서 추상화를 향상할 계획입니다.
#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
머티리얼 셰이더
머티리얼의 정면 머티리얼 입력이 연결된 경우에는 머티리얼 셰이더에서 TEMPLATE_USES_SUBSTRATE==1이 정의되며, 클로저 데이터를 다음과 같이 처리하여 얻을 수 있습니다.
// 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);
레거시 루트 노드 입력과 같이 서브스트레이트 노드를 사용하지 않는 머티리얼의 경우에는 TEMPLATE_USES_SUBSTRATE==0이 정의되며, 다음과 같이 평소처럼 데이터를 얻을 수 있습니다.
float3 BaseColor = GetMaterialBaseColor(PixelMaterialInputs);
float Metallic = GetMaterialMetallic(PixelMaterialInputs);
...머티리얼 프로퍼티
BSDFContext를 얻으면(위의 코드 참고) 다음과 같이 클로저 데이터에 액세스할 수 있습니다.
SLAB_DIFFUSEALBEDO(BSDFContext.BSDF)
SLAB_F0(BSDFContext.BSDF);
SLAB_ROUGHNESS(BSDFContext.BSDF)라이팅 평가
디퍼드 라이팅으로 특정 라이트를 평가하려면 Substrate\SubstrateDeferredLighting.ush에 있는 다음 함수를 사용합니다.
FSubstrateDeferredLighting SubstrateDeferredLighting(...)포워드 렌더링에서 전체 라이팅을 평가하려면 Substrate\SubstrateForwardLighting.ush에 있는 다음 함수를 사용합니다.
float3 SubstrateForwardLighting(...)또한 Substrate/SubstrateEvaluation.ush에는 두 함수가 있으며, 각각 분석적 라이트와 인바이런먼트 라이팅 평가에 유용합니다.
// Analytical lighting
FSubstrateEvaluateResult SubstrateEvaluateBSDFCommon(...);
// Environment lighting
FSubstrateEnvLightResult SubstrateEvaluateForEnvLight(...);셰이더 파일
자주 사용되는 셰이더 파일 목록은 다음과 같습니다.
현재 셰이더 API는 향후 출시 버전에서 변경될 수 있습니다.
| 셰이더 파일 | 설명 |
|---|---|
| 서브스트레이트의 핵심 데이터 구조체, 데이터 접근자 및 적응형 GBuffer에 대한 데이터 읽기를 포함합니다. |
| 블렌더블 GBuffer 데이터에 대한 읽기/언패킹 로직을 포함합니다. |
| 분석적 라이트 및 인바이런먼트 라이트에 대한 메인 셰이딩 평가 로직을 포함합니다. |
| 디퍼드 라이팅 패스에 대한 셰이딩 평가를 포함합니다. |
| 포워드 라이팅 패스에 대한 셰이딩 평가를 포함합니다. |
추가 리소스
서브스트레이트 기술 프레젠테이션: Siggraph 2023 - 언리얼 엔진 서브스트레이트: 중요 머티리얼 제작하기
서브스트레이트 제작 프레젠테이션: 언리얼 페스트 2025 스톡홀름 - 서브스트레이트에 대한 모든 것