
Height Map : 높이를 저장하고 있는 그레이 스케일의 텍스쳐를 통칭
Parallax Mapping(시차 맵핑)?
시야각에 따라 UV를 이동시켜 깊이감을 흉내내는 기법.
실제로 vertex를 이동시키지는 않고, Normal map으로 표현하기 힘든 기울어진 표면에서 입체감을 강화시켜주는 효과를 보여줌.
기울기에 의한 차폐까지 계산되는 Paorallax Occlusion이라는 기술도 있음.

Detail Map : 근접했을 때 흐려지는 텍스쳐의 디테일을 보완하고자 만든 기법
돌이 젖는다는 것은,
정리하면,

간단하고 효율적으로 젖은 표면을 만들 수 있다.

색을 칠한 윗 부분만 어두워지고 정반사가 늘어난다.
Troubleshooting
책에서 말하는대로 윗부분만 어두워지는게 아니라 아래 부분도 어두워지길래 다시 한 번 확인해봤더니, 책에선 색을 칠하지 않은 부분은 검은색으로 칠해져있었다. 나는 검은색을 칠해두지 않아서 윗부분과 아래 부분의 차이가 없었다.

Lerp에 연결하는 값에 Multiply로 계수를 조절해줄 수도 있다.
컴퓨터 그래픽 라이트 기본 3가지 종류
조명의 방향 벡터와 물체의 노말 벡터(법선 벡터)가 서로 마주보고 있을 때 그 면은 가장 밝다.
숫자로 색상, 위치, 방향을 표현할 수 있다.
Vector3(1,0,0)은 빨강으로도, X축 방향 길이 1인 화살표로도 표현될 수 있다.
Vector3(0,1,0)은 녹색으로도, Y축 방향 길이 1인 화살표로도 표현될 수 있다.
Vector3(0,0,1)은 파랑으로도, Z축 방향 길이 1인 화살표로도 표현될 수 있다.
Normal Map의 RGB 칼라도 같은 느낌으로 보면 된다.
노말 벡터와 라이트 벡터가 서로 마주보면 가장 밝고, 각도가 벌어지면 점점 어두워지는데,
노말 벡터가 면에 있으면 부드러운 라이팅을 구현할 수 없으므로,
요즘에는 노말 벡터가 버텍스에 있다. 버텍스 사이의 밝기 값은 보간으로 표현한다.
그런데 보간을 해버리면 각지게 표현할 때 버텍스 주변에 있는 면들이 모두 다른 밝기를 가질 수가 없다.
그래서 요즘의 게임 엔진은 각진 물체를 표현하기 위해 버텍스를 복사해서 같은 자리에 추가하여 표현한다.
즉, 각지게 표현하면 요즘엔 버텍스 양이 오히려 늘어난다.
가장 밝은데 -1이면 곤란하니까 연산하기 전에 조명 벡터 방향을 반대로 해준다.
(유니티에선 조명 벡터가 뒤집힌 채로 받아오기 때문에 안 뒤집어줘도 된다)
램버트 (Lambert) 라이팅 : 조명 벡터랑 노말 벡터 내적. Diffuse Light를 표현하는 가장 흔한 방식.
Shader Graph의 라이팅 계산법은 Lit와 Unlit 정도.
Lit 셰이더는 퀄리티는 좋지만 모바일에선 약간 무거움.
물리적으로 옳지 않은 창의적 효과 표현 못 함.
라이팅 구조를 커스텀으로 조정해서 창의적 표현해야됨.
이를 위해 SimpleLit이라 부르는 전통적 라이팅 구조를 만들어보는 실습할 것.
라이팅 구조를 새로 만들어야 하니 아무 라이팅 연산 없는 Unlit Shader Graph를 만든다.
Normal Vector 노드를 추가한다.
Light Vector를 받아오기 위해 Custom Function 노드를 추가한다.
Custom Function 노드는 직접 HLSLI 코딩으로 노드에 없는 기능을 작성하는 노드이다.
Normal Vector 노드 Space 옵션
Custom Function 노드의 Graph Inspector 옵션
Custom Function의 Precision은 Single, Preview는 Preview3D, Outputs는 Direction이라는 이름을 가진 Vector3로 설정해놓고
#ifdef SHADERGRAPH_PREVIEW
Direction = float3(1,1,1);
#else
Light light = GetMainLight();
Direction = light.direction;
#endif
Type을 String으로 바꾼 뒤 Name은 CustomLight, Body에는 위의 코드를 적어준다.
이후 Directional Light의 각도를 바꿔주면 색깔도 바뀌는 것을 확인할 수 있다.
코드 설명
Troubleshoting
책에서 하라는대로 Outputs에 변수를 추가하긴 했는데 이름을 Direction으로 안 바꿔서 변수가 할당되지 못하는 오류가 생겼었음.

