게임 프로그래밍
[Unity-Shader] Rim Light 본문
모든 물체는 기울어질수록 반사가 심해집니다. 반사율은 재질에 따라 다르게 나타납니다.
역광이거나, 털이거나 반투명 재질을 가진 물체들은 이 현상이 매우 강렬하게 나타날수 있고, 재질에 따라 잘 안보일 수도 있습니다. 사진 분야에서는 이것을 Rim Light라고 부릅니다.
금속 재질은 비금속 재질보다 확연하게 반사율이 다릅니다. 이러한 반사 공식을 Fresnel(프레넬) 이라 부릅니다.
이 프레넬 공식을 구현해 림 라이트를 만들어 봅시다.
Lambert 라이트에 대해서 잠깐 얘기해보겠습니다. "노멀 벡터와 조명 벡터의 각도가 같으면 밝고, 90도가 되면 어두워진다" 이었습니다.
1
2
3
4
5
|
struct Input
{
float2 uv_MainTex;
float3 viewDir;
};
|
cs |
input에 float viewDir을 추가하였습니다.이것은 "뷰 벡터" 입니다. 이는 버텍스에서 카메라가 바라보는 방향을 나타냅니다.
1
2
3
4
5
6
7
|
void surf (Input IN, inout SurfaceOutputStandard o)
{
fixed4 c = tex2D (_MainTex, IN.uv_MainTex );
float rim = dot(o.Normal, IN.viewDir);
o.Emission = rim;
o.Alpha = c.a;
}
|
cs |
이를 Lambert 라이트 처럼 버텍스와 내적을 하게 해준다면, 뷰 벡터와 마치 라이팅처럼 연산이 될 것입니다. 카메라가 마치 조명처럼 인식되어 내가 바라보는 방향이 계속 밝아지게 되는것 입니다.
이 결과를 뒤집어 줍니다.
1
2
3
4
5
6
7
|
void surf (Input IN, inout SurfaceOutputStandard o)
{
fixed4 c = tex2D (_MainTex, IN.uv_MainTex );
float rim = dot(o.Normal, IN.viewDir);
o.Emission = 1 - rim;
o.Alpha = c.a;
}
|
cs |
1
2
3
4
5
6
7
|
void surf (Input IN, inout SurfaceOutputStandard o)
{
fixed4 c = tex2D (_MainTex, IN.uv_MainTex );
float rim = dot(o.Normal, IN.viewDir);
o.Emission = pow(1 - rim,3);
o.Alpha = c.a;
}
|
cs |
제곱 계산을 통해 쎄기를 조절할 수 있습니다.
1
2
3
4
5
6
7
8
|
void surf (Input IN, inout SurfaceOutputStandard o)
{
fixed4 c = tex2D (_MainTex, IN.uv_MainTex );
//o.Albedo = c.rgb;
float rim = dot(o.Normal, IN.viewDir);
o.Emission = pow(1 - rim,3) * _Color;
o.Alpha = c.a;
}
|
cs |
컬러 변수를 추가함으로써 림 라이트의 색을 변경할 수 있을 것 입니다.

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
|
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
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 = dot(o.Normal, IN.viewDir);
o.Emission = pow(1 - rim,3) * _Color;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
|
cs |
전체소스 코드 입니다.
'프로그래밍 > 유니티' 카테고리의 다른 글
[Unity-Shader] Blinn-Phong (0) | 2020.05.01 |
---|---|
[Unity] hierarchy 에서 특정 Scirpt를 가지고 있는 오브젝트를 찾을때 (0) | 2020.04.04 |
[unity] Unity Ads 넣는 방법 (0) | 2020.04.02 |
[Unity3D] Script Templates (0) | 2020.03.19 |
[Unity] Custom TileMap Creator (0) | 2020.03.17 |
Comments