본문 바로가기
Unity - Surface Shader

5. 알파블렌딩과 컷아웃

by SimonLee 2023. 11. 20.

알파(Alpha)는 오브젝트의 투명도를 의미합니다.

알파블렌딩은 투명한 오브젝트가 앞에 있을때, 뒤에 있는 배경 컬러값과 적당하게 컬러값을 섞어준다는 것을 의미합니다.

투명한 오브젝트를 그릴때 배경이 미리 그려져있어야 하기 때문에 , 렌더링 순서가 관련이 있습니다.

 

오브젝트 렌더링 순서는 다음과 같습니다.

불투명한 오브젝트 -> 뒤에있는 반투명 오브젝트 -> 앞에있는 반투명 오브젝트 

불투명한 오브젝트는 Z buffer로 픽셀에 그려야 할지 말지를 알수가 있습니다.

그래서 렌더링 순서가 상관이 없지만

반투명 오브젝트는 반투명된 부분의 컬러값이 뒤에있는 배경과 블렌딩(알파블렌딩)이 되어야 하기 때문에

반드시 뒤에서 부터 그려져야 합니다.

 

그래서 소팅이 필요한데요

알파 소팅은 오브젝트의 중심점과 카메라의 거리 기준으로 정렬을 합니다.

 

오브젝트의 크기와 카메라 뷰의 각도에 따라서 정확하게 앞뒤를 확하게 판정을 할 수가 없습니다.

그래서 알파 블렌딩을 사용하는 경우, 카메라 각도 조절 혹은 중심점 및 오브젝트 크기 변경 등 

별도의 작업이 필요할수 있습니다.

 

사용방법은 다음과 같습니다.

Queue라는 것은 렌더링 오더링을 의미하며 숫자 타입으로 매핑이 되어있습니다.

Trasparent는 Opaque 보다 높은 숫자이며, Opaque 보다 나중에 렌더링 됩니다.

 SubShader
{
        Tags { "RenderType"="Transparent" "Queue" = "Transparent"}
        ....
        CGPROGRAM
        #pragma surface surf Lambert alpha:fade
}

 

알파 블렌딩 대안책으로 나온 것은 Alpha Testing(Cutout) 입니다

오더링은 불투명한 오브젝트 -> 알파 테스팅 -> 알파 블렌딩 순으로 렌더링 됩니다.

 

_Cutoff 프로퍼티는 잘려버릴 픽셀의 정도 입니다.

예제 0.5 기준으로 하면)

_Cutoff 값이 alpha 값과 비교를 하여

0.5보다 작은 alpha 값들은 완전 투명으로 만들고, 

0.5보다 큰 값은 완전 불투명으로 만들어 버립니다.

 

흔들리는 풀이나 나무를 그려할때 사용이 됩니다.

 

RenderType = "TransparentCutout" Queue = "AlphaTest"

 

#pragma alphatest:_Cutoff

Shader "Custom/AlphaTest"
{
    Properties
    {       
        _Color ("Main Color", Color) = (1, 1, 1, 1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}     
        _Cutoff("Alpha cutoff", Range(0, 1)) = 0.5
    }
    SubShader
    {
        Tags { "RenderType"="TransparentCutout" "Queue" = "AlphaTest"}
        cull off
        LOD 200

        CGPROGRAM
        #pragma surface surf Lambert alphatest:_Cutoff

        #pragma target 3.0

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;            
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Legacy Shaders/Transparent/Cutout/VertexLit"
}

 

블렌딩 기법을 알아봅시다.

blend 라는 keyword를 사용하여 현재 오브젝트 컬러와 배경을 블렌딩을 할수 있습니다.

blend [현재오브젝트 컬러값과 곱해질 계수] [배경컬러값과 곱해질 계수]

 

투명도 적용 블렌딩

1) blend SrcAlpha OneMinusSrcAlpha

- 오브젝트 픽셀 칼러 * alpha + 배경 칼러 * (1 - alpha)

- 가장 많이 쓰는 블렌딩 기법 입니다. 

- 투명 오브젝트 겹치는 부분이 있을때, 서로 컬러값이 다르므로 앞뒤 바뀌면 티남.

Order이 바뀜.

 

2) blend SrcAlpha One ( Additive )

- 오브젝트 픽셀 칼러 * alpha + 배경 칼러 * 1

- 배경 컬러값이 100% 적용 되기 때문에 겹쳐지는 부분이 밝아 집니다.

- 불투명한 오브젝트의 순서가 바뀌어도 블렌딩된 컬러값이 동일하여 앞뒤 바뀌어도 눈치챌수가 없습니다.

 

투명도 적용되지 않는 블렌딩

아래 blend도 테스트를 해보시면 좋을것 같네요

- blend One One
- blend DstColor Zero
- blend DstColor SrcColor
- blend DstColor SrcColor

 

 

Shader "Custom/AlphaBlending"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue" = "Transparent"}
        zwrite off
        blend SrcAlpha OneMinusSrcAlpha
        //blend SrcAlpha One // additive -> no ordering problem
        //blend One One // no alpha apply
        //blend DstColor Zero
        //blend DstColor SrcColor
        //blend DstColor SrcColor

        LOD 200

        CGPROGRAM
        #pragma surface surf Lambert keepalpha        
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };
        
        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Legacy Shaders/Transparent/VertexLit"
}