해피 하베스트 데모의 조명과 그림자가 Unity 2022 LTS의 유니버설 렌더 파이프라인 (URP)을 사용하여 어떻게 제작되었는지 알아보세요.
해피 하베스트는 샘플 2D 하향식 농업 시뮬레이션 게임입니다. 이 글에 소개된 기법을 비롯한 더 많은 기법은 전자책에서 자세히 다룹니다. 아티스트를 위한 2D 게임 아트, 애니메이션 및 라이팅.
이 시리즈의 다른 글을 읽고 해피 하베스트의 효과와 비주얼을 재현하는 방법을 알아보세요:
- Unity 2022 LTS에서 2D 캐릭터 애니메이션을 만드는 방법
- 2D 타일맵으로 아트와 게임플레이를 제작하는 방법
- VFX 그래프 및 셰이더 그래프를 사용한 2D 특수 효과(곧 제공 예정)
다이내믹 2D 라이팅은 레벨의 분위기를 극적으로 바꾸고 게임플레이를 향상시킬 수 있습니다. 예를 들어 동굴에 횃불을 비추고, 창문을 통해 빛을 비춰 반짝이는 먼지 티끌을 강조하고, 해피 하베스트의 경우 낮과 밤의 주기를 시뮬레이션하는 애니메이션을 만들 수 있습니다.
유니티의 고급 2D 다이내믹 라이팅 시스템과 스프라이트의 보조 텍스처를 사용하면 효과적인 테두리 조명과 선명한 음영 디테일로 캐릭터를 돋보이게 만들 수 있습니다.
2D 라이트는 라이트 2D 컴포넌트가 부착된 게임 오브젝트입니다. 스프라이트 렌더러, 스프라이트 셰이프 렌더러 및 타일맵 렌더러와 함께 작동합니다. 또한 정렬 레이어를 사용하며 각 조명은 하나 이상의 레이어에 영향을 줄 수 있습니다. 대상 정렬 레이어 드롭다운 목록에서 영향을 받을 레이어를 선택할 수 있습니다.
2D 조명에는 네 가지 유형이 있습니다:
자유 형식: n면 다각형과 같은 모양을 만들 수 있습니다. 이 유형의 조명은 오가닉 또는 스타일라이즈드 환경이 아닌 곳에서 사용할 수 있습니다. 용암 웅덩이와 같이 환경의 넓은 부분을 효율적으로 조명하거나, 천장 구멍을 통해 들어오는 신의 광선처럼 빛의 모양을 시뮬레이션하거나, 빛이 투사되는 창문의 모양을 따르는 데 적합합니다.
Sprite: 이 모양을 사용하면 모든 스프라이트를 라이트의 텍스처로 사용할 수 있습니다. 이 기능은 다른 조명 유형으로는 구현할 수 없는 특정 모양을 원할 때 유용합니다. 가능한 텍스처의 예로는 렌즈 플레어, 눈부심, 라이트 쿠키, 디스코 볼 조명과 같은 빛의 모양 투영 또는 벽에 별을 투영하는 램프 등이 있습니다.
Spot: 이 표시등은 원 또는 원 섹터일 수 있습니다. 스포트라이트용 또는 토치 불, 양초, 자동차 조명, 손전등, 볼류메트릭 조명 등으로 특정 지점을 비추는 데 사용됩니다.
전 세계: 이 조명은 모양이 없는 대신 대상 정렬 레이어에 있는 모든 개체에 불을 켭니다. 블렌드 스타일(라이트와 스프라이트 간의 상호작용 방식)과 소팅 레이어당 하나의 글로벌 라이트만 사용할 수 있습니다. 먼저 기본 환경 조명을 추가하는 데 사용합니다.
이러한 설정은 각 조명 유형에 대해 사용할 수 있습니다:
블렌드 스타일: 블렌드 스타일은 특정 라이트가 씬의 스프라이트와 상호작용하는 방식을 결정합니다. 씬의 모든 조명에는 사용 가능한 네 가지 블렌드 스타일 또는 모드 중 하나가 있어야 합니다: 더하기, 변조, 빼기 및 사용자 지정. 각 모드는 스프라이트에 조명을 비추는 방식을 제어합니다.
라이트 오더 및 오버랩 연산: 이를 통해 여러 개의 조명이 동일한 픽셀에 영향을 미칠 때 발생하는 상황을 제어할 수 있습니다.
그림자: 이 옵션을 활성화하면 그림자 캐스터가 있는 게임 오브젝트가 이 광원에서 그림자를 드리웁니다.
볼류메트릭: 이를 통해 투사된 그림자의 명암 감쇠를 제어할 수 있습니다.
노멀 맵: 활성화하면 스프라이트의 노멀 맵 정보를 사용하여 픽셀 방향에 따라 빛의 양을 계산합니다.
스프라이트 에디터 > 보조 텍스처를 통해 2D 프로젝트의 모든 스프라이트 에셋에 선택적 보조 텍스처를 할당할 수 있습니다. 보조 텍스처에는 두 가지 유형이 있습니다: 노멀 맵 및 마스크 맵. 해피 하베스트에서는 캐릭터부터 타일맵과 소품까지 모든 요소에 노멀과 마스크 맵을 사용하여 고품질의 실시간 조명과 그림자 효과를 만들 수 있습니다.
노멀 맵
해피 하베스트 전체에 걸쳐 라이트와 노멀 맵을 사용하여 볼륨감을 살리고 데모에 독특한 룩앤필을 부여했습니다. 스폿, 포인트 및 자유형 조명과 함께 노멀 맵을 사용할 수 있습니다.
노멀 맵을 만드는 방식에 따라 스프라이트가 3D라는 착각을 불러일으키거나 깨뜨릴 수 있습니다. 노멀 맵의 모든 픽셀은 메인 텍스처의 각도에 대한 데이터를 저장합니다. 빨간색, 녹색, 파란색(RGB) 채널은 X, Y, Z 좌표에 대한 각도 데이터를 저장합니다. 노멀 맵을 사용하는 모든 조명에는 방향이 있으며, 노멀 맵이 있는 텍스처의 픽셀은 픽셀의 방향뿐만 아니라 이 방향에 따라 음영 처리됩니다. 픽셀이 빛의 방향을 향하고 있으면 조명이 켜지고, 반대쪽을 향하고 있으면 빛을 받지 못하는 실제 빛의 작동 방식을 모방한 것입니다.
마스크 맵
마스크는 라이트가 스프라이트에 영향을 줄 수 있는 위치를 제어합니다. 마스크 채널로 선택할 수 있는 채널은 4개입니다: 빨간색, 파란색, 녹색 및 알파. 마스크 최대값은 전체 조명을 의미하고 최소값은 조명이 없음을 의미합니다.
마스크 맵은 비주얼에 디테일을 추가하여 게임을 완성하는 데 도움이 됩니다. 2D 라이트 블렌드 스타일에서도 사용됩니다.
블렌드 스타일은 주어진 픽셀에서 라이트의 값을 가져와 같은 픽셀의 마스크에 해당 값을 곱합니다. 그런 다음 선택한 블렌드 스타일에 따라 결과 마스크된 조명 값을 해당 픽셀의 색상에 더하거나 빼거나 곱합니다.
림 조명에 사용되는 마스크 맵
가독성을 위해 캐릭터가 움직일 때 실루엣 주위에 테두리 조명을 비추는 경우가 많습니다. 테두리 조명은 캐릭터의 윤곽을 강조하는 데 사용되는 효과입니다. 물체 뒤에서 들어오는 빛과 빛의 자연스러운 산란 특성을 시뮬레이션합니다. 이를 프레넬 효과라고도 합니다. 횡스크롤 2D 게임에서 지면과 배경은 캐릭터의 실루엣을 증폭시키는 데 도움이 될 수 있습니다. 하향식 게임에서는 실루엣이 환경에 더 많이 포함되므로 선명한 테두리 조명을 통해 모양을 구분하는 것이 좋습니다.
해피 하베스트의 주인공과 소품에는 테두리 조명 효과를 위한 마스크 맵이 포함되어 있습니다. 주인공의 경우 조명 영역은 R 채널에, 소품은 G 채널에 그립니다. 그 이유는 캐릭터의 실루엣을 일반 소품과 다르게 조명하기 위해서입니다(블렌드 스타일 채널에서 R 채널에만 영향을 주는 다른 조명 세트 사용).
노멀 맵은 Unity에서 노멀 맵으로, 마스크 맵은 텍스처 유형 기본값으로 임포트해야 한다는 점을 기억하세요. 이렇게 하면 스프라이트 아틀라스로 텍스처를 패킹할 때 각 텍스처가 올바른 아틀라스에만 패킹되어 중복을 방지할 수 있습니다.
이미 그림자가 칠해진 스프라이트에는 2D 조명이 좋지 않습니다. 또한 노멀 맵에서 라이팅을 '페인팅'하게 되므로 작업량이 두 배로 늘어나게 됩니다. 대신 방향성이 없는 그림자를 그리면 햇빛과 같은 방향성 빛을 피하는 한 스프라이트가 더 멋지게 보입니다.
모든 스프라이트, 타일 또는 스프라이트 모양에 대한 노멀 맵을 만드는 데는 시간이 많이 걸릴 수 있습니다. 생성에 다양한 기술을 결합하고, 정말 중요한 수작업에 시간을 투자하고, 배경 소품은 프로세스를 자동화하는 것을 고려하세요. Blender 또는 3ds Max와 같은 3D 모델링 소프트웨어에서 2D 스프라이트를 생성하는 경우 이 텍스처를 쉽게 생성할 수 있습니다.
몇 가지 예를 살펴보겠습니다:
- 기존 노멀 맵을 모핑하여 현재 2D 개체에 맞게 조정합니다. 예를 들어 반지나 보석은 이미지의 샘플 노멀 맵을 사용할 수 있습니다.
- 스프라이트일루미네이터, 노멀페인터, 크리타의 탄젠트 노멀 브러시, 레이그터 같은 노멀 맵 생성 도구를 사용하세요.
- 생성기 앱은 스프라이트의 각도를 고려하지 않으므로 전체 스프라이트에 사용하지 마세요. 또한 사물을 인식하지 못합니다. 대신 스프라이트 색상이나 이미지 편집 앱의 베벨 또는 엠보스와 유사한 일반 필터를 추가하여 모양을 추정합니다.
- 얼굴의 각도는 인식하지 못하지만 각도의 변화가 있어야 하는 위치를 추측하려고 시도합니다. 이러한 제한에도 불구하고 사슬, 케이블 또는 용의 꼬리처럼 경사진 스프라이트 섹션의 노멀 맵과 벽돌, 돌, 나무 등의 표면 노멀을 생성하는 데 여전히 유용합니다.
- Unity는 그레이 스케일 하이트맵에서 노멀 맵을 생성하는 방법을 제공합니다. 검은색은 최소 표면 높이를, 흰색은 최대 높이를 나타내는 텍스처입니다. 이미지를 노멀 맵으로 가져온 후 회색조로 만들기 옵션을 선택합니다. 이 기술은 엔진을 종료하지 않고도 노멀 맵을 빠르게 생성하는 데 유용합니다.
- 샘플 이미지에서 색상을 샘플링합니다. 먼저 노멀 맵 팔레트(온라인에서 찾을 수 있음)를 가져와 표면 각도를 표현하는 데 사용되는 색상을 샘플링할 수 있습니다. 팔레트를 즐겨 사용하는 페인팅 앱에 복사하고 색상 선택기를 사용하여 노멀 맵에 칠할 색상을 선택하기만 하면 됩니다.
- 각도 색상이 100% 정확할 필요는 없습니다. 그러나 스프라이트의 전체적인 모양을 사실적으로 유지해야 합니다. 문맥에 맞지 않는 각도 색상을 사용하면 조명을 비추면 모양이 무너집니다.
- 노멀 맵을 그리는 것은 공간적 상상력이 필요하기 때문에 처음에는 까다로울 수 있습니다. 머리의 기본 평면과 같은 간단한 것부터 시작해보세요. 여기에 사용된 예제는 로우 폴리로 단순화된 사람 머리 모델입니다.
- 노멀 맵을 그릴 때는 스프라이트의 일부인 기본 3D 모양을 상상한 다음 각 개별 부분의 각도를 시각화해 보세요. 각도를 알면 팔레트 스프라이트의 어느 부분에서 색상을 샘플링할지 알 수 있습니다.
- 여기에 표시된 예제 이미지는 평평한 표면에서 작업한 것이지만, 부드러운 브러시로 페인팅하는 과정도 비슷합니다. 딱딱한 가장자리를 블렌딩하여 보다 자연스러운 모양을 만들 수 있습니다.
- RGB 채널당 하나씩 세 가지 각도에서 오브젝트의 빛과 그림자를 수동으로 칠하고 색상 채널을 결합합니다. 상단에서 들어오는 빛은 G 채널을, 오른쪽에서 들어오는 빛은 R 채널을, 중앙에서 들어오는 빛은 B 채널을 사용해야 합니다. B 채널은 선택 사항이므로 작업량을 줄이면서도 사실적인 룩을 구현할 수 있습니다.
글로벌 라이트는 전체 씬에 영향을 미치므로 분위기를 쉽게 바꿀 수 있습니다. 데모(앰비언트 라이트라는 게임 오브젝트)에서는 일반적인 색조를 적용하고 어두운 영역을 피하는 데 사용됩니다.
2D 글로벌 라이트는 모든 새 씬에 기본적으로 추가됩니다. 장면에 균일한 색조를 적용하기 위해 흰색을 사용하거나 색상, 강도 또는 영향을 받는 레이어를 변경할 필요는 없습니다.
씬에는 글로벌 라이트가 하나만 있어야 합니다. 파라미터를 조작하여 강도를 낮추고 장면에 보라색 색조를 적용하여 야간과 같은 다양한 환경 조건을 쉽게 시뮬레이션할 수 있습니다. 데모에서 색상은 하루 중 시간에 따라 변경되며, 이는 나중에 설명하는 DayCycleHandler 스크립트로 관리되는 효과입니다.
해피하베스트에서는 대형 스포트라이트가 키 조명으로 사용됩니다. 카메라에 부착되어 있어 항상 화면에 표시되며 태양의 움직임을 시뮬레이션하는 스크립트에 따라 회전합니다.
2D 씬에는 3D 씬처럼 방향 조명이 없습니다. 그러나 X 및 Y 위치에서 스프라이트를 비추는 광원을 사용할 수 있습니다. 이를 통해 하루가 진행됨에 따라 태양이 움직이는 것과 같은 효과를 만들 수 있으며, 이는 탑다운 및 시뮬레이션 게임에서 중요할 수 있습니다. 또한 저사양 플랫폼을 타겟팅하는 경우 대형 조명을 사용하면 비용이 발생한다는 점에 유의할 필요가 있습니다. 이 글의 마지막에 있는 성능 팁 섹션을 확인하세요.
데모에서 4개의 조명이 연결된 LightsRotator라는 이름의 하위 게임 오브젝트를 찾습니다:
NightLight: 달빛 방향 시뮬레이션
DayLight: 햇빛 방향 시뮬레이션(야간 조명과 반대 위치)
NightLightRim: 나이트라이트 달 방향 조명과 유사하지만 캐릭터 및 소품 테두리 조명에만 적용됩니다.
DayLightRim: DayLight 햇빛 방향 조명과 유사하지만 캐릭터 및 소품 테두리 조명에만 적용됩니다.
이러한 조명의 움직임을 제어하는 스크립트는 하루 동안의 색상 변화도 제어합니다. 그라데이션은 특정 시간에 각 조명의 색상을 선택합니다. 이러한 그라데이션은 DayCycleHandler 게임 오브젝트에 첨부된 DayCycleHandler 스크립트에서 확인할 수 있습니다.
해피 하베스트의 모든 곳에 라이트와 노멀 맵이 사용되어 볼륨감이 느껴지는 효과를 연출합니다. 스폿, 포인트 및 자유형 조명과 함께 노멀 맵을 사용할 수 있습니다. 라이트 오브젝트에서 노멀 맵을 활성화해야 스프라이트에서 사용할 수 있다는 점을 기억하세요. 두 가지 품질 설정을 사용할 수 있습니다: 빠르고 정확합니다.
노멀 맵이 활성화된 경우 부시가 라이트 위치에 따라 볼륨을 시뮬레이션하는 방식을 확인할 수 있습니다. 가로등과 기타 소품이 관심 지역을 비추고 플레이어가 길을 탐색할 수 있도록 도와줍니다.
2D 오브젝트는 섀도우 캐스터 2D 컴포넌트를 스프라이트나 애니메이션 캐릭터에 부착하여 무한한 그림자를 투사할 수 있습니다.
무한 그림자는 빛의 영역이 제한적이거나 가로등이나 벽난로처럼 강하고 집중된 광원이 있을 때 멋진 효과를 연출합니다.
라이트 오브젝트에서 노멀 맵을 활성화하여 스프라이트에서 해당 텍스처를 사용하고 그림자 옵션을 활성화하는 것을 잊지 마세요.
또한 캐릭터의 실루엣에 그림자가 투영되어서는 안 되는데, 이는 하향식 게임에서 비현실적으로 보일 수 있기 때문입니다. 섀도 캐스터 2D 컴포넌트는 캐릭터 게임 오브젝트 내부의 발 뼈에 붙어 있기 때문에 발에만 영향을 줍니다(시각 > Prefab_character_base > root_bone > ... > foot_r_bone 및 foot_l_bone).
하향식 게임에서 햇빛이 비추는 끝없는 그림자 투영은 이상하게 보일 수 있습니다. 해피 하베스트에 사용된 기법은 시간대에 따라 회전하고 늘어나는 나무와 덤불의 블롭 그림자를 사용하는 것입니다. 그 결과 아트 디렉션을 더 잘 따르는 부드러운 그림자가 만들어집니다.
스크립트의 UpdateShadow 함수는 이 그림자를 회전합니다. 다른 블롭 섀도와 마찬가지로 이 섀도는 스프라이트 기반 라이트입니다. 트리라는 부모 게임 오브젝트 내의 게임 오브젝트를 검사하면 이를 확인할 수 있습니다. 회전 핸들이라는 게임 오브젝트 안에서 ShadowLong이라는 하위 게임 오브젝트를 찾습니다. 섀도 인스턴스 스크립트는 업데이트섀도 스크립트에 RotationHandle을 추가합니다. 그런 다음 이 스크립트는 함수를 사용하여 그림자의 크기와 회전을 업데이트하는 관리자 역할을 합니다.
블롭 그림자는 광고판이나 나무처럼 작거나 평평한 물체에 잘 어울립니다. 그러나 깊이가 있고 형태가 뚜렷한 큰 건물은 정확한 그림자를 드리워야 합니다. 해피 하베스트에서는 프리폼 라이트가 이러한 그림자를 만듭니다. 2D에는 깊이 정보가 없기 때문에 건물이 지면에서 만들어내는 투영을 모방하여 근사치를 구합니다.
그림자를 잘 정의하는 데 있어 어려운 점은 낮과 밤의 주기에 따라 그림자가 작동하도록 만드는 것입니다. 그림자가 태양의 다양한 위치에 반응하도록 하기 위해 라이트 보간 스크립트는 서로 다른 기준 그림자 사이에서 프리폼 라이트의 벡터 포인트를 조정합니다.
데모의 계층 구조에서 Light_2D_Warehouse라는 게임 오브젝트를 찾습니다. 4개의 자유형 조명이 부착되어 태양이 위, 아래, 건물의 좌우에 비추는 그림자를 모방합니다. 이 스크립트는 API를 사용하여 서로 다른 벡터 포인트를 이동하는 부드러운 보간을 생성합니다.
상단 그림자를 먼저 만든 다음 수정하여 다른 그림자를 만듭니다. 각 그림자를 만들 때 각 그림자의 포인트 수가 같고 포인트 사이의 전환이 고려되는지 확인하는 것이 중요합니다.
그림자가 생성되면 하루 동안 각 그림자의 시간 가중치를 나타내는 정규화 파라미터를 사용하여 조명 보간기 컴포넌트 스크립트에 추가합니다. 스크립트의 미리보기 시간 기능을 사용하면 에디터에서 어떻게 보일지 미리 시각화할 수 있습니다.
DayCycleHandler 관리자는 낮과 밤의 주기를 조율하는 스크립트입니다. 몇 가지 기능을 자세히 살펴보겠습니다.
Lights Root라는 게임 오브젝트는 햇빛과 달빛을 시뮬레이션하기 위한 스포트 조명을 포함하는 부모입니다. DayCycleHandler 스크립트에 의해 회전됩니다.
나이트, 앰비언트 및 림 조명은 용도를 전달하기 위해 이름이 붙여졌습니다. 그라데이션은 각 조명이 적절한 분위기를 연출하기 위해 표시하는 색조를 말합니다.
하루 기간(초 ) 변수의 경우 낮의 기간을 초 단위로 정의하고 시작 시간을 설정할 수 있습니다. 테스트 시간에서는 에디터에서 다양한 시간대에 게임이 어떻게 보일지 미리 시각화할 수 있습니다.
유한 그림자 효과를 제어하는 매개 변수는 그림자 각도 및 그림자 길이입니다. 각 필드에서 애니메이션 커브는 하루 종일 그림자의 시계 방향 각도를 나타냅니다. 길이 매개변수는 주어진 순간에 그림자의 길이를 정의합니다. 예를 들어 해가 지고 있을 때는 그림자를 길게 만들고, 해가 장면을 수직으로 비출 때는 그림자를 짧게 만들어야 할 수 있습니다. 그림자 각도 및 그림자 길이 설정을 새로 고치려면 테스트 시간 슬라이더를 이동해야 할 수도 있습니다.
특히 모바일 플랫폼에서 2D 조명을 사용할 때 흔히 우려하는 것은 게임 내 조명 추가 비용입니다. 실제 대상 하드웨어에서 지원되는 최저 사양으로 테스트하는 것이 좋습니다. 성능을 향상시키기 위해 적용할 수 있는 몇 가지 일반적인 최적화 방법도 있습니다:
채우기 비율을 가능한 한 낮게 유지하세요. 큰 조명 하나가 작은 조명 여러 개보다 성능이 떨어질 수 있습니다.
조명은 일괄 처리할 수 있을 때 가장 성능이 좋습니다. 인접한 레이어에 걸쳐 동일한 조명 설정을 가진 조명을 모두 함께 그릴 수 있습니다.
렌더링 스케일을 가능한 한 낮게 유지하세요. 렌더 스케일은 조명을 렌더링할 때 사용되는 텍스처 크기를 조정하며, 텍스처 크기가 작을수록 렌더링할 픽셀 수가 줄어듭니다.
화면에서 그림자를 드리우는 조명 수를 최소화합니다. 그림자 그리기로 전환할 때 적지 않은 성능 비용이 발생합니다.
화면에 표시되는 다양한 블렌드 스타일 수를 최소화합니다. 블렌드 스타일 그리기로 전환할 때 상당한 비용이 발생합니다.
프로젝트의 필요에 맞게 최대 라이트 렌더 텍스처 및 최대 그림자 렌더 수를 조정합니다. 수치가 높을수록 성능이 향상되지만(최대 한도까지) 필요한 메모리도 증가합니다. 올바른 번호를 찾아야 합니다.
아직 다운로드하지 않았다면 Unity의 2D 게임 개발 및 렌더링(3D 및 2D)을 다루는 고급 전자책을 다운로드하세요:
고급 Unity 크리에이터를 위한 유니버설 렌더 파이프라인 소개
Unity의 고해상도 렌더 파이프라인에서 라이팅에 대한 최종 가이드
또한 다른 2D 데모도 확인해 보세요, 로스트 크립트 와 드래곤 크래셔.
고급 프로그래머, 아티스트, 테크니컬 아티스트, 디자이너를 위한 더 많은 리소스는 Unity 베스트 프랙티스 허브에서 확인할 수 있습니다.