Unity에서 라이트 맵을 효율적으로 생성하기 위한 Bakery 에셋을 활용하는 과정은 기대 이상으로 흥미롭고 도전적이었습니다. Bakery는 GPU에서 실행되는 라이트 맵 생성 도구로, 다양한 조명 효과를 손쉽게 적용할 수 있습니다. 이 글에서는 Bakery를 적용하면서 마주한 여러 문제와 그 해결 과정을 자세히 다루고자 합니다. 특히, 커스텀 셰이더를 사용하는 경우 라이트 맵이 제대로 베이크되지 않는 문제를 해결하는 과정에 초점을 맞추겠습니다.
Bakery의 기본 개념과 Meta Pass 이해하기
Bakery를 사용하기 위해서는 먼저 Meta Pass라는 개념을 이해해야 합니다. 이는 라이트 맵을 생성할 때 Albedo 값과 Emission 값을 제공하는 셰이더 패스입니다. 일반적인 커스텀 셰이더는 Meta Pass를 포함하지 않기 때문에, 라이트 맵이 제대로 베이크되지 않는 경우가 발생합니다. Unity의 스탠다드 셰이더는 이미 Meta Pass를 포함하고 있어, 추가적인 설정 없이도 라이트 맵을 성공적으로 생성할 수 있습니다.
Meta Pass의 기능과 특징
Meta Pass는 라이트 맵에만 영향을 주며, 실시간 렌더링에는 영향을 미치지 않습니다. 이 기능 덕분에, 라이트 맵 생성 시 필요한 정보만을 제공하여 최적화된 결과를 얻을 수 있습니다. 예를 들어, 그림자와 관련된 설정은 Meta Pass에 포함되지 않으며, 이러한 설정은 별도로 다루어야 합니다. 이러한 특징으로 인해, Meta Pass는 라이트 맵을 효과적으로 관리하는 중요한 요소로 작용합니다.
커스텀 셰이더에 Meta Pass 추가하기
커스텀 셰이더에 Meta Pass를 추가하는 과정은 처음에는 쉽지 않았습니다. 공식 문서와 여러 온라인 자료를 참고하여 필요한 코드를 작성했지만, 초기에는 제대로 작동하지 않았습니다. 아래는 Meta Pass를 추가하기 위해 필요한 코드의 예시입니다.
“`hlsl
SubShader {
Pass {
Name “META”
Tags {“LightMode”=”Meta”}
Cull Off
HLSLPROGRAM
#include “UnityStandardMeta.cginc”
#pragma vertex vert_meta
#pragma fragment frag_meta_Toon
#pragma shader_feature _EMISSION
CBUFFER_START(UnityPerMaterial)
sampler2D _BaseMap;
half4 _BaseColor;
CBUFFER_END
float4 frag_meta_Toon(v2f_meta i): SV_Target
{
UnityMetaInput o;
UNITY_INITIALIZE_OUTPUT(UnityMetaInput, o);
half4 c = tex2D(_BaseMap, i.uv);
o.Albedo = half3(c.rgb * _BaseColor.rgb);
o.Emission = _EmissionColor;
return UnityMetaFragment(o);
}
ENDHLSL
}
}
“`
이 코드는 Meta Pass가 요구하는 기본적인 구조를 갖추고 있습니다. 이를 통해 라이트 맵 베이킹 시, 커스텀 셰이더의 머티리얼도 정상적으로 처리될 수 있도록 하였습니다.
Emission 처리와 Global Illumination Flags 설정
커스텀 셰이더에서 Emission 값을 처리하는 것도 중요한 부분입니다. Bakery를 사용하여 라이트 맵을 베이크할 때, 머티리얼의 Emission이 정상적으로 반영되려면, MaterialGlobalIlluminationFlags를 적절히 설정해야 합니다. 초기에는 이 설정이 잘못되어 Emission 효과가 사라지는 문제가 발생했지만, 아래와 같은 코드를 통해 이를 해결할 수 있었습니다.
“`csharp
public class GlobalIlluminationFlags : MonoBehaviour
{
public MaterialGlobalIlluminationFlags flag = MaterialGlobalIlluminationFlags.AnyEmissive;
void OnEnable()
{
SetFlags();
}
void OnValidate()
{
SetFlags();
}
private void SetFlags()
{
var rend = GetComponent<Renderer>();
if (rend && rend.sharedMaterial)
{
rend.sharedMaterial.globalIlluminationFlags = flag;
}
}
}
“`
이 스크립트는 Emission을 사용하는 머티리얼에 붙여 사용해야 하며, 다른 오브젝트에서 같은 머티리얼을 사용할 경우 마지막으로 설정된 플래그가 적용됩니다. 이를 통해 라이트 맵이 제대로 생성되도록 보장할 수 있었습니다.
라이트 맵 베이킹의 실제 경험과 문제 해결
라이트 맵을 베이크할 때 발생하는 여러 문제를 해결하는 과정에서 많은 시행착오가 있었습니다. 드로우 모드에서 라이트 맵이 제대로 적용되지 않는 문제는 특히 골치 아픈 부분이었습니다. 이 문제를 해결하기 위해 드로우 모드를 조정하고 결과를 시각적으로 확인하는 방법을 사용했습니다.
베이킹 결과의 시각적 확인
라이트 맵 베이킹 후 결과를 시각적으로 확인하는 과정은 매우 중요합니다. 드로우 모드를 활성화하여 라이트 맵만을 그리도록 설정하면, 라이트 맵이 제대로 적용되었는지 쉽게 확인할 수 있습니다. 이를 통해 예상치 못한 문제가 발생했을 때 즉각적으로 대응할 수 있었습니다.
최종 마무리 및 참고 자료
Bakery를 활용한 라이트 맵 생성 과정은 많은 도전과 학습의 연속이었습니다. 특히 커스텀 셰이더의 처리 방법과 관련된 문제들은 실제 프로젝트를 진행하면서 많이 겪는 부분입니다. 이러한 과정을 통해 얻은 경험은 향후 프로젝트에 큰 도움이 될 것입니다.
추가적으로 참고한 자료들은 다음과 같습니다:
- Unity의 공식 문서
- 다양한 Unity 커뮤니티 및 블로그에서 제공되는 셰이더 관련 정보
이 글을 통해 Bakery와 커스텀 셰이더를 활용한 라이트 맵 처리 방법에 대한 이해가 깊어지기를 바랍니다. 다양한 상황에서 발생할 수 있는 문제들을 미리 인지하고 대응할 수 있는 능력을 기르는 것이 중요합니다.