Unity Shader 공부- 림라이트

림라이트는 저렇게 경계면에서 빛나는 듯한 연출을 할때 사용되는 빛이다.

 

게임에서 보면 이렇다

그래서 오늘은 림라이트를 만들어 볼건데..

 

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
Shader "Custom/RimShader"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _BumpMap("NormalMap",2D) = "bump"{}
        _RimColor("RimColor", Color) = (1,1,1,1)
        _RimPower("RimPower",Range(1,10))=3
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
       
 
        CGPROGRAM 
        #pragma surface surf Lambert noambient
 
 
        sampler2D _MainTex;
        sampler2D _BumpMap;
        float4 _RimColor;
        float _RimPower;
        
        struct Input
        {
            float2 uv_MainTex;
            float2 uv_Bump;
            float3 viewDir;
        };
 
        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);//우선 uv에 텍스처를 입힌다.
            o.Albedo = c.rgb;
            o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_Bump));//노멀맵을 뽑아내서 나중에 빛계산을 위해 노말을 뽑아놓음
            float lightPower = dot(o.Normal, IN.viewDir);//노멀맵에 ViewDir를 내적하면 해당 버텍스의 빛의 세기가 나온다.
            //o.Emission = pow(1 - lightPower, _RimPower) * _RimColor.rgb; //1-lightPower을 해서 빛을 역전시켜줌,거기에 _RimPower만큼 제곱
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

우선 림을 적용시키지 않고 기본적인 람버트 쉐이딩으로 표현하면

요론식으로 된다.

그리고 이때 Rim을 적용시키면? *위의 코드에서 주석만 제거*

 

오웅 이렇게 후광있는듯이 가능해진다.

 

여기까지 아주 간단한 림라이트였고, 이거로 홀로그램을 만들어 보려한다.

 

참고로 o.Emission은 자체적으로 방출하는 색상으로

 

Albedo에 + 되는 색상이다.

그러므로 o.Emission에 림값을 넣어줌으로써 저렇게 경계면이 하얗게 올라오는 것

 

 

 

이걸 응용해서 홀로그램을 만들 수 있는데.

 

 

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
Shader "Custom/RimShader"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        //_BumpMap("NormalMap",2D) = "bump"{}[제거]
        _RimColor("RimColor", Color) = (1,1,1,1)
        _RimPower("RimPower",Range(1,10))=3
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue" = "Transparent" }
       
 
        CGPROGRAM 
        #pragma surface surf Lambert noambient alpha:fade//[변환]
 
 
        sampler2D _MainTex;
        //sampler2D _BumpMap;[제거]
        float4 _RimColor;
        float _RimPower;
        
        struct Input
        {
            float2 uv_MainTex;
            //float2 uv_Bump; [제거]
            float3 viewDir;
        };
 
        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);//우선 uv에 텍스처를 입힌다.
            //o.Albedo = c.rgb;[제거]
            //o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_Bump));[제거]
            float lightPower = dot(o.Normal, IN.viewDir);//노멀맵에 ViewDir를 내적하면 해당 버텍스의 빛의 세기가 나온다.
            float rim = pow(1 - lightPower, _RimPower);//1-lightPower을 해서 빛을 역전시켜줌,거기에 _RimPower만큼 
            o.Emission = _RimColor.rgb;
            o.Alpha = rim;//라이트 파워만큼의 알파
        }
        ENDCG
    }
    FallBack "Diffuse"
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

일단은 제거하고 변경해준다. (위처럼)

오오.. 그럼 이렇게 albedo는 투명하게 나오고 Rim이 처리된 부분만 보이는 투명물질이 만들어진다!

 

그리고 여기서 홀로그램같은 느낌을 표현하려면

 

우선 연출을 위한 코드를 구현해야하는데

1
2
o.Emission = frac(IN.worldPos.g);
o.Alpha = 1;//라이트 파워만큼의 알파
 

 우선 Emission 부분을 이런식으로 바꿔보자

frac 내장함수는 소수점 부분만을 표현하는 것이다 즉0~1사이라는 것.

 

그렇다면 오브젝트의 월드좌표에서 y값이 0일시 저런식으로 표현된다.

하얀색이 끝나는부분이 (??,1,??) 인 것.

 

1
o.Emission = pow(frac(IN.worldPos.g*3),30);
 

이 코드에 대해 확실히 알았다면 *3을 해줬을때 컬러의 0~1사이 값을 표현하는게 더 많아 지는 것을 눈치 챌 수 있을거고,

pow를 해주면 림라이트에서 더 경계면쪽으로 색상이 모여들었듯이

 

1아래의 값들이 좀더 작아지면서 어두운 부분이 더 많아 지는것을 눈치 챌것이다.

1
2
3
4
5
6
7
8
void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);//우선 uv에 텍스처를 입힌다.
            float lightPower = dot(o.Normal, IN.viewDir);//노멀맵에 ViewDir를 내적하면 해당 버텍스의 빛의 세기가 나온다.
            float rim = pow(1 - lightPower, _RimPower)+ pow(frac(IN.worldPos.g * 3 - _Time.y), 30);//1-lightPower을 해서 빛을 역전시켜줌,거기에 _RimPower만큼 
            o.Emission = _RimColor;
            o.Alpha = rim;//라이트 파워만큼의 알파
        }
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

 

그리고 색상을 결정할 때 _Time.y 만큼 빼주면 흰선들이 올라가는걸 표현할 수 있고 Rim에다가 더해주고

아까처럼 코드를 바꿔주면

요로코롬 된다.

 

노멀맵을 적용 시켜주면

완성!

 

역시 쉐이더는 보이는게 있어서 재미있다.

 

내일은 블린퐁 만들어봐야징

  Comments,     Trackbacks