본문 바로가기
툰렌더링 공부

언리얼 엔진 뜯어보기 #6

by IX. 2023/04/26 10:46:20

4.26

셰이더 컴파일 중 강제종료했더니 엔진이 고장났다.

다시 빌드해야 할 것 같다. 수요일 아침의 산뜻한 출발.

이것이 프로그래머가 가는 지옥인가.

컴파일을 중간에 그만두고 다시 켰더니 두개의 코어가 싸우며 데이터를 망가뜨린 모양이다.

그래서 한동안 고생. 하지만 팀 내 언리얼 전문가가 해결해 주셨다.

새로 세팅된 무대에서!

덕분에 오늘 공부 쉽니다. 내일은 스카이라이트를 알아보자.

 

4.27

언리얼에서 앰비언트 컬러를 조절하는 부분은 2가지가 있다. 하나는 라이트매스, 하나는 스카이라이트.

이 중 루멘은 라이트매스를 사용하지 않으므로 패스. 라이트맵이여, 안녕!

 

스카이 라이트 코드를 살펴보기 전에 먼저 스카이라이트의 특성부터 이해해보자.

내가 이해한 바로 기본은 IBR(Image Based Rendering)과 같다.다만 이걸 게임에서 캡처하느냐, 이미지를 갖다쓰느냐의 차이이다.

Intensity 50의 빨강. 기본은 더하기인데, AO는 곱하기...한 번 더 계산 후 Lerp인가?

일단 의심되는 부분을 빼는 것으로 시작해보자.

BasePassPixelShader.usf 엔 2개의 스카이 라이팅을 더하는 부분이 있다.

//OutSubsurfaceLighting += SkySubsurfaceLighting;
//OutDiffuseLighting += SkyDiffuseLighting;

땡. 정답이 아니다.

 

아래로 내려보니 간접광을 더 하는 좀 더 직접적인 코드가 있다.

//DiffuseColor += (DiffuseIndirectLighting * DiffuseColorForIndirect + SubsurfaceIndirectLighting * SubsurfaceColor) * AOMultiBounce( GBuffer.BaseColor, ShadingOcclusion.DiffOcclusion );

땡. 이것도 정답이 아니다.

그럼 좀 더 범위를 크게 잡아서, GetSkyLighting()이 조명에 영향을 끼치는 것은 맞는지 확인해볼 필요가 있다. 함수 전체를 주석처리 해보자.

땡. 스카이라이트는 여전히 계산되고 있다. 스카이라이트를 계산하는 곳은 다른 곳이다.

 

대부분의 간접광은 FPixelShaderInOut_MainPS()에서 집중적으로 계산되고 있다. 그런데 이 부분의 코드를 아무리 건드려도 결과물에 영향을 끼치지 않는 모양새다. 이 패스를 타긴 타는 걸까? 베이스컬러를 초록색으로 바꿔보자

어..타네. 음...그렇다면...변수가 선언되자마자 간접광 색을 지정해보자.

DiffuseIndirectLighting = float3(0, 1, 0);
SubsurfaceIndirectLighting = float3(1, 0, 0);

스카이라이트 외에 디퓨즈 컬로로 컬러블리딩을 하고 있는 모양?

헌데 이게 다시 해보니 재현이 안된다.. 왜일까.

 

픽셀 셰이더를 따라 렌더순서를 훑고 있노라니 MRT가 다시 등장했다.

내가 잘못파악했던 사실은 MRT[0]은 포그값이라는 것이다.(다만, 언릿에서는 디퓨즈 그 자체다)

씬에 헤이트포그가 없으므로, 이 수치는 사실 어떻게 변경하든 씬에는 영향을 끼치지 않는다.

LightAccumulator에도 인자를 단순하게 넘기고 있다.

 

또한 렌더링된 이미지는 최종적으로 MRT[3]에 저장되는 줄 알았는데, 이게 단순히 '디퓨즈'만 저장하는 걸로 보인다.

왜냐면 MRT[3] = 초록으로 맞추면...

이런 결과를 보인다. 

그렇다면 간접광 계산된 정보가 셰도우 마스크로 넘어가는 걸까?

다시 AccumulateDynamicLighting()로 돌아가서 그림자의 색을 빨강으로 변경해보자.

가만... 그런데 간접광이 사라졌다.

MRT[3]의 정체를 정확히 파악할 필요가 있어 보인다.

먼저 그림자를 모두 빼보자.

디렉셔널 라이트의 존재를 모두 지워도 형체가 남는다. 이미시브는 남는다.

즉 그 사이 어딘가에서 스카이 라이트를 합성하고 있다. 그게 어디일까.

 

다음에 알아보도록 하자.

 

5.2

긴 휴일이었다.. 뭘 하다가 말았더라...

싶다가 휴가를 쉬고 오니 회사일이 덤벼서 엔진파보기는 나중에.

 

5.3

루멘관련 자료를 찾아보다가 루멘은 스카이라이트를 보조로만 사용한다는 내용을 발견했다.

그렇다면 스카이 라이트는 왜 씬전체의 앰비언트 컬러를 조절하는 것일까? 또 AO는 왜 표현되는 것일까?

2가지 실험을 해보자.

포워드 라이트에서의 스카이 라이트, 루멘이 없는 언리얼4에서의 스카이 라이트.

 

먼저 포워드 라이트의 스카이라이트

라이트빌드전까지는 그저 검게 표현된다.예상대로 간접광은 물론이고 AO조차 어림도 없다.

 

하지만 언리얼4에서는 AO가 표현된다.

퀄리티야 어떻든 모빌리티를 스테이셔너리로 맞추면 안쪽도 어둡게 표현해준다.

그렇다면, 언리얼5에서도 똑같이 라이트를 구워주면...

'

아차...! 못굽는다!!! 사유는 다음과 같다.

에디터 모드일때, 프로젝트 세팅에서 스태틱 라이트를 허용하거나, 셰이더모델5이하에서만 작동한다.

AO는 실시간으로 계산되고 있는 것인가?

 

스태틱 라이트를 허용해서 라이트빌드를 테스트할 생각을 하니 벌써부터 머리가 아프다.

그것은 셰이더 재컴파일을 의미하기 때문...

에라이!

스태틱 라이트 허용이 라이트맵 베이킹을 의미하는 것이라면, 루멘의 실시간 GI와 충돌하는 것은 아닌가?

라이트 빌드를 통해 생성한 정보를 루멘과 합쳐본다면 어떤 결과를 보여줄까?

정말 깔끔하게 무시한다... 구워는 드릴께. 수준

루멘을 끄면, 비로소 보이는 라이트맵. 

이제 가설을 세워보자. 사전계산된 AO와 루멘이 계산하는 AO는 다르다.

그렇다면 스카이라이트는 루멘에 귀속되어 합성될 것이다.

이에 대해서는 내일 알아보기로 하자.