플레이어가 시즌 사이에 포트나이트에 로그인하면 새로운 시즌이 시작되기 전까지 자리표시자 역할을 하는 고정된 화면을 보게 됩니다. 포트나이트 팀은 뭔가 색다른 콘텐츠로 챕터 3 시즌 3의 시작을 알리고 싶었습니다.
포트나이트 팀은 언리얼 엔진의 핵심 기능을 활용하여 곧 출시되는 시즌의 비주얼 요소로 가득 찬 몰입감 있는 씬을 만들었습니다.
이렇게 제작된 씬은 샘플 정밀도가 높은 오디오 재생이 가능한 언리얼 엔진의 네이티브 서브시스템 쿼츠에 동기화되었습니다. 프로시저럴 방식으로 생성된 음악 요소는 비주얼 이펙트와 함께 쿼츠 클럭에 '등록'되었고, 덕분에 멋진 생물 발광 숲이 음악에 완벽하게 동기화되어 고동칠 수 있었습니다.
포트나이트의 새 시즌을 축하하는 이벤트에서 이와 같은 시도는 처음입니다. 이 블로그에서는 프로젝트에 참여한 에픽게임즈 디자이너와 아티스트로부터 이 멋진 결과를 얻을 수 있었던 비결에 대해 들어보겠습니다.
다운타임 화면에서 재생되는 비디오 게임 오디오
안녕하세요! 저는 에픽게임즈의 테크니컬 사운드 디자이너 애덤 블록(Adam Block)입니다. 이 기술 블로그에서 최근에 저희 팀이 언리얼 엔진 서브시스템 쿼츠를 사용하여 포트나이트에 구현했던 것을 공유하고 설명하려 합니다. 이 글을 통해 쿼츠가 무엇인지, 어떻게 작동하는지 더 잘 이해하여 자신의 프로젝트에 쿼츠를 도입하는 계기가 되기를 바랍니다. 이 놀라운 기능에 대해 알아보기 위해 시간 내 주셔서 감사합니다.
쿼츠란 무엇인가요?
쿼츠는 오디오 버퍼 사이에서도 이벤트가 매우 정확한(샘플 정밀도가 높은) 순간에 일어나도록 이벤트를 계획하는 언리얼 엔진 내 서브시스템입니다. 음악 컨텍스트에서 쿼츠를 사용하는 경우, 쿼츠는 오케스트라 앞의 지휘자 역할을 한다고 말할 수 있습니다. 지휘자는 오른손으로 지휘봉을 일정한 패턴으로 흔들며 모든 연주자가 정해진 템포를 따르도록 하는 동시에, 경우에 따라 왼손을 앞으로 뻗어 자신의 파트에서 연주를 시작해야 하는 여러 섹션의 연주자에게 정확한 순간을 알려줍니다.
쿼츠 덕분에 높은 샘플 정밀도로 오디오를 재생할 수 있으며, 오디오 엔진은 충분한 시간을 들여 PFX 또는 기타 게임플레이 이벤트용 게임 스레드에 이벤트를 다시 전달할 수 있습니다. 멋지지 않나요? 'Play Quantized' 이벤트를 재생하는 쿼츠는 .wav, 사운드 큐, 메타사운드, 오디오 컴포넌트를 비롯한 모든 종류의 uSoundbase 오브젝트를 사용할 수 있습니다.
'Quantized Playback' 이벤트가 발생하는 바로 그 순간에 파티클 이펙트가 버스트되거나 라이트가 빛을 발하도록 트리거할 수 있습니다. 쿼츠 서브시스템 내에서는 곡의 템포와 미터(예: 4마디마다, 8마디마다 두 번째 비트에)와 관련된 특정한 수의 '양자화 바운더리'를 정의할 수 있습니다.
쿼츠는 음악에 관한 아이디어를 구현하는 좋은 방법이지만, 음악과 관련되지 않은 아이디어를 구현할 때 사용해도 좋습니다. 사실 포트나이트의 일부 무기에서는 매우 빠르고 정확한 무기 발사 오디오를 트리거하기 위해 쿼츠가 사용되었습니다. 쿼츠 클럭을 사용하여 110 BPM 클럭의 32번째 음표를 실행하는 기관단총의 발사 오디오 시간을 계획한다고 생각해 보세요. 파티클 이펙트는 쿼츠 클럭을 등록하여 총이 발사될 때마다 정확하게 파티클 이펙트를 스폰할 것입니다. 쿼츠를 사용하지 않는 경우 영상의 프레임 레이트에 바인딩되므로, 빠르게 발사되는 총 소리가 일정하지 않고 '성급하게' 들리는 경우가 종종 발생할 것입니다.
프로시저럴 음악
포트나이트 새 시즌의 출시에 앞서 대략 10시간에 이르는 '다운타임' 기간을 위한 커스텀 음악을 제작해 달라는 요청이 있었습니다. 이는 쿼츠를 사용하여 인식할 수 있는 반복적인 루프나 특징적인 음악적 패턴 없이 프로시저럴 방식으로 생성된 (루핑되지 않는) 청취 경험을 만들 수 있는 기회였습니다. 일반적으로 동일하게 반복되는 콘텐츠를 계속해서 들으면 쉽게 지루해지거나 질릴 수 있습니다. 그래서 저희는 악절의 작은 '청크'를 가져다 셔플하고 런타임 동안 재생할 베리에이션을 무작위로 선택했습니다.
저희는 이 로직을 처리할 블루프린트에 음악 컨트롤러를 빌드했습니다. 다시 말해, 여러 곡이 추가된 플레이리스트를 셔플하고 곡을 무작위로 선택하는 음악 컨트롤러를 빌드한 것입니다. 곡이 선택되면 베이스, 드럼, 멜로디, 퍼커션, 코드 등 모든 음악적 '스템'은 '현재 곡'으로 참조되며 쿼츠 서브시스템을 사용하는 블루프린트 로직은 무엇을 언제 재생해야 하는지 알려줍니다.
쿼츠의 엄청난 장점 중 하나는, 이 기능이 언리얼 엔진의 서브시스템이기 때문에 개발 팀의 누구나 제 쿼츠 클럭을 등록하여(예를 들어, '곡 1', '곡 2' 등) 현재 재생되고 있는 트랙의 모든 마디와 비트를 얻을 수 있다는 것입니다. 마디, 비트 등을 갖고 있는 사람은 누구나 음악과 완벽히 동기화된 상태에서 원하는 아이디어를 구현하는 창작의 자유를 누릴 수 있습니다.
저희의 경우, 다른 팀이 아주 쉽게 처리할 수 있도록 쿼츠 클럭에서 마디, 비트, 기타 서브디비전에 대한 델리게이트를 호출했습니다. 이 델리게이트는 FX 팀이 비주얼 변경사항을 처리하기 위해 사용하는 이벤트에 바인딩되었습니다. 이렇게 해서 만들어낸 결과물을 소개합니다.
기본 데이터 에셋 - 곡별 정보
각 곡은 자체 기본 데이터 에셋입니다. 이 데이터 에셋은 트랙과 관련된 모든 정보를 가지고 있습니다. 트랙 이름(저희는 이 변수를 '클럭 이름'이라고 불렀습니다), 템포, 트랙이 종료되고 플레이리스트가 셔플될 때까지 절차적으로 재생되길 원하는 곡 재생 시간(마디), 각 레이어의 마디와 비트(예: 베이스 라인은 4비트가 마지막 비트인 8마디 프레이즈, 멜로디는 4비트가 마지막 비트인 4마디 프레이즈), 트랙 데이터와 에셋 내의 각 음악 스템(레이어)의 모든 uSoundBase 에셋과 같은 정보가 있죠.
개념적으로, 저희는 DJ 덱과 유사한 'A' 및 'B' 접근 방식을 사용했습니다. 멜로디가 'A'인 'A' 덱에서 모든 파트를 재생하고 해당 파트가 종료되면 다른 파트가 무작위로 선택되어 'B' 덱에서 재생됩니다. 비록 이 행동을 염두에 두고 오디오 컴포넌트를 사용하지는 않았지만, 당시에 프레이즈를 교환하고 호출 및 응답 시스템을 가리킨다는 아이디어는 잘 맞아 떨어진 것 같습니다.
'A' 멜로디, 코드 파트, 드럼 프레이즈, 베이스 라인, 타악기 파트의 배열은 대응하는 'B'의 에셋 배열에서 모든 것을 전환하고 선택합니다. 이 시스템은 기본적으로 프로시저럴 방식으로 생성된 호출 및 응답 접근 방식입니다. 데이터 에셋은 이러한 에셋과 더불어 각 레이어의 지속 시간을 정의하는 파라미터와 세팅을 보유하여, 쿼츠 클럭을 보유하는 음악 컨트롤러가 재생할 새로운 레이어를 찾고, 셔플하고, 기다려야 하는 때를 알 수 있습니다.
BeginPlay
이 프로세스가 정확히 어떻게 이루어지는지 차례대로 살펴보겠습니다. 첫째로, 사운드 믹스를 푸시하여 남아 있는 메뉴 음악이 있거나, 다른 음악이 방치되어 재생되지 않은 극한 상황의 시나리오가 발생했는지 확인합니다. 또한 멋진 로우 파이 늪지대 비주얼에 맞추어 늪지대 분위기의 앰비언트 루프 사운드를 페이드 업합니다. 앰비언트 사운드는 15초 동안 재생된 후 30초 동안 페이드 아웃됩니다. 재생되는 레코드가 있는 것처럼 니들 드롭 사운드 이펙트를 재생합니다. 테마가 '로우 파이'이므로 설정을 실행하고 음악을 재생합니다.
Shuffle Data Asset
이 함수에서는 DataAsset 배열을 취해서 셔플하고 그중 하나를 CurrentDataAsset으로 설정합니다. 이 DataAsset에서 BPM을 가져와서 다음 BPM 변수로 설정하고 IntroComplete 부울을 'false'로 설정합니다. 새로운 곡을 처음으로 재생하기 때문입니다.
Set Song Duration
이후로 모든 로직은 'Current Data Asset' 변수에서 가져옵니다. 예를 들어, 다음 함수에서는 곡의 재생 시간(마디 개수)을 가져와 'Current Song Duration'이라는 변수로 설정합니다. 이는 음악 컨트롤러가 언제 다시 플레이리스트를 셔플하고 다른 곡을 선택해야 할지 알기 위한 방법입니다. 마디의 개수는 쿼츠가 카운트하죠.
Does clock exist
툴이 처음으로 로직을 실행할 때 클럭이 이미 존재하는지 확인합니다(예: 트랙 이름 'Track02'를 기준으로). 이 경우에는 클럭이 존재하지 않습니다. 그러므로 클럭용 쿼츠 양자화 바운더리를 구성하고 새로운 클럭을 만들어 현재 곡의 이름에 관계없이 명명합니다.
양자화 바운더리 생성 및 캐시
이 함수에서는 필요한 쿼츠 양자화 바운더리를 생성하고 캐시합니다. 예를 들어, '4마디마다', '다음 마디', '즉시' 등 몇 가지 시나리오는 재생 일정을 계획하는 데 유용합니다. 이를 변수로 생성하고 캐시함으로써 블루프린트 그래프를 더욱 정돈된 형태로 만들고 양자화된 요소를 재생할 때 각 바운더리에 쉽게 접근할 수 있습니다.
부울 리셋
이 함수에서는 이전 사이클에서 설정한 모든 부울을 리셋합니다.
사이클에서 곡 확인
이 섹션에서는 이번이 곡을 순환하는 첫 번째 차례인지 확인합니다. 첫 번째 차례일 경우, 현재 활성 상태인 클럭이 있는지 먼저 확인합니다. 클럭이 아직 작동하고 있지 않다면 곡에 4마디로 이루어진 스테레오 인트로를 가져다 오디오 컴포넌트에 설정하고 '즉시' 양자화 바운더리를 사용하여 'Play Quantized'에 연결합니다.
이 '즉시' 양자화 바운더리는 클럭을 시작하며 트랜스포트를 리셋합니다(이는 쿼츠 양자화 바운더리에 대한 옵션입니다). 기본적으로, 이 시점에서 곡을 재생하는 첫 번째 차례임을 확인하고, 곡 인트로를 대기시키고, 재생 트랜스포트를 00:00:00으로 설정합니다.
다음으로 'Play Quantized'에서 다른 양자화된 비트를 등록합니다. 이는 개별 서브디비전이 델리게이트의 수를 카운트하고 전송하며 기반 클럭 펄스 이벤트 역할을 하는 이벤트로 실행되는 곳입니다.
메인 재생 로직
마디와 비트가 고동치기 시작하면 마디 변수와 비트 변수를 각각 설정하여 마디의 총 재생 시간과 현재 비트의 카운트를 유지합니다. 나중에 이 변수를 사용하여 곡 플레이리스트를 셔플할 정확한 시간을 알고 새로운 곡을 선택합니다.
각 비트에서는 다음과 같은 이벤트를 만들어서 곡이 변경되어야 하는지 확인합니다.
'Calculate Song Duration' 함수에서는 현재 데이터 에셋의 '마디의 총 재생 시간'을 참조하고 계산을 하는 각 비트에서 '지금 변경해야 하는가?'를 알아봅니다. 이는 'Bar Counter' 변수를 참조하고 Modulo를 사용하여 현재 곡 재생 시간에 최종적으로 도달한 때와 측정 값의 4번째 비트에 도달한 때를 알립니다. true일 경우, 곡의 플레이리스트를 셔플할 시간임을 알 수 있어 로직을 계속 진행할 수 있습니다.
트랙을 바꿔야 할 때는 'DJ Spin' 사운드 이펙트를 큐에 추가하고, 첫 번째 곡을 끝내고 다음 곡의 인트로를 시작하도록 돕는 전환 사운드를 스폰합니다.
마지막으로, 블루프린트 로직의 상단으로 점프하는 'InitiateNewTrackPlayback' 이벤트에 도달하여 동일한 로직을 실행하며 처음부터 다시 시작합니다. 하지만 이번에는 초기의 'Needle Drop'과 앰비언트 루핑 오디오를 우회합니다.
프로시저럴 음악 생성
트랙이 시작되면 재생할 음악 엘리먼트를 무작위로 선택하고 대기열에 등록합니다. 이때 발생하는 몇 가지 일을 한번 알아보겠습니다. 각 비트에서 'Calculate Part Timing' 함수를 사용하여 '새 음악 엘리먼트를 재생하기 적절한 시간인지' 확인합니다.
예를 들어, 베이스 파트는 'Current Data Asset'을 참조하고 베리에이션을 선택하기 전에 올바른 마디와 비트에 있는지 확인합니다. 조건이 맞을 경우, 로직의 다음 부분을 이어서 실행합니다.
이제, 다음에 재생하기 적절한 베이스 파트의 세트를 선택합니다. 앞서 언급했듯이, 각 음악 레이어에는 두 개의 '세트'가 있습니다. 바로 'A' 그룹과 'B' 그룹, 또는 '덱'입니다. DJ의 A 덱, B 덱과 유사합니다. 'A'가 재생되고 있으면 'B'에서 재생할 것을 무작위로 선택하는 것입니다. 현재 'B'가 재생되고 있다면 'A'에서 재생할 것을 무작위로 선택합니다.
선택을 마치면 'Deck A Is Playing' 변수를 취하여 다음 번에 로직이 실행될 때 다른 요소를 선택하도록 반대로 설정합니다. 이로 인해 부울 변수는 필연적으로 매번 플립플롭하게 됩니다. A가 재생되고 있으면 B를 선택하고 활성 상태로 설정합니다. B가 활성화되어 있으면 A를 선택하고 활성 상태로 설정합니다.
Play 함수로 사운드 변수 전달하기:
각 파트는 무작위로 선택되기 때문에 음악 클립 uSoundBas 레퍼런스를 출력으로 전달하고 'Queue Next Deck' 함수에 연결합니다.
'Queue Next Deck' 함수는 4마디 프레이즈인지, 전환 엘리먼트(2마디)인지, 8마디 프레이즈인지 등을 확인합니다. 확인 결과에 따라, 올바른 양자화 바운더리를 사용하여 자기 자신을 'Play Quantized' 함수에 배정합니다.
이것으로 모든 프로세스에 대해 알아보았습니다! 쿼츠는 높은 샘플 정밀도로 정확한 바로 그 순간에 재생되도록 계획할 수 있는 매우 강력한 서브시스템입니다. 이 구성에서 작업한 모든 것은 음악 레이어를 나누고, 이를 4마디 또는 8마디 프레이즈로 잘게 쪼갠 다음 다양한 양자화 바운더리를 사용하여 적절한 시간에 재생되도록 계획하는 것입니다.
쿼츠가 카운트를 완료하고 각 곡의 최대 마디 개수에 도달하면, 데이터 에셋 풀을 셔플하고, 다른 곡을 선택하고, BPM을 설정하고, 특정 부울, 게이트, DoOnce 등을 지우고, 동일한 로직을 실행합니다.
이 문제를 해결하는 저의 접근 방식은 '유일한' 방식이 아니며 또한 '에픽게임즈'의 방식이 아니라는 것을 분명히 하고 싶습니다. 그저 '하나의' 방법일 뿐입니다. 저희가 한 것처럼 이 컨트롤러를 더욱 향상하고 최적화하다 보면 통합하고, 중복을 줄이고, 이 구성에 메타사운드를 도입할 기회가 많이 생겨날 것입니다. 게임 음악, 그중에서도 특히 프로시저럴 음악 생성에 관심이 있다면 쿼츠를 활용해 보고 각자 잘 맞는 접근 방식을 사용하여 자신만의 시스템을 제작해 보시기 바랍니다. 쿼츠 서브시스템은 음악에만 사용할 수 있는 툴이 아닙니다. 음악이 아닌 다른 용도로 쿼츠를 사용한 사례가 많이 있습니다. 무기, 이벤트, 프로젝트 규모의 동기화 작업은 쿼츠 클럭을 만들어 자신만의 방법을 시도할 수 있는 훌륭한 기회입니다.
언리얼 엔진 쿼츠 서브시스템에 대해 조금 더 이해하고, 자신의 프로젝트에 활용할 방법을 생각해 보는 시간이 되었다면 좋겠습니다. 다시 한번 감사합니다!
비주얼 생성
안녕하세요! 저는 에픽게임즈의 마케팅 아트 디렉터 폴 오클리(Paul Oakley)입니다. 포트나이트 챕터 3 시즌 3의 시작 화면에 사용된 비주얼을 만든 방법에 대해 알려드리겠습니다.
개략적으로 설명하자면, 몰입형 로우 파이 앰비언트 화면을 제작했습니다. 이는 곧 출시되는 시즌의 분위기와 자연 콘셉트에 정말 잘 맞았습니다. 저희는 생물 발광 숲이라는 아이디어가 완벽히 어울릴 것이라고 생각했습니다.
렌즈와 뎁스 오브 필드를 사용하여 굉장히 추상적인 모습의 환경을 개발했습니다. 전경에 있는 요소는 디테일이 살아있지만 거리가 멀어질수록 더욱 추상적으로 보입니다.
앞서 로우 파이 사운드트랙에 대해 이야기했었죠. 저는 살아있는 생물 발광 숲 아이디어를 사운드트랙 아이디어와 묶어, 이 숲의 다양한 부분을 비트의 여러 요소와 페어링하면 어떨지 의견을 제시했습니다. 이 아이디어를 구현하기 위해 오디오 팀이 힘을 발휘했습니다.
저희는 CG 팀에게 스태틱 미학 렌더를 만들도록 요청했습니다. 그런 다음, 생물 발광 나무 등 해당 이미지의 다양한 채널을 모든 맵에 연결하여 실행했습니다. UI/UX 팀이 UV 카드를 생성했고, 이 카드에 이미지를 매핑했습니다.
UI/UX 팀은 이러한 채널을 사용하여 강도와 색상의 베리에이션을 구현했고 이를 쿼츠 클럭에 연결했습니다. 그런 다음, 각 비트의 진폭을 트리거하는 강도 곱셈 값을 구했습니다.
기본적으로, 이는 카드에 매핑된 CG 이미지였으며, 채널은 해당 이미지 내 다양한 마스크 엘리먼트를 나타내도록 실행되었습니다.
그 후에는 색상과 강도를 어떻게 변경할지, 또는 카드 바로 다음에 펄린 노이즈나 프로시저널 노이즈를 수학 함수로 이용하여 파동이나 모션을 어떻게 변경하면 좋을지 정의했습니다.
개발자를 위한 흥미로운 기능
이 프로젝트에는 개발자가 주목할 만한 멋진 요소가 많습니다. 리얼타임 워크플로에 블렌딩된 기존의 필름메이킹이 그 한 가지 예시입니다.
이미시브 마스크든, 텍스처 마스크든, 포그 볼륨 패스든 대상에 관계없이 AOV 렌더링 또는 보조 출력과 같은 예전의 필름메이킹 방식을 사용했습니다.
이런 추가적인 패스와 함께 미학을 달성하는 것이죠. 일반적으로, 컴포짓한 다음 오프라인에서 렌더링하면 또 다른 하나의 스태틱 이미지를 얻게 됩니다. 이를 사이에 끼우고 다시 압축하면 이미지를 실제로 볼 수 있게 되죠.
이건 그런 식으로 작동하지 않습니다. 모든 출력을 가지고 리얼타임 컨텍스트에서 카드로 다시 전송한 다음, 카메라를 통해 실시간으로 캡처하는 것입니다. 그리고 해당 카드에서 모든 보조 출력을 다시 컴포짓한 후 수학을 적용하고 이러한 마스크를 이용하여 변경하는 것이죠.
쿼츠 클럭은 또한 이러한 마스크에 연결되고, 이를 변경하고, 카메라로 캡처된 마스크를 실시간으로 진동하게 합니다. 이 과정이 끝나면 화면 공간에 다시 뷰어로 표시됩니다. 정말 혁신적인 방식입니다. 기존에 존재하는 다양한 요소를 가져다 전위적으로 활용한 것입니다.
UI 및 셰이더
안녕하세요. 저는 포트나이트 프로젝트에 참여한 에픽게임즈의 시니어 UI 아티스트 마르셀 스와네포엘(Marcel Swanepoel)입니다. 포트나이트 챕터 3 시즌 3의 시작을 알리는 화면의 UI와 UI 머티리얼에 대해 소개하겠습니다.
저희는 이 기능의 개발 사이클을 시작하면서 필요한 UI 기술 요건을 먼저 살펴보았습니다. 여기서의 목표는 다이내믹 오디오 입력을 가져다 최종 비주얼 출력 제어에 사용하기 위한 기능을 갖춘 시스템을 만드는 것이었습니다. 이와 더불어, 로딩 화면에 사용할 수 있을 정도로 시스템을 민첩하게 유지해야 했습니다.
최종 시스템의 경우, 블루프린트부터 머티리얼 파라미터 컬렉션(Material Parameter Collection, MPC)에 이르는 오디오를 출력하기로 결정했습니다. 이는 최종 비주얼 제작에 사용되는 2D FX와 다양한 렌더 패스에 영향을 주는 데 사용하는 UI 머티리얼로 이 데이터를 가져오는 데 필요한 다이내믹 입력 역할을 합니다. 그런 다음 이 UI 머티리얼은 언리얼 모션 그래픽(Unreal Motion Graphics, UMG)을 사용하여 텍스트, 타이머와 같은 UI 엘리먼트를 추가하는 로딩 화면의 위젯 블루프린트에 참조됩니다.
UI 머티리얼은 렌더 팀이 제공한 여러 렌더 패스를 리컴포짓해야 하기 때문에 복잡성 측면의 경계를 설정합니다. 다양한 패스 분류는 색상 패스부터 시작합니다. 색상 패스는 완전히 렌더링된 이미지로, 빛나는 폴리지, 강, 보케가 모두 꺼져 있습니다. 또한 이러한 엘리먼트의 리플렉션과 반사광은 모두 비활성화되어 있습니다. 그 결과, 음악이 시작되기 전 화면이 시작될 때 로딩 화면의 첫 스태틱 샷이 됩니다.
RGB 값의 전체 범위를 전달해야 하기 때문에 다양한 텍스처 패스에 폴리지 이미시브를 도입합니다. 이렇게 하면 오디오로부터 오는 여러 시간 간격에 트리거되는 폴리지 그룹을 생성할 수 있습니다. 이를 통해 모든 이미시브 폴리지에 더 다양한 베리에이션을 도입할 수 있습니다.
전체 이미지에서 집중적으로 사용한 또 다른 중요 패스는 Z 뎁스입니다. 이는 씬 뎁스에서 폴리지 이미시브의 강도를 제어하고 억제하는 데 도움이 됩니다. 씬의 폴리지 위치에서 뒤로 갈수록 강도가 낮아집니다. 여기서 이런 질문이 생각날 수 있습니다. 왜 폴리지 패스 자체에서 씬 뎁스와 강도를 렌더링하지 않을까요? 폴리지 이미시브 범위를 0~1로 유지하는 것을 선호하기 때문입니다. 이를 통해 이펙트를 향상시키고, 패스를 모두 리컴포짓한 이후 전체 씬의 균형을 더욱 효과적으로 유지할 수 있습니다. 즉, 최종 출력과 균형을 더욱 제어할 수 있게 됩니다.
또한, Z 뎁스는 렌더 패스를 전경과 배경 그룹으로 나눠 폴리지 이미시브의 범위를 더욱 확장할 수 있게 해줍니다. 이미시브 패스 중 하나의 렌더링된 단일 텍스처를 가져와 자연스럽게 느껴지는 화면상의 장소에 Z 뎁스를 배치한 다음, 범위가 제한된 Z 뎁스를 마스크로 사용하여 두 개의 이미시브 출력을 갖습니다.
그런 다음 전경과 배경을 다른 오디오 출력에 매핑하면 배경 사이클이 전경보다 더 빠르거나 느리게 진행되도록 할 수 있습니다. 또는, 전체 이미시브 패스를 단일 오디오 출력에 매핑하여 사이클이 전체 씬에서 균일하게 진행되도록 할 수도 있습니다. 하지만 베리에이션을 늘리고 싶으므로 이는 적절하지 않습니다. Z 뎁스를 사용하여 이미시브를 분할하면, 단일 폴리지 이미시브 패스에서 얻는 베리에이션의 양을 두 배로 늘리고 원하는 결과를 얻을 수 있습니다.
굽어 흐르는 강에 줄무늬 이펙트를 생성하여 연출한 방법을 살펴보면 Z 뎁스 패스에 얼마나 많이 의존하고 있는지 다시 한번 알 수 있습니다. 이 무늬는 커스텀 UV의 V 채널을 가로질러 패닝하는 채널로 가득 찬 디스턴스 필드입니다.
무늬가 씬을 가로지를 때 Z 뎁스를 사용하여 디스턴스 필드의 범위를 제한하면, 초점이 맞지 않아 흐릿한 배경에서 초점이 맞은 전경으로 무늬가 움직이는 것과 같은 착시 효과가 발생합니다. 이와 더불어 Z 뎁스로 씬을 가로지르는 무늬의 강도를 조절합니다. 커스텀 UV는 강의 윤곽을 따라 생성되므로, 이를 0~1 범위로 매핑하여 무늬가 이를 적절히 따라 가도록 연출할 수 있습니다. 오디오 입력을 사용하여 무늬의 강도와 표시되는 수를 조절합니다.
씬을 완성하기 위해 보케와 라이트 레이를 사용하여 애트머스페릭을 추가했습니다. 이는 모두 Z 뎁스에 의존하여 씬에 블렌딩하고 영역을 적절히 마스킹합니다. 보케 효과는 모션, 사이즈, 원형을 이루는 부호화된 디스턴스 필드(Signed Distance Field, SDF)의 오파시티를 구동하기 위해 무작위 노이즈 함수를 사용하여 만들어졌습니다. 라이트 레이 마스크는 렌더 팀이 제공한 또 다른 패스였으며, 저희는 이를 Z 뎁스와 커스텀 UV 마스크와 함께 채널에 쌓았습니다. 채널 패킹은 최대 3개의 그레이스케일 텍스처를 하나의 RGB 텍스처 에셋에 통합할 수 있는 이상적인 방법입니다. 각 색상 채널은 별개의 그레이스케일 텍스처 값을 보유하기 때문에 머티리얼에서 별도의 채널을 한 번에 추출할 수 있습니다. 이는 최적화 게인에 아주 좋습니다.
최초의 씬에 부여된 값을 범위 내로 유지하고 true 상태를 보장하기 위해 렌더 팀과 긴밀히 협력하여 머티리얼과 텍스처의 균형을 최종적으로 맞추고 조정했습니다.
성공 기준을 충족하는 통합 시스템을 구축하겠다는 저희의 목표는 UI 머티리얼을 활용하지 않고서는 불가능했습니다. 저희 팀의 진정한 문제는 오디오 입력을 유의미하고 역동적인 비주얼 경험으로 전환하는 방법을 찾는 것이었습니다.
개인적으로, UI 머티리얼 파이프라인이 UMG에 가져다준 유연성은 간과할 수 없는 요소라고 생각합니다. 놀라울 정도로 강력하고 다재다능한 이 기능을 UI 개발에 광범위하게 사용할 수 있었는데 지난 5년 동안 최고의 경험이었습니다.
지금 언리얼 엔진을 다운로드하세요!
세계에서 가장 개방적이고 진보된 창작 툴을 받아보세요.
모든 기능과 무료 소스 코드 액세스를 제공하는 언리얼 엔진은 제작에 바로 사용할 수 있습니다.