게임 프로그래밍
[Unity-shader] rim light 홀로그램 본문
림 라이트를 이용하면 홀로그램 같은것을 만들 수 있습니다.

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 관련 부분이 추가 되었습니다.