Standard Shader
: 물리 기반 쉐이더로, 주변 환경에 따른 재질 변화를 물리 법칙에 기반하여 실시간으로 재질을 구현해주는 사실적인 쉐이더 표현 기법
SurfaceOutputStandard 구조체
: 구조체 안에는 변수들이 정의되어 있고, 알맞은 값을 넣어주면 간편하게 결과를 얻을 수 있다.
struct SurfaceOutputStandard
{
fixed3 Albedo;
fixed3 Normal;
fixed3 Emission;
half Metallic;
half Smoothness;
half Occlusion;
half Alpha;
}
- Metallic
: 0이면 비금속, 1이면 금속 재질
- Smoothness
: 0이면 거칠어서 난반사, 1이면 매끄러워서 정반사
난반사가 일어나는 이유는 '거친 표면' 때문이며, 피부나 천의 경우에는 부드러워 보이더라도 미세한 표면 단계에서 거칠기 때문에 스페큘러(정반사)가 적게 나타난다.
재질이 매끈하면 난반사Diffuse
< 정반사Specular
➡️ 이것을 조절하는 것이 Smoothness 인자이다.
유니티에서 Standard Shader라는 '물리 기반 렌더링'은 에너지 보존 법칙으로 나가는 빛의 양은 들어온 빛의 양을 넘을 수 없다 라는 기본 개념을 가진다.
거칠기에 따라 난반사와 정반사의 비율이 결정되며, 정반사가 높아지면 그만큼 난반사는 줄어든다.
(아래 사진은 밑으로 갈 수록 정반사가 높아진다.)
이러한 재질의 올바른 사용법은 Metallic Value Chart를 참고한다.
https://docs.unity3d.com/Manual/StandardShaderMaterialCharts.html
코드에 NormalMap을 입력받도록 _BumpMap
변수를 추가 (텍스쳐 형식과 거의 동일하다.)
NormalMap은 DXTnm
파일 포맷이다. 이 파일은 NormalMap의 R과 G의 퀄리티를 최대한 보전하여 저장하고, 보전된 R과 G는 NormalMap의 X
와 Y
로 계산되며 Z
는 삼각함수를 이용해 추출된다.
이를 위해 float3 y = UnpackNormal(float4 x);
함수를 이용해 NormalMap을 적용한다.
o.Normal = UnpackNormal(tex2D(_BumpMap, In.uv_BumpMap));
//float4인 데이터를 집어넣어서(tex2D) float3 데이터(Normal)로 받는다.
fixed3 n = UnpackNormal(tex2D(_BumpMap, In.uv_BumpMap));
o.Normal = n
//두 줄로 나누어 작성할 수도 있다.
//x와 y에 특정 숫자를 곱해줘서 NormalMap의 강도롤 조절할 수 있다.
// -> o.Normal = float3(n.x*2, n.y*2, n.z)
- Ambient Occlusion(환경 차폐)
- 일반적으로는 환경광(Ambient Color)로 가득찬 세상이며 그림자가 있는 부분도 사방에서 오는 환경광 정도를 받고있다.
- 하지만, 매우 구석지거나 복잡한 물체들로 가려져 환경광도 닿지 못해 매우 어두워지는데 이 부분이 Ambient Occlusion이다.
_Occlusion
변수를 추가_MainTex
와 같은 UV를 사용한다.)
o.Occlusion
은 float를 받기 때문에, RGB를 모두 사용하는 텍스쳐 한장을 단지 Occlusion 기능을 위해 추가하는 것은 낭비이다!
➡️ 텍스쳐를 절약하기 위해_MainTex
의 알파채널을 Occlusion맵으로 사용할 수도 있다. (포토샵을 이용해야한다.)
1. NormalMap 추가
2. Specular 추가
3. 추가 응용
세번째 텍스쳐(버텍스 컬러 G 마스크)부분만 젖은 효과를 만들어보자.
Smoothness에 1이 들어가면 반짝이는 것을 생각해서, 세번째 텍스쳐에 해당하는 버텍스 컬러 g 채널값을 Smoothness에 넣어보자
o.Smoothness = IN.color.g;
다른 부분이 완전히 둔탁해진 것을 보완하기 위해 전체적인 Smoothness를 약간 올려줄 수 있다.
o.Smoothness = IN.color.g + 0.3;
G 부분이 너무 심하게 반짝이므로, 조금 내려준다.
o.Smoothness = IN.color.g * 0.5 + 0.3;
인터페이스의 _Smoothness
값으로 반짝임을 조절하기 위해 버텍스 컬러의 g채널에 곱해준다.
o.Smoothness = (IN.color.g * 0.5) * _Smoothness + 0.3;