1학기 게임엔진1 수업을 들으면서, LandScape과 Foliage 에 대해 배우면서
교수님께서 PCG 라는 것에 대해 알아보길 권하셨다.
당시 유튜브 알고리즘을 통해 아래 영상을 보기도 했으며, Foliage도 신기했는데 그보다 상위의 5.2버전에 새로 나온 시스템은 어떤 것일까 하며 관심을 가지게 되었고, 배워두고 싶어 찾아보게 되었다.
https://www.youtube.com/watch?v=aoCGLW53fZg
Game Developers Conference(GDC) 2023에서 언리얼엔진 5.2버전의 기능으로 설명된 영상이다.
랜드스케이프만 되어있는 지형에 암석이 생성되고, 숲을 생성하는 등의 메시를 생성하는 과정 뿐만 아니라
사용을 하기 위해선

다음과 같이 플러그인이 설정되어 있어야 한다.

다음과 같이 PCG Volume을 생성할 수 있고,


PCG Volume의 디테일 패널에서 Graph를 검색해 나오는 Instance에 PCG Graph를 생성해 연결해 줄 수 있다.
생성된 PCG Volume을 살펴보면

다음과 같이 Input Type이 있는데, 랜드스케이프로 설정한 뒤,

간단한 랜드스케이프를 만들고 크기를 조정해줬다.
PCG Graph를 열면,

