개요

게임 엔진에서 ColorSpace(색공간)을 Gamma, Linear 2가지 중 하나를 선택할 수 있으며 UI를 포함한 2D 텍스처 알파가 ColorSpace에 따라 다르게 보이는 이슈가 있습니다.

 

이번 포스팅은 이러한 이슈를 해결하기 위한 리서칭, 그리고 작업자를 위한 최적의 세팅 가이드를 소개합니다.

 

이슈 원인 - Linear ColorSpace에서 알파가 다르게 보이는 이유

https://www.slideshare.net/jpcorp/ss-96115075

게임 엔진에서 Linear ColorSpace를 사용하면 알파 블랜딩, 쉐이더 연산 값이 다르게 변합니다. 이는 PBR(물리기반렌더링) 3D 게임에서 더 현실적이고 정확한 조명 연산을 위해 필요한 기능입니다.

하지만 포토샵 등 텍스처 에셋 제작은 Gamma ColorSpace 기준으로 제작하기 때문에 포토샵에서 알파가 다르게 보이는 이슈가 발생합니다.

 

위 내용은 간단 요약한 것이며 ColorSpace에 대한 자세한 이론이 궁금하시다면 아래 자료를 참고해주시길 바랍니다.

 

 

이슈 해결을 위한 리서칭

Linear ColorSpace에서 포토샵과 알파가 동일하게 보이기 위해 3가지 시도를 해봤습니다.

먼저 3가지 방법을 소개하고, 결과 리뷰를 작성합니다.

 

1. UI 쉐이더에서 알파 값 감마 보정

Unity Sprite 혹은 UGUI Image 컴포넌트에 커스텀 쉐이더 기반 Material을 세팅할 수 있습니다.

여기에 세팅되는 커스텀 쉐이더에서 알파 값 감마 보정을 시도했습니다.

 

쉐이더 코드는 아래와 같습니다. fragment 쉐이더에서 알파 값에 대한 감마 보정 코드를 추가합니다.

감마 보정은 pow(alpha, 2.2)해도 되고, 유니티 내장 함수에 있는 코드를 사용해도 됩니다.

(2개 방법 전부 밴딩 현상 문제 있음)

 // Unity 내장 함수
 inline half GammaToLinearSpace (half sRGB)
 {
     // Approximate version from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1
     return sRGB * (sRGB * (sRGB * 0.305306011h + 0.682171111h) + 0.012522878h);
     // Precise version, useful for debugging.
     //return half3(GammaToLinearSpaceExact(sRGB.r), GammaToLinearSpaceExact(sRGB.g), GammaToLinearSpaceExact(sRGB.b));
 }

 float4 frag(v2f IN) : SV_Target
 {
     float4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd);// * IN.color;
     #if !UNITY_COLORSPACE_GAMMA
         // Gamma to Linear
        //color.a = GammaToLinearSpace(color.a);     // Unity 내장 함수
        color.a *= pow(color.a, 2.2f);
     #endif
     color *= IN.color;

     #ifdef UNITY_UI_CLIP_RECT
     color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
     #endif

     #ifdef UNITY_UI_ALPHACLIP
         clip (color.a - 0.001);
     #endif

     return color;
 }

 

 

2. AssetPostprocessor를 활용해 알파 보정하여 텍스처 임포팅

public class SpriteAssetPostprocessor : AssetPostprocessor
{
    private void OnPostprocessTexture(Texture2D texture)
    {
        TextureImporter textureImporter = (TextureImporter)assetImporter;

        ModifySpriteAlphaGammaToLinear(textureImporter, texture);
    }

    private static void ModifySpriteAlphaGammaToLinear(TextureImporter textureImporter, Texture2D texture)
    {
        if (textureImporter.textureType != TextureImporterType.Sprite ||
            PlayerSettings.colorSpace != ColorSpace.Linear) return;
        if (texture.name.Contains("Linear") == false) return;

        Color[] pixels = texture.GetPixels();
        for (int i = 0; i < pixels.Length; i++)
        {
            Color pixel = pixels[i];
            // pixel.a = Mathf.Pow(pixel.a, 2.2f);
            pixel.a = GammaToLinearSpace(pixel.a);
            pixels[i] = pixel;
        }
        texture.SetPixels(pixels);
        texture.Apply();
        Debug.Log(texture.name);
    }

    static float GammaToLinearSpace(float sRGB)
    {
        // Approximate version from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1
        return sRGB * (sRGB * (sRGB * 0.305306011f + 0.682171111f) +0.012522878f);

        // Precise version, useful for debugging.
        //return half3(GammaToLinearSpaceExact(sRGB.r), GammaToLinearSpaceExact(sRGB.g), GammaToLinearSpaceExact(sRGB.b));
    }
}

 

C# 스크립트에서 Assetpostprocessor 클래스를 활용해 텍스처를 엔진에서 임포트 할때 자동으로 알파 값을 보정하는 기능을 개발했습니다.

쉐이더에서 처리하는 것보다 성능적으로 더 좋다고 판단해서 시도했습니다.

 

 

3. 포토샵에서 색상 공간 변경

이번에는 엔진에서 아무것도 하지 않고 포토샵에서 색상 공간을 변경하는 방법입니다.

포토샵의 "색상 설정" 옵션에서 "감마를 사용하여 RGB 색상 혼합" 옵션을 활성화하고 리소스 제작 작업을 합니다.

해당 옵션은 기본적으로 비활성화되어 있지만 활성화한다면 엔진에서 Linear ColorSpace 세팅한것과 동일한 룩으로 변경됩니다.

이 방법의 단점은 포토샵 블랜딩 효과가 불량하게 동작할 수 있고 Gamma ColorSpace에서 다르게 보이는 이슈가 발생할 수 있으니 참고 바랍니다.

(24.04.25 비활성화 <-> 활성화 내용을 반대로 작성한 것 수정, 댓글 피드백 감사합니다)

 

 

결과 리뷰

위 사진은 엔진에서 감마, 리니어 결과 그리고 위 리서칭 3가지 방법에 대한 결과물을 모았습니다.

엔진에서 처리하는 2가지 방법은 알파 강도가 비슷해지기는 했지만 색상 블랜딩이 여전히 다르게 보이는 이슈가 있습니다.

반면 포토샵에서 색상 설정 적용한 결과물은 엔진에서 Linear Colorspace와 동일한 결과를 보여주고 있습니다.

 

다음은 그라데이션 텍스처를 출력한 결과물입니다.

엔진에서 세팅한 2가지 방법은 색상 블랜딩 이슈도 있었지만, 위 사진을 자세히 보시면 밴딩 현상까지 보이는 품질 이슈가 있습니다.

또한 Texture Importer(Asset Postprocessor)에서 처리한 결과물은 알파 값을 다르게 저장했기 때문에 알파 값 이슈도 발생합니다.

 

 

 

결론 및 다른 시도 방향

Linear ColorSpace에서 알파가 다르게 보이는 이슈는 엔진에서 처리하면 문제가 해결되지 않습니다.

최적은 작업자가 포토샵에서 "색상 설정" 기능을 활용해 Linear ColorSpace에 맞는 리소스를 제작하는 것 입니다.

 

그 외 유니티 엔진에서 UGUI 렌더파이프라인에 대한 커스텀을 시도해볼 수 있을 것 같습니다.

 


WRITTEN BY
CatDarkGame
Technical Artist dhwlgn12@gmail.com

,