티스토리를 오랜만에 다시 찾게 되어서 근 1년 반만에 글을 업로드 합니다 ㅎㅎ
댓글을 남겨주신 분 정말 감사합니다! 정리된 쉐이더 소개들은 열심히 올려보도록 하겠습니다.
좀 더 깔끔하게 보고 싶으신 분들은, 구글 도큐먼트 링크를 추천합니다.
https://docs.google.com/document/d/13jMcv0xb4e1Q37O3DFh2D2BKsMLHkf8etL-25PHOtpc/edit?usp=sharing
6주차, 빛을 알아보자.
6주차, 빛을 알아보자. 저번 시간에 배운 버텍스 컬러 및 노말 등 가벼운 리마인딩은 5주차를 참고하도록 하자! ( https://docs.google.com/document/d/1BlYdxFLroX1PqUpn2FHSuM82q_5KBEKciCW4Hob5wGg/edit?usp=sharing ) 빛을
docs.google.com
1. 빛을 왜?
결국 우리가 살면서 보고, 느끼고 판단하는 시각적 요소에는 빛이 빠질 수가 없다. 게임 내에서 하나의 세계(?)를 구현하는 우리의 멋진 게임 개발 삶에도 끝내주는 그래픽을 표현하기 위해서라면 잘 알아둘 필요가 있다.
다만 빛을 만들어내는 입장에서 브루스 올마이티의 짐 캐리처럼 마구잡이로 개념없이 행동할 수는 없는 일이다. 가볍게 알아보도록 하자!
1-1. 빛을 구분해보자!
빛을 세분화 시킨 레퍼런스도 존재한다. 의역으로 해석해두긴 했지만 대충 저런 형식으로 기본적으로 현실에 존재하는 빛에 대한 점을 여러 부분으로 나눌 수 있는 것이다. 물론, 상단에 있는 사진의 라이트의 개념과 이름을 전부 이해할 필요는 없다.
왜냐하면, 우리는 현실의 라이트를 컴퓨터 그래픽스로 따라할 뿐이다.
그리고 현실의 라이트를 따라하기 위해서 총 3가지의 현실의 빛을 따라하는 Digital Light들이 존재한다.
각 3가지의 라이트는 현실에는 미존재하지만 그래픽으로 나타내기 위한 축약의 형태에 가깝다. 여기서 문제 하나를 보자!
A와 B가 지면이 있고 B는 A의 그림자를 무시한다고 보자.
그럼 A가 밝을까, B가 밝을까?
대부분의 사람들은 A가 밝다고 생각할 것이다. A는 빛과 가장 가깝고 강한 빛을 빠른 시간 내로 받을 수 있다고 생각하기 때문이다.
다만 컴퓨터 그래픽스에서는 다르다. B가 더 밝다!
B가 더 밝은 이유를 알아보기 전에, 기본적으로 알아야 할 개념이 있다.
핸드폰 플래시를 키고 정면에서 책을 비췄을 때와 측면으로 돌려진 책을 비췄을 때 과연 어떤 것이 더 밝을지를 생각하면 좋다.
당연히 정면으로 세워진 책이 더 뚜렷하게 빛이 밝게 보인다.
즉, 면과 빛이 정면으로 같이 바라보고 있을 때. 빛과 면의 각도가 직각일 때에 빛이 강하게 보여지고 있다는 것이다.
즉 컴퓨터 그래픽스에서의 B가 A보다 밝은 이유는
B의 면적에 닿는 빛의 각도가 A보다 훨씬 90도(직각)에 가깝기 때문이다.
그러나! 실생활에서의 A가 더 밝게 보인다.
왜냐면 실생활의 대기중에서는 먼지 등 산란을 시키는 요소들이 많고, 이로 인해서 멀게 존재하는 B의 면적까지 빛이 감쇄되기 때문이다.
이를 통해 컴퓨터 그래픽스의 빛에서는 그림자를 우선적으로 전제하지 않는다는 것을 알 수 있다. (감쇄 또는 그림자 설정을 넣을 필요가 있다는 것이다.)
동시에 상단의 3가지의 빛 예시중 Spot Light (빛이 퍼지는 것이 아닌 직각으로 내려오는 형태)를 사용하게 된다면 어떤 결과가 나올지 이제 알 수 있게 되었다.
1-2. 벡터를 이해해보자!
빛이 내려오고, 바닥과의 각도를 잴 수 있다고 한다면 분명 방향이 있다는 것이다.
그리고 컴퓨터 그래픽스는 그런 방향을 ‘벡터(Vector)’라고 부른다.
벡터의 어원은 직접 찾아볼 수 있겠지만 결국 벡터는 ‘달라지는 것’, 즉 크기와 방향을 나타내는 역할을 한다.
화살표로 생각하면 쉽다. 길이는 힘의 크기, 화살표의 지표가 방향이다.
화살표의 길이가 길면 크기가 큰 것이고, 지표에 따라 방향이 달라지는 것이다.
다만 Vector1 은 방향을 나타낼 수 없다. 예시를 더 보자!
우리가 지금까지 버텍스의 위치를 배웠던 것처럼, 화살표로 나타내기 위해서는 각 시작점과 끝점이 있어야 한다.
그림을 보자하니 float2를 통해 길이와 방향으로 벡터를 나타내고 있다.
만약 float1의 값이었다면 힘은 나타낼 수 있을지 몰라도 방향은 나타낼 수가 없다.
float2를 통해 평면적인 벡터의 값을 보았다고 한다면, 이젠 float3를 통해 3차원 값의 벡터를 볼 수도 있을 것이다. 이제 Unity의 피봇 좌표들을 보게 되면 Vector3로 읽히게 되기도 한다.
다만 이 부분에 대해선 조금 나중에 다뤄보기로 하자. 왜냐면 …
2. 빛을 또?
컴퓨터 그래픽스에서 빛과 벡터가 있다는 것을 깨달았다면, 이 친구들도 알아야 한다.
Diffuse, Ambient, Specular Light 총 3가지의 친구가 있다. 천천히 알아보도록 하자!
2-1. Diffuse Light (난반사)
디퓨즈(Diffuse)는 거친 표면에 빛이 반사되어 나오는 현상이며, 난반사라고 불린다.
표면이 일정하지 않으며 닿은 빛이 반사(Reflection)되는 것 또한 일정하지 않다.
일정하지 않은 반사로 인해 어떤 각도에서 보든 그 형태 그대로 보이게 된다.
2-2. Specular Light (정반사)
스펙큘러(Specular)는 부드러운 표면에 빛이 반사되어 나오는 현상이며, 정반사라고 불린다. 표면이 일정하고 닿은 빛이 반사(Reflection)되는 것 또한 일정하다.
2-3. Ambient Light (반사광)
앰비언트(Ambient)는 환경광, 반사광이라 불리는데 모든 물체에 고루 보이는 빛이다. (이 이상 쓸 말이 없다. 환경에 존재하는 Omni-Light 라고 생각하면 좋다.)
이렇게 3가지의 기본 Light 친구들을 알아보았지만, 저 친구들을 전부 넣어보면
… 결과는 이렇다.
뭔가… 너무 단순하다.
예쁘다면 어쩔 수 없지만, 뭔가 상단에 있었던 현실에 있는 구 형태와는 다르게 어색한 느낌이 강하다.
그럼 도대체 무엇을 해야 할까?
3. PBR(물리기반 셰이더) 알아내기
상단에 있는 사진은 진짜같지만, 사실 진짜가 아니다. (함정입니다.)
PBR 기반의 쉐이더를 사용하여 제작한 모델링의 결과물이다. 도대체 이 PBR이 뭐길래 이렇게 사실적인 결과가 나오는 것일까?
Physically Based Rendering, 즉 물리 기반 셰이더는 쉐이더 하나를 통합하여 셰이더 하나로 어떤 질감이든 만들어둘 수 있도록 만든 것이다.
주변 환경(빛)에 따라서 변화하므로 결국 보았을 때 예쁜 것보다는 현실에 기반한 정확한 Material이 중요하게 된 것이다.
하지만 아티스트들은 “현실? 그게 뭔데요?”하며 제 눈을 믿는 일이 많다.
그런 사람들을 위해 유니티는 친절하게 가이드까지 만들어두었다.
읽어보면 알겠지만, 각각 질감이나 특징에 따라 어떤 값을 주어야 하는지를 만들어두었다.
그러나 우리는 여전히 “그게 뭔 개소리인데요?”라고 반응하게 되는 아티스트이다. 그러므로 또 다시 천천히 PBR을 살펴보도록 하자...
3-1. 물리기반의 등가 교환
갑자기요? 라고 얘기할 수 있겠지만
결국 컴퓨터 그래픽스도 현실을 기반한, 심지어 현재는 PBR이라는 “물리 기반”을 중점으로 하는 것이기 때문에 현실의 규칙에 따를 수밖에 없다.
- 정반사와 난반사는 서로 비례한다.
정반사가 강해지면 난반사는 감소하고, 정반사가 강해지면 난반사는 약해진다.
(이에 대한 좋은 예시를 찾을 수 없었다. )
금속은 고유의 스펙큘러 색을 가지고 있지만, 비금속은 흰 스펙큘러를 가지고 있다.
예를 들어 마루 장판을 보면 흰색으로 스펙큘러가 생길 때가 있다.
마루 장판 위에 만약 고유의 색을 가진 스펙큘러가 뜬다면 그건 금속재질이거나, 조명의 색일 가능성이 높다.
동시에 금속의 경우 고유의 색을 가진 스펙큘러를 띈다.
(구리나 금 등, 고유의 색이 있다.)
이대로도 이해가 되지 않는다면, 거울의 Diffuse 색이 무엇이냐! 를 따지면 된다.
결국 거울에는 색이 없다는 것이다. 스펙큘러만이 남았을 뿐…
아무튼! 나머지 어려운 계산은 유니티가 해주므로, 이런 점만 알아두면 되겠다!
(내가 잘 모르겠어서 더이상 못 쓰겠다. BRDF가 도대체 뭔지 모르겠다.)
그러나 이렇게 현실에 기반한 셰이더를 배운다 하더라도, 특정 게임에 또는 AD가 또는 내 눈에 보았을 때 예쁘지 않으면 나가리(?) 일 수도 있다. 우리는 현실에 기반된 기술을 배우기는 하지만, 결국 게임은 Virtual Reality이기 때문이다.
결국, 이쁘면 장땡이다.
4. PBR(물리기반 셰이더) 써보기
솔직히 새로 배우는 것처럼 써버렸지만, 결국 우리가 쓰는게 PBR이다.언리얼과 유니티에 기본적으로 들어가있고, 추가적으로 PBS라는 다른 패스가 존재할 뿐이다.
거의 일반화가 되어가는 라이트 개념이고 PBS의 경우 반사가 아닌 기본 스펙큘러에 익숙한 사람들을 위한 방식일 뿐이다.
그리 큰 차이는 없지만 PBR 및 PBS의 구조체를 살펴보자!
PBR | PBS |
struct SurfaceOutputStandard { fixed3 Albedo; fixed3 Normal; fixed3 Emission; half Metalic; half Smoothness; half Occulsion; half Alpha; }; |
struck SurfaceOutputStandardSpecular { fixed3 Albedo; fixed3 Normal; fixed3 Emission; half Metalic; half Smoothness; half Occulsion; half Alpha; }; |
솔직히, 결과물은 Standard 랑 다를 바가 없다.
그래서 응용해보았다!
노말과 AO가 약한 텍스처를 집어 넣었기 때문에 그리 뚜렷하지는 않다.
코드 내에 정리하지 않았기에 추가 설명을 하자면…
4-1. PBR 쉐이더의 유의할 점
평소 노말맵, 텍스처 외에도 시도해본 예제에는 Roughness(Smoothness), AO, Emission 등 다양한 텍스처들이 들어간 것을 볼 수 있었다.
각 텍스처들을 사용할 때의 유의할 점을 확인해보자.
- Roughness(Smoothness)
1. Properties에서 맵을 불러올 때, 값이 0.5(Gray)가 되어야 한다.
(Smoothness의 기본 값이 0.5인 것과 같은 이치이다.)
2. 유니티는 Roughness가 아니라 Smoothness로 적용되기 때문에 섭스턴스 페인터나 언리얼이 아닌 이상 반전(One Minus)를 해줘야 한다.
3. Roughness Texture의 설정 중 sRGB 설정은 꺼줘야 한다.
4. o.Smoothness에 적용할 때 (1-Rough) 상태에서 _Smoothness(Range)값을 곱해주면 0~1사이로 옅어질 수 있게 조절할 수 있다. (1을 곱하면 제자리, 1 이하를 곱할 시 옅어진다.)
더 반짝이길 원하면 Range 설정을 바꿔주면 된다.
- AO(Ambient Occlusion)
1. Properties에서 맵을 불러올 때 값이 1(White)가 되어야 한다.
2. Struct Input에서 따로 uv를 불러올 필요가 없다. (이건 철칙이다.)
그러므로 void surf에서 사용할 때에도 uv의 경우 _MainTex 설정을 사용한다.
- Emission
1. Properties에서 맵을 불러올 때, 값이 0(Black)이어야 한다.
2. Emission은 Emission의 uv를 사용한다.
해당 부분을 유의하면서 다시 한번 작업해본 결과물이다!
쓰인 텍스쳐는 Albedo(+Emission을 위한 Alpha), Normal, AO 뿐이다.
Roughness가 없는 모델링이었기에 Emission을 Albedo.a에 사용했는데, 만약 Roughness가 있다면 Albedo.a에, Emission은 AO.rgb중 하나에 넣었을 것 같다.
그렇게 하면 Properties 내부의 양도 줄일 수 있고 텍스처 양도 줄일 수 있었다.
여담으로 Emission의 경우 정확하게 확인하기 위해서 Post Processing을 사용하였다.
'Shader' 카테고리의 다른 글
8주차, 림라이트를 만들어보자. (1) | 2023.06.02 |
---|---|
7주차, 빛을 커스텀 해보자. (1) | 2023.02.09 |
5주차, Vertex Color를 주자. (0) | 2020.10.08 |
4주차, UV를 다뤄보자. (0) | 2020.10.05 |
3주차, 함수 조작을 배워보자. (0) | 2020.09.17 |