애러 추적 : GetSingleLayerWaterMaterialOutput 에 대해서...
애러 추적
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 는 수정 하지말고 추가 하는 것이 원칙인데... 예전에 무시하고 작업 했다가 최근 몇 일 힘들었네요.