UNREAL ENGINE

애러 추적 : GetSingleLayerWaterMaterialOutput 에 대해서...

jplee 2024. 6. 28. 11:39

애러 추적

5.4.2 소스를 일부 내용을 목적에 부합하게 일부 수정하고 게임 콘텐트를 빌드 하면서 만나게 된 몇 가지 애러 출력을 추적 합니다.

애러를 추적하고 근본 원인을 이해하고 복기 합니다.

5.4.1 수정 된 엔진을 사용하고 있는 상태에서 컨텐트의 쉽핑 빌드 테스트가 진행 될 때 5.4.2 수정 버전으로 교체 하여 진행 하는 경우.

PackagingResults: Error: use of undeclared identifier 'GetSingleLayerWaterMaterialOutput0'
PackagingResults: Error: use of undeclared identifier 'GetSingleLayerWaterMaterialOutput1'
PackagingResults: Error: use of undeclared identifier 'GetSingleLayerWaterMaterialOutput2'
PackagingResults: Error: use of undeclared identifier 'GetSingleLayerWaterMaterialOutput3'

및 아래 GetThinTranslucentMaterialOutput0 함수가 undeclared identifier (선언되지 않은 식별자) 애러를 띄우게 되는 경우가 있습니다.

이에 대한 원인 추적.

이 애러 추척 상황은 매우 일반적이지 않은 상황이란 점을 먼저 언급합니다.

상황.

1. EngineTypes.h 와 PixelInspectorResult.h 및 관련 몇군데를 수정 함.  게임 프로젝트에 전용으로 사용할 SHADINGMODELID 가 추가 되었음.

2. 이때 의도 하지 않게 IDX 가 변경 되었음. 

원본 디파인 된 인덱스는 아래와 같음.

#define PIXEL_INSPECTOR_SHADINGMODELID_SINGLELAYERWATER 10
#define PIXEL_INSPECTOR_SHADINGMODELID_THIN_TRANSLUCENT 11

ShadingCommon.ush 도 참조.

// SHADINGMODELID_* occupy the 4 low bits of an 8bit channel and SKIP_* occupy the 4 high bits
#define SHADINGMODELID_UNLIT								0
#define SHADINGMODELID_DEFAULT_LIT							1
#define SHADINGMODELID_SUBSURFACE							2
#define SHADINGMODELID_PREINTEGRATED_SKIN					3
#define SHADINGMODELID_CLEAR_COAT							4
#define SHADINGMODELID_SUBSURFACE_PROFILE					5
#define SHADINGMODELID_TWOSIDED_FOLIAGE						6
#define SHADINGMODELID_HAIR									7
#define SHADINGMODELID_CLOTH								8

#define SHADINGMODELID_SINGLELAYERWATER						10
#define SHADINGMODELID_THIN_TRANSLUCENT						11
#define SHADINGMODELID_STRATA								12		// Temporary while we convert everything to Strata

#define SHADINGMODELID_NUM									15
#define SHADINGMODELID_MASK									16		// 4 bits reserved for ShadingModelID

Custom Shading model 을 추가 하다 보면 define idx 일치 시키지 않은 경우가 발생 할 수 있음. 주의.

1차적으로 아무튼 위와 같은 내용과도 관계가 있는데...

이게 왜 저 위와 같은 선언되지 않은 식별자가 있다는 애러가 뜨냐면... 

애러 관련 된 GetSingleLayerWaterMaterialOutput 함수 선언부를 소스코드에서 아무리 찾더라도 없음. 함수를 호출 하는 부분만 검색 됨.

왜냐면 저 함수는 머티리얼 에디터에서 Apply 할 때 생성해서 uasset 에 저장 되는 생성함수.

MaterialExpressions.cpp 를 보면...

23098 라인 부터...

// BasePixelShader.usf에서 사용되는 함수 이름 GetSingleLayerWaterMaterialOutput{index}를 생성합니다.
if (OutputIndex == 0)
{
    CodeInput = ScatteringCoefficients.IsConnected() ? ScatteringCoefficients.Compile(Compiler) : Compiler->Constant3(0.f, 0.f, 0.f);
}
else if (OutputIndex == 1)
{
    CodeInput = AbsorptionCoefficients.IsConnected() ? AbsorptionCoefficients.Compile(Compiler) : Compiler->Constant3(0.f, 0.f, 0.f);
}
else if (OutputIndex == 2)
{
    CodeInput = PhaseG.IsConnected() ? PhaseG.Compile(Compiler) : Compiler->Constant(0.f);
}
else if (OutputIndex == 3)
{
    CodeInput = ColorScaleBehindWater.IsConnected() ? ColorScaleBehindWater.Compile(Compiler) : Compiler->Constant(1.f);
}

머티리얼 편집기에서 Pin 에 연결 된 조건에 따라 함수를 생성해서 uasset 안에 식별자를 선언함.

 

셰이더의 IDX가 변경 되었다면 WATER 마스터 머티리얼에 셋팅 된 현재 라이트모델이 표시 이름만

SingleLayerWater

일 수 있음.

이때는 머티리얼 에디터에서 워터 마스터 어셋을 열고 SingleLayerWater 라이트모델을 unlit 으로 바꿨다가 다시 SingleLayerWater 해서 현재 IDX 로 갱신 해 주고 Apply 하고 저장하면 위 MaterialExpressions.cpp 루프가 다시 돌고 uasset 에 함수를 생성해서 저장 함. 이걸 셰이더 에서 호출해서 바인딩 하는 것임.

이러한 구조를 취하는 셰이딩 모델을 2개가 존재 함.

MSM_SingleLayerWater       UMETA(DisplayName="SingleLayerWater"),
MSM_ThinTranslucent       UMETA(DisplayName="Thin Translucent"),

이렇게 2 가지.

가능하면 원래의 IDX 는 수정 하지말고 추가 하는 것이 원칙인데... 예전에 무시하고 작업 했다가 최근 몇 일 힘들었네요.