유니티에서 스프라이트를 쓸때

색깔을 바꾸면 뭔가 칙칙하게 바뀌는 듯한 느낌이 든다


기본 스프라이트에서 왼쪽이 흰색 , 오른쪽이 파란색을 넣었을 때


이유는 기본 스프라이트 쉐이더가 색깔을 적용할때

곱해서 처리하기 때문이다


쉐이더에서 색을 저장할때 fixed4라는 자료형을 쓰는데

R,G,B,A값을 저장하는 역활을 한다


그러니깐  

(0,0,0,0) 이 투명한 검은색

(1,1,1,1)이 불투명한 흰색

이 되는 것이다.


만약 (0.5,0.5,0.5,1)(회색)과 (0.5,0.5,0.5,1)을 합칠때


더한다면 (1,1,1,2)이 되어서 하얀색이 되고 (2는 1로 취급)

곱한다면 (0.25,0.25,0.25,1)이 되어서 어두운 회색이 된다


따라서 곱하기를 쓰는 유니티 기본 스프라이트에

색을 넣으면 더 칙칙해지는 것이다


그런데 그냥 + 를 쓰면

색이 1을 넘어갔을때 짤리게 된다


그래서 스크린이라는 방식이 있는데

result = 1-(1-A)*(1-B);

원래 색상들을 1에서 빼서 곱하고

그 값을 또 1에서 빼는 것



그래서 만드는 방법은


1.

https://unity3d.com/kr/get-unity/download/archive?_ga=1.66259950.1501402159.1471086308


유니티 다운로드 아카이브에서 내장 셰이더를 다운로드한다.

기왕이면 버전에 맞게 다운로드 하면 된다.


그러면 셰이더들이 잔뜩 들어있는 압축파일을 받게 되는데


ctrl + f 로 Sprites-Diffuse.shader 를 찾는다


Diffuse 를 쓰는 이유는 Default 쉐이더는 너무 간소화되서 어떻게 수정하는지 모르기 때문에......



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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
 
Shader "Sprites/Diffuse"
{
    Properties
    {
        [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
        _Color ("Tint", Color) = (1,1,1,1)
        [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
        [HideInInspector] _RendererColor ("RendererColor", Color) = (1,1,1,1)
        [HideInInspector] _Flip ("Flip", Vector) = (1,1,1,1)
        [PerRendererData] _AlphaTex ("External Alpha", 2D) = "white" {}
        [PerRendererData] _EnableExternalAlpha ("Enable External Alpha", Float) = 0
    }
 
    SubShader
    {
        Tags
        {
            "Queue"="Transparent"
            "IgnoreProjector"="True"
            "RenderType"="Transparent"
            "PreviewType"="Plane"
            "CanUseSpriteAtlas"="True"
        }
 
        Cull Off
        Lighting Off
        ZWrite Off
        Blend One OneMinusSrcAlpha
 
        CGPROGRAM
        #pragma surface surf Lambert vertex:vert nofog nolightmap nodynlightmap keepalpha noinstancing
        #pragma multi_compile_local _ PIXELSNAP_ON
        #pragma multi_compile _ ETC1_EXTERNAL_ALPHA
        #include "UnitySprites.cginc"
 
        struct Input
        {
            float2 uv_MainTex;
            fixed4 color;
        };
 
        void vert (inout appdata_full v, out Input o)
        {
            v.vertex = UnityFlipSprite(v.vertex, _Flip);
 
            #if defined(PIXELSNAP_ON)
            v.vertex = UnityPixelSnap (v.vertex);
            #endif
 
            UNITY_INITIALIZE_OUTPUT(Input, o);
            o.color = v.color * _Color * _RendererColor;
        }
 
        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = SampleSpriteTexture (IN.uv_MainTex) * IN.color;
            o.Albedo = c.rgb * c.a;
            o.Alpha = c.a;
        }
        ENDCG
    }
 
Fallback "Transparent/VertexLit"
}
 
cs

아무튼Sprites-Diffuse.shader는 요로케 생겼는데 여기서 수정할 부분은 


2. 

이름 바꾸기


이미 유니티에는 Diffuse 쉐이더가 들어있기 때문에

쉐이더의 이름을 바꿔줘야한다


저 "/" 는 폴더같은 느낌으로 머터리얼에서 쉐이더를 고르기 편하게 해준다.


2. 

surf함수 수정

1
2
3
4
5
6
7
8
void surf (Input IN, inout SurfaceOutput o)
{
    fixed4 c = 1 - ((1 - SampleSpriteTexture(IN.uv_MainTex)) * (1 - IN.color));
    c.a = SampleSpriteTexture(IN.uv_MainTex).a * IN.color.a;
 
    o.Emission = c.rgb * c.a;
    o.Alpha = c.a;
}
cs

surf함수를 이렇게 바꾸면 된다.


여기서 스크린이아니라 + 를 쓰고 싶으면 3번 줄을 

fixed4 c = SampleSpriteTexture(IN.uv_MainTex) + IN.color;

로 바꾸면 된다.



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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
 
Shader "Sprites/Screen"
{
    Properties
    {
        [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
        _Color ("Tint", Color) = (1,1,1,1)
        [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
        [HideInInspector] _RendererColor ("RendererColor", Color) = (1,1,1,1)
        [HideInInspector] _Flip ("Flip", Vector) = (1,1,1,1)
        [PerRendererData] _AlphaTex ("External Alpha", 2D) = "white" {}
        [PerRendererData] _EnableExternalAlpha ("Enable External Alpha", Float) = 0
    }
 
    SubShader
    {
        Tags
        {
            "Queue"="Transparent"
            "IgnoreProjector"="True"
            "RenderType"="Transparent"
            "PreviewType"="Plane"
            "CanUseSpriteAtlas"="True"
        }
 
        Cull Off
        Lighting Off
        ZWrite Off
        Blend One OneMinusSrcAlpha
 
        CGPROGRAM
        #pragma surface surf Lambert vertex:vert nofog nolightmap nodynlightmap keepalpha noinstancing
        #pragma multi_compile_local _ PIXELSNAP_ON
        #pragma multi_compile _ ETC1_EXTERNAL_ALPHA
        #include "UnitySprites.cginc"
 
        struct Input
        {
            float2 uv_MainTex;
            fixed4 color;
        };
 
        void vert (inout appdata_full v, out Input o)
        {
            v.vertex = UnityFlipSprite(v.vertex, _Flip);
 
            #if defined(PIXELSNAP_ON)
            v.vertex = UnityPixelSnap (v.vertex);
            #endif
 
            UNITY_INITIALIZE_OUTPUT(Input, o);
            o.color = v.color * _Color * _RendererColor;
        }
 
        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = 1 - ((1 - SampleSpriteTexture(IN.uv_MainTex)) * (1 - IN.color));
            c.a = SampleSpriteTexture(IN.uv_MainTex).a * IN.color.a;
 
            o.Emission = c.rgb * c.a;
            o.Alpha = c.a;
        }
        ENDCG
    }
 
Fallback "Transparent/VertexLit"
}
 
cs

완성본!




기본 흰색 , 기본 파란색 , 스크린 파란색

블로그 이미지

stuban

ㅇ.ㅇ

,