Normal Vector와 Dot Product 노드를 사용해 내적해주면 빛이 연산된다.
내적 연산하면 -1 값도 나오는데, 이를 Saturate, Maximum, Clamp 노드 등을 이용해 0으로 잘라준다.
앰비언트 라이트나 추가 라이트를 비출 때 음수에 숫자를 더하게 되어서 밝아지지 않는 등 문제가 생길 수 있기 때문이다.

버텍스의 Normal Vector를 Normal Map 텍스쳐로 대체해주면 디테일이 살아난다.
이 과정에서 Tangent Space인 Normal map을 World Space로 바꿔주기 위해 Transform 노드를 이용한다.
Transform 노드에서 Type도 Direction으로 바꿔줘야 함.

래버트 라이트는 가벼운 조명 공식이지만, cos 그래프 특성상 밝다가 너무 급격하게 음영이 떨어진다.
하프 램버트 공식은 물리적으론 옳지 않지만 보기 좋기 때문에 만들어졌다.
이전의 NdotL에서 Saturate를 통해 무시해줬던 음수 부분을 끌어올리기 위해
*0.5+0.5를 추가로 연산해주면 음영이 조금 더 부드러워진다.
실제로 사용할 땐 빛이 180도까지 미치다보니 음영이 너무 부드러워져서
3제곱 혹은 *0.7+0.3 정도로 사용한다. (저자는 *0.7+0.3가 더 가벼워서 좋아한다고 함)
NdotL?
N(Normal)과 L(Light)를 dot(내적)한 결과물
지금까지 구현한 것 : 빛 방향에 따른 음영
구현해야 할 것 : 조명의 색상과 강도, Albedo 텍스쳐, 환경광 등등

Color = light.color;을 추가하여 빛의 색깔을 받아온다이제 조명의 색상과 밝기를 변화하면 모델의 색상이 변하는 것을 확인할 수 있다.
이것은 '빛을 받는 부분은 자신이 가진 색상을 사방으로 방출해서 물체의 색이 보이게 된다'는 난반사(Diffuse Reflection)를 NdotL로 간단하게 구현한 것.
모든 난반사 물체는 자신의 색의 빛을 사방으로 연하게 반사한다.
이렇게 한 번 이상 반사된 빛이 다른 물체에 닿아 그 물체를 밝히면 이것을 환경광(Ambient Light)라 한다.
환경광이 아주 강해서 조명처럼 색이 묻어나는 것을 컬러 블리딩(Color Bleeding)이라 한다.
아주 맑은 날 야외라면 하늘에는 파란 환경광, 대지에는 지면 색의 환경광이 보일 것.
흐린 날에는 주광도 약해져서, 물체에 음영이 강하지 않아 환경 차폐(Ambient Occlusion)만 강조되어 보일 것.

유니티는 스카이 박스에 환경광이 있다. 이를 받아오려면 Baked GI 노드를 사용하면 된다.

Ambient Occlusio은 Ambient에 곱해주면 된다.
남은 구현할 것