Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
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
Archives
Today
Total
관리 메뉴

게임 프로그래밍

[Unity-shader] rim light 홀로그램 본문

카테고리 없음

[Unity-shader] rim light 홀로그램

Junwe 2020. 4. 30. 19:58

림 라이트를 이용하면 홀로그램 같은것을 만들 수 있습니다.

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
Shader "Custom/Rim"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Color("Color",Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }
        LOD 200
 
        CGPROGRAM
        #pragma surface surf Standard Lambert noambient alpha:fade
 
 
        sampler2D _MainTex;
        float4 _Color;
 
        struct Input
        {
            float2 uv_MainTex;
            float3 viewDir;
        };
 
        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
        // #pragma instancing_options assumeuniformscaling
        UNITY_INSTANCING_BUFFER_START(Props)
            // put more per-instance properties here
        UNITY_INSTANCING_BUFFER_END(Props)
 
        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex );
            //o.Albedo = c.rgb;
            float rim = saturate(dot(o.Normal, IN.viewDir));
            rim = pow(1-rim,3);
            o.Emission = float3(0,1,0);
            o.Alpha = rim;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
 
cs

기존 림 라이트의 연산을 alpha에 넣어 줬습니다. Alpha연산을 하기 위해 

Tags { "RenderType"="Transparent" "Queue"="Transparent" }

#pragma surface surf Standard Lambert noambient alpha:fade

도 추가 해줬습니다.

o.Alpha = rim * (sin(_Time.y) * 0.5 + 0.5) ;

rim 부분에 time을 넣어준다면 깜빡이는 효과를 넣어줄 수 있습니다. sin그래프는 -1~1 사이의 값이기 때문에 - 일 경우 결과가 뒤집혀서 나옵니다. 하프 램버트 라이트 공식인 (value * 0.5 + 0.5) 를 써주면 0~1 사이의 값으로 나오게 됩니다.

 

홀로그램에 줄이 나오게 해봅시다.

1
2
3
4
5
6
7
8
9
10
 
        struct Input
        {
            float2 uv_MainTex;
            float3 viewDir;
            float3 worldPos;
        };
 
 
 
cs

 

우선 input안에 worldPos를 추가합니다. 이는 이름 처럼 월드 좌표계에서의 포지션입니다.

o.Emission = IN.worldPos.g;

worldPos 의 g(y)값을 넣으면 이러한 색이 됩니다. 위로 올라갈 수록 밝아진다(1보다 값이 점점 커짐)는 것을 알 수 있습니다. 오브젝트를 위 아래로 움직이면 값이 어떤지 알 수있을것입니다.

우리가 필요한것은 0~1사이의 값 입니다. 이때 사용하기 좋은 함수느 frac라는 함수로, '소수점 부분'만 리턴하게 해줍니다.

그리고 나온 값의 제곱을 해준다면 "선"처럼 만들어질것 입니다. 그후 그 선이 움직이게 타임 값을 빼주면 됩니다.

 

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
Shader "Custom/Rim"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Color("Color",Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }
        LOD 200
 
        CGPROGRAM
        #pragma surface surf Standard Lambert noambient alpha:fade
 
 
        sampler2D _MainTex;
        float4 _Color;
 
        struct Input
        {
            float2 uv_MainTex;
            float3 viewDir;
            float3 worldPos;
        };
 
        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
        // #pragma instancing_options assumeuniformscaling
        UNITY_INSTANCING_BUFFER_START(Props)
            // put more per-instance properties here
        UNITY_INSTANCING_BUFFER_END(Props)
 
        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex );
            //o.Albedo = c.rgb;
            float rim = saturate(dot(o.Normal, IN.viewDir));
            rim = pow(1-rim,3) + pow(frac(IN.worldPos.g * 3 - _Time.y),30);
            o.Emission = float3(0,1,0);
            o.Alpha = rim;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
 
cs

전체 소스 코드 입니다. rim 계산부분에 worldPos 관련 부분이 추가 되었습니다.

Comments