3.24
셰이더 모델은 추가했다. 하지만 더 재미있는 걸 하기 전에, 먼저 리로드방법에 대해 알아야 한다.
C++파일이야 어쩔 수 없지만, 수정이 잦은 파일을 고칠 때마다 엔진을 재시동하는 건 비효율적이다.
그렇다면 먼저 확인을 위해 최종 Output이 어디에 붙어있는지 파악해야 한다.
일단 DeferredLightPixelShaders.usf 에서 그럴싸해 보이는 값을 수정해보자.
// OutColor.rgb = AtmosphericTransmittance * Radiance.xyz * Attenuation * LocalCoverage * GetExposure();
OutColor.rgb = float3(1, 0, 0);
OutColor.a = LocalCoverage;
안된다.(...) 이게 아닌가
공식문서를 보니 Ctrl+Shift+.로 셰이더를 재컴파일 할 수 있다고 써 있다.
이거라면 시간을 좀 더 단축할 수 있다!
일단 이것 저것 값을 고쳐보자.
코드처럼 최종 아웃풋을 빨갛게 표현하고 싶다.
하지만 어떤 값을 변경해도 변화가 없다.
루멘이야 그렇다쳐도 Unlit은 변해야 할텐데!?
내일 다시 도전해보자.
실패하면 될 때까지!
3.27
아웃컬러를 조절하는 부분은 BasePassPixelShader.usf에 있다.
여기서 컬러를 계산한 후, 이를 빛누적기(LightAccumulator)에 넘겨준다.
이를 넘겨주기 전에 Color를 빨간색으로 강제로 맞춰주었다.
언릿은 예상대로 붉은색이 나온다. 하지만 여전히 Lit은 형태를 띈다.
난 최종색깔 = RGB라고 처리된 부분을 찾고 있었는데, 언리얼은 그보단 좀 더 복잡한 로직을 사용하는 것 같다.
하지만 코드만 길었지, 절반정도는 Strata라는 머티리얼 합성 시스템에 사용되는 로직들이다.
이 Strata여전히 실험기능이라고 한다.언리얼을 4.0에 만났다면 조금 더 쉬웠을까.(하지만 루멘도 없었겠지..)
Chat GPT는 언리얼4 시절의 정보를 담고 있지만, 그래도 도움은 된다.
고장내보자.
Out.MRT[0] = half4(0, 1, 0, 1);
Out.MRT[1] = half4(1, 0, 0, 1);
Out.MRT[2] = half4(0, 0, 1, 1);
Out.MRT[3] = half4(1, 0, 0, 1);
Out.MRT[4] = half4(1, 1, 0, 1);
3.28
건강검진으로 인해 이틀휴가
사렬줘...
3.30
BasePassPixelShader.usf를 수정할 경우 머티리얼을 적용시켜 놓고 Apply를 누르면 5분걸릴 셰이더 컴파일이 5초만에 끝난다. 전역에 적용되지는 않지만, 셰이더 개발엔 더 없이 좋은 처리방법이다. 역시 매뉴얼을 잘 읽어야 한다.
3.31
원하는 거의 모든 내용은 BasePassPixelShader.usf에 모두 기술되어 있다. 예상과는 다르게 MRT배열은 0번만 중요하고, 나머지는 모션블러등에 사용된다. mainPS()에서 사용되는 Out구조체는 생각보다 단순했다.
struct FPixelShaderOut
{
// [0..7], only usable if PIXELSHADEROUTPUT_MRT0, PIXELSHADEROUTPUT_MRT1, ... is 1
float4 MRT[8];
// Explicit uint output specific to strata.
uint StrataOutput[3];
// Pixel Shader OutCoverage, only usable if PIXELSHADEROUTPUT_COVERAGE is 1
uint Coverage;
// Pixel Shader OutDepth
float Depth;
};
마참내! 원하던 걸 찾아냈다. 이 코드는 간접광과 AO를 합성해서 돌려주는 것 같다. 물론 예상대로 돌아갈지는 좀 더 확인이 필요하다.
DiffuseColor += (DiffuseIndirectLighting * DiffuseColorForIndirect + SubsurfaceIndirectLighting * SubsurfaceColor) * AOMultiBounce( GBuffer.BaseColor, ShadingOcclusion.DiffOcclusion );
그리고 좀 더 다양한 연산을 거쳐서 그 값을 Color에 넘겨준다.
#if !POST_PROCESS_SUBSURFACE && !MATERIAL_SHADINGMODEL_THIN_TRANSLUCENT
// For skin we need to keep them separate. We also keep them separate for thin translucent.
// Otherwise just add them together.
Color += DiffuseColor;
#endif
#if !MATERIAL_SHADINGMODEL_THIN_TRANSLUCENT
Color += Emissive;
#endif
그리고 그 컬러는 빛 연산을 거쳐
LightAccumulator_Add(LightAccumulator, Color, 0, 1.0f, false);
MRT 0번배열에 저장된다.
Out.MRT[0] = RETURN_COLOR(LightAccumulator_GetResult(LightAccumulator));
하지만 이전에 했듯이 MRT[0]을 단색으로 맞춰도 어쩐지 더 칠해지는 색들이 있다.
이것에 대해선 좀 더 나중에 조사해보자.