목표
언리얼에서 런타임에 Skeletal Mesh에 직접 페인팅하거나, 텍스처를 입힌다.
작업중 겪었던 문제들은 아래와 같다.
- 스태틱 메시의 경우에는 일반적으로 Find Collision UV 노드를 사용하는 것 같은데(프로젝트 셋팅의 Support UV From Hit Result를 켜야 작동한다), 스켈레탈 메시의 경우 이 노드로는 Collision 된 위치의 UV 정보를 얻어울 수 없다.
https://forums.unrealengine.com/t/find-collision-uv-always-returns-zero-for-skeletal-meshes/378548
링크에서 볼 수 있듯 "broken as intended"이다.
다행히도 Ryan 아저씨가 제시한 솔루션이 있는데, 이것을 활용한 방법이 아래 링크에 자세히 나와 있다.
https://www.kodeco.com/6817-dynamic-mesh-painting-in-unreal-engine-4
이 방법을 참고해서 조금 응용해 보았다.
Unwrap Material
World Position Offset 노드에 아래와 같은 노드를 작성하면, 월드 공간에서 메시의 UV를 직접 펼칠 수 있다.
예제에서는 HitPosition을 중심으로 SphereMask 영역을 칠하는데, 나는 HitPosition을 중심으로 UV를 펼쳐 텍스처를 투영해 보았다.
월드상의 위치와 방향으로 UV 이동 및 회전하기
블루프린트에서 마우스 Hit 위치를 받아서 이 위치까지 메시의 Local Position을 offset 시켜주었고, 마우스 Hit Normal과 Actor Rotation를 비교했을 때, 벡터 간 각도 theta를 머터리얼로 넘겨 Local Position을 회전시켜 주었다.
XY, XZ 평면상의 theta를 구해서 각각 파라미터로 넘겨주었다.
이 각도는 0 ~ 360 도 사이로 맵핑되었는데, 각각 Local Position X축 ~ Y축, 또는 -X축 ~ -Y축 중 어느 축을 UV로 사용할 지를 블렌딩하는 값으로 사용하였다.
이렇게 이동 및 회전된 좌표에서 UV 위치를 만들었다. 아래 영상은 이렇게 만든 UV 방향을 시각화 해본 것이다.
R, G, B Arrow는 각각 Hit Normal의 X, Y, Z를 나타낸다.
(정확히는 Y 벡터만 얻어오고, 나머지는 외적 계산으로 얻은 결과이다)
렌더 타겟으로 캡쳐하기
텍스처의 UV 좌표를 얻었으면 위에서 본 예제처럼 메시를 Unwrap해서 렌더타겟으로 캡쳐한다. 캡쳐한 렌더타겟의 BaseColor, Alpha 를 얻어와 기존 값들과 섞어주었다.
렌더타겟의 해상도가 기존 메시가 가지고 있던 해상도보다 작으면, 이미지 해상도가 상대적으로 낮은 게 눈에 띄게 된다.
캡쳐된 영상은 렌더타겟 해상도 2048이다.
렌더타겟이 머터리얼 1개당 1장씩 필요하기 때문에, 실제 인게임에 사용하려면 텍스처 최적화 방안이 필요하다.
'Unreal Engine' 카테고리의 다른 글
UE5에서 투명한 바닥에 반사 표현하기 (0) | 2023.02.27 |
---|---|
Glitter Material (반짝이는 글리터 재질) (0) | 2023.02.12 |
Unreal에서의 Metallic 표현 (0) | 2022.12.18 |
언리얼 엔진에서는 노멀맵을 어떻게 구분할까? (0) | 2022.08.29 |
Part 6 : 새로운 셰이딩 모델을 추가하기 (Adding a new Shading Model) (0) | 2020.05.09 |