다음과 같이 Input 노드를 시작으로 있는데,
인풋 데이터를 샘플링하면 포인트 데이터가 나오는데, 쉽게 공간의 트랜스폼 데이터라던가 추가적인 데이터를 담아 관리할 수 있다고 한다.
*샘플링(Sampling): 어떤 자료에서 일부 값을 추출하는 것 (https://ko.wikipedia.org/wiki/%EC%83%98%ED%94%8C%EB%A7%81)
Surface Sampler 노드를 연결해준다.
Surface Sampler노드의 설정창을 보면

Debug 패널이 있는데,
여기서 Debug를 활성화하거나 혹은 Surface Sampler 노드를 누른채 'D'를 누르면 디버그가 된다.

다음으로 Generate 를 누르면,

해당 PCG 볼륨이 겹쳐지는 랜드스케이프 범위 내에서 다음과 같이 Point Mesh로 설정된 PCG_Cube가 생성된 것을 볼 수 있다. 또한 랜드스케이프의 굴곡에 맞춰 배치된 것도 확인할 수 있다.

또한 PCG Graph의 Seed 값을 변경해보면 그에 맞게 Point의 위치가 달라지는 걸 확인할 수 있다.
다음으로 다른 속성인 Points Per Squared Meter, Point Extents, Looseness에 대해 살펴보자면,
이 세개는 서로 유기적인 관계인데
먼저 Point Extents 는 각 포인트의 바운드 크기를 제어하는 역할로,


다음과 같이 한 포인트당 크기가 줄어든 것을 확인할 수 있다.
그 다음으로 Points Per Squared Meter인데,


제곱미터당 포인트 갯수라서 간단히 밀도정도로 생각하면 될 것 같다.
또한 이 수치는 최대치가 있어서 세 값이 유기적으로 적용되며 최대치도 있어서 어느정도 수치 이후부턴 변경이 되지 않을 수 있다.
다음으로 Looseness는 간단히 말해 랜덤성을 나타내주는데,



밀집도랑은 조금 다른것이, 이 Point들은 정사각형 배치를 기준으로 배치되기에, 0.0을 기준으로 보면 그리드 방식이 뚜렷하게 보이는데, 이에 랜덤화를 추가하기 위한 값이라고한다.
3.0의 수치를 보면 포인트간의 간격이 늘고, 띄엄띄엄 있어 정해진 느낌이 들지 않아 좀 더 보기 좋은 것을 확인할 수 있다.
또한 PCG_Cube로 보이는 메시는 단순한 메시가 아니라 가시적으로 바운더리를 보여주는 역할이라고 하며,
해당 바운더리들이 겹치는 경우에 대해서 판단할 수 있어서 Procedural Generation을 할 때 아주 좋다고 한다.
(나무 안에 암석이 스폰되거나 등을 방지)

다음으로 Density Filter 노드를 활용하면 어느정도 밀집도를 조절할 수 있다.


다음과 같이 일부 포인트들이 없어졌으며, Lower/Upper Bound 의 값을 조정해보면 더욱 세밀하게 변경할 수 있다.
또한 현재 디버그 창을 보면 알 수 있듯이, 중간 사이의 과정 또한 디버그를 통해 확인할 수 있고
실시간으로 실행되어 적절한 값을 찾기 아주 좋다.

다음으로는 Transform Points 노드인데, 해당 포인트에 랜덤한 Location, Rotation, Scale을 주는 과정이다.


우측은 랜덤회전(0~360) , 랜덤스케일(0.5~2.0)의 값을 준 실행결과이다.
딱 봐도 더 자연스럽고 정밀한 표현이 가능해졌다.
또한 Foliage를 배우면서도 확인해야 했던 점이, 해당 Point들 또한 랜드스케이프의 법선벡터에 의해 회전이 정해지는데,
경사진 곳의 나무라도 위로 곧게 자라야하기에 이를 위해서 절대 회전(Absoulute Rotation) 또한 제공한다.
이렇게 포인트를 생성했으면, 이제 해당 포인트에 렌더링을 시작할 수 있는데,

Static Mesh Spawner 노드를 연결해주고,

스폰할 스태틱 메시를 연결해주면,


다음과 같이 Point 위치에 해당 스태틱 메시가 생성된 걸 볼 수 있고,


한개뿐만 아니라 여러개의 스태틱 메시를 소환할 수도 있다.
(준비된 에셋이 없어 최대한 나무같은 Starter Content의 기둥을 사용했다! )
또한 현재 기둥(나무) 가 너무 많아서 불편하다면

Mesh Selector Type의 옵션에서 직접 빌드함으로써 원하는 옵션으로 선택하거나, 현재 디폴트로 되어있는 PCGMeshSelectorWeighted를 활용한다면,


다음과 같이 Weight를 조정해주면 해당 비율로 메시들이 생성된다.


디버그 기능(D) 뿐만 아니라 Point Data(A) 를 확인할 수 있는 기능도 있으며,
해당 포인트를 더블클릭 하면 에디터 상에서 해당 포인트에 대해 포커싱 되어 매우 편한 기능인 것 같다.


그리고 해당 볼륨에서, 수풀과 다르게 나무는 지면의 법선벡터와 같은 방향이 아니라 곧게 하고 싶어 방법을 찾아보니,

다음과 같이 Out 결과를 또 분할 할 수 있었다.
Out의 포인트 결과들을 나누어 Transform Points로 한쪽은 Absolute Rotation을 활성화, 한쪽은 안하고서
나무와 수풀을 연결해주면 원하는 결과를 얻을 수 있었다.

그리고 Transform Points를 하면서 z축 값으로 올려버렸을 때, 지면과 멀어진 것에 어색함이 느껴졌었는데,


Projection이라는 노드를 통해 결과값들을 Landscape에 붙여줄 수 있는 것을 확인했다.
아직 활용방안을 모두 살펴보진 않았지만, 액터의 특정한 면에도 붙이거나 하는 등의 역할도 가능하지 않을까 싶다.
사실 일부는 Foliage를 하면서 경험해본 것들이긴 하지만,
더욱 "실시간"으로, 정밀하게 표현할 수 있었으며 또한 이 데이터들이 자동으로 관리되고 정렬돼서 스트리밍이 훨씬 더 쉬워진다고 하니 여러모로 장점이 많은 기능인 것 같다.
또한 눈과같은 지형적 메시 데이터라던가 강을 나타내는 Spline Line을 따라서 PCG를 생성하는 등
유동적이면서 관리하기 쉬운 형태로 접근할 수 있게 하는 것 같다.
앞으로 해당 PCG를 활용한 기술들을 배워봄으로써, 조금 더 비쥬얼적으로 성능적으로 좋은 광경을 만들어 나가볼 예정이다.
PCG의 개념에 대한 부분은
해당 링크에서 잘 설명해준 것 같아 읽어보면 좋을것 같다.
'Unreal5 > 절차적 콘텐츠 생성(PCG)' 카테고리의 다른 글
| PCG(5) - 정글 바이옴 PCG 만들기 (0) | 2023.09.03 |
|---|---|
| PCG(5) - Custom Node (0) | 2023.08.31 |
| PCG(4) - Actor에 PCG 컴퍼넌트 붙이기 / Static Mesh에서 포인트 만들기 (0) | 2023.08.31 |
| PCG(2) - Spline(숲 / 길) (0) | 2023.08.30 |
| PCG(1) - 시작 (0) | 2023.08.29 |