본문 바로가기

Unity3D C#/유니티 쉐이더 공부

버텍스 컬러 마스킹으로 활용하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Shader "Custom/vertexcolor" {
    Properties {
        _MainTex("Albedo (RGB)", 2D) = "white" {}
        _MainTex2("Albedo (RGB)", 2D) = "white" {}
        _MainTex3("Albedo (RGB)", 2D) = "white" {}
        _MainTex4("Albedo (RGB)", 2D) = "white" {}
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        
        CGPROGRAM
        #pragma surface surf Standard nomabient
 
        sampler2D _MainTex;
        sampler2D _MainTex2;
        sampler2D _MainTex3;
        sampler2D _MainTex4;
 
        struct Input {
            float2 uv_MainTex;
            float4 color:COLOR;
        };
        
        void surf (Input IN, inout SurfaceOutputStandard o) {
            fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
            fixed4 d = tex2D(_MainTex2, IN.uv_MainTex);
            fixed4 e = tex2D(_MainTex3, IN.uv_MainTex);
            fixed4 f = tex2D(_MainTex4, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
 
cs


            float4 color:COLOR;

ㄴ버텍스컬러를 받기 위해 추가한 줄


4장의 텍스쳐 컬러를 받아 Albedo에 출력하는데 정작 출력하는 것은 c뿐임.

위 코드대로라면 흰색 화면만 c 텍스쳐만 보이게 됨.


하지만 버텍스컬러가 다음과 같이 칠해져있다면 

o.Albedo = IN.color.r; 코드를 사용하게 되면

위와 같이 보이게 되는데 RGB로 볼 때는 몰랐던 R 채널만 봤을 때의 흑백 모습임.

이 성질을 이용해서 멀티 텍스쳐링을 할 수 있음.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Shader "Custom/vertexcolor" {
    Properties {
        _MainTex("Albedo (RGB)", 2D) = "white" {}
        _MainTex2("Albedo (RGB)", 2D) = "white" {}
        _MainTex3("Albedo (RGB)", 2D) = "white" {}
        _MainTex4("Albedo (RGB)", 2D) = "white" {}
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        
        CGPROGRAM
        #pragma surface surf Standard nomabient
 
        sampler2D _MainTex;
        sampler2D _MainTex2;
        sampler2D _MainTex3;
        sampler2D _MainTex4;
 
        struct Input {
            float2 uv_MainTex;
            float4 color:COLOR;
        };
        
        void surf (Input IN, inout SurfaceOutputStandard o) {
            fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
            fixed4 d = tex2D(_MainTex2, IN.uv_MainTex);
            fixed4 e = tex2D(_MainTex3, IN.uv_MainTex);
            fixed4 f = tex2D(_MainTex4, IN.uv_MainTex);
 
            o.Albedo = lerp(c.rgb, d.rgb, IN.color.r);
            o.Albedo = lerp(o.Albedo, e.rgb, IN.color.g);
            o.Albedo = lerp(o.Albedo, f.rgb, IN.color.b);
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
 
cs

lerp 함수를 이용하여 c와 d의 r채널의 검은 부분은 c 텍스쳐, 흰 부분은 d텍스쳐가 나오도록 하고

버텍스컬러의 g 부분은 e 텍스쳐가, b 부분은 f 텍스쳐가 나오도록 함

o.Albedo = d.rgb * IN.color.r + e.rgb * IN.color.g + f.rgb * IN.color.b + c.rgb * (1-(IN.color.r + IN.color.g + IN.color.b)); 이렇게 코딩하면 굳이 lerp를 사용하지 않아도 동일한 결과를 낼 수 있다고 함


이 방식으로 쉐이더를 구현해놓고 나면, 이후에 버텍스 컬러를 다르게 칠해주는 것만으로 실시간 텍스쳐 블렌딩 효과를 구현할 수 있음. 지형 뿐 아니라 먼지가 묻거나 파손된 벽 재질의 오브젝트 표현하는 등 다양하게 응용될 수 있다고 함.