일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Three(Two) Tone Shading
- working set
- Virtual Byte
- Cell Look
- AppSW
- URP
- Toon Shader
- C언어
- OculusMotionVectorPass
- 게임 수학
- Specular
- Private Bytes
- 작업 집합
- Cell Shader
- 3d
- 메모리 누수
- Windows Build
- ASW(Application SpaceWarp)
- Cartoon Rendering
- 개인 바이트
- 가상 바이트
- URP로 변경
- 프로그래밍 기초
- ColorGradingLutPass
- 벡터
- Rim Light
- VR
- Today
- Total
WinCNT
URP로 Toon Shader 만들기 -Specular 2- 본문
URP에 대해서 공부하면서 알게 된 것을 정리하는 페이지입니다
서론
저번에는 Toon Shading의 Specular 요소란 무엇인가에 대해서 정리해 봤다
이번에는 Specular의 실제 구현에 대해서 정리하고자 한다
스펙큘러냐 하이라이트냐
여기서 말하는 스펙큘러와 하이라이트는 모두 블린 퐁 모델에서의 스펙큘러와 같다
즉, 빛이 정반사되어 눈에 들어와서 빛나 보이는 부분을 말한다
다만 그 표현 방식이 다르기 때문에 유니티 툰 쉐이더(UTS)에서는 다른 단어를 사용하고 있었다
간단히 말해 스펙큘러는 블린 퐁 모델에서의 스펙큘러와 같은 느낌이고
하이라이트는 스펙큘러를 Two Tone Shading처럼 경계로 나눈 느낌이다
예시를 보면 이해하기 쉬울 것이다
그럼 Two Tone Shading처럼 스펙큘러도 모두 하이라이트로 하면 되지 않을까라고 생각할 수 있는데, 모든 걸 경계로 나눌 수 없다는 것이 Toon Shading의 귀찮은 점이다
배경을 PBR, 캐릭터를 NPR로 한다고 해도(원신처럼) 캐릭터도 머리카락, 얼굴, 몸(옷), 스킬 시전 시의 표현은 다를 것이다
또한 아트 컨셉에 따라서는 다양한 표현이 필요하게 될 것이다
즉, 결론은 일단 둘 다 구현하는 게 좋다는 것…
스펙큘러와 하이라이트의 그래프
일단 여러 스펙큘러의 그래프를 정리해봤다
Blinn-Phong
float y(float x) {
// x == Normal dot Half Angle
float specFactor = pow(max(x, 0.0), 20.0);
return specFactor;
}
UTS의 Specular
float y(float x) {
// x == Half NdotH == 0.5 * dot(normal, halfAngle) + 0.5
float _SpecularPower = 0.5;
float ret = pow(x, exp2(mix(11.0, 1.0, _SpecularPower)));
return ret;
}
UTS의 Highlight
float y(float x) {
// x == Half NdotH == 0.5 * dot(normal, halfAngle) + 0.5
float _SpecularPower = 0.5;
float ret = 1.0 - pow(x, 5.0);
ret = step(x, 1.0 - pow(_SpecularPower, 5.0));
ret = 1.0 - ret;
return ret;
}
대략적으로 Blinn-Phong과 UTS의 스펙큘러 그래프는 큰 차이가 없어 보인다
UTS의 Hightlight의 그래프는 보이는 바와 같이 경계로 나눠져 있다
사족이지만 UTS도 그렇고 우마무스메도 그렇고
스펙큘러는 특히 매직 넘버가 많은 것처럼 보인다
단순히 필자가 이해하지 못 한 수식이 숨어있을 가능성도 있다
Specular 구현하기
그래프의 식을 구현하면 스펙큘러도 구현할 수 있다
물론 스펙큘러냐 하이라이트냐를 나눠주는 처리도 필요하다
외부에서 프로퍼티 등으로 조절하는 게 제일 좋지만 필자는 일단 내부의 변수로 만들었다
나중에 필요해지면 그 때가서 수정하면 되겠지
/// Specular
// Half-Angle Vector
const float3 _HalfDir = normalize(IN.lightDir + IN.viewDir);
const float _HalfNdotH = 0.5 * dot(IN.normal, _HalfDir) + 0.5;
// Specluar로 할까 하이라이트로 할까 정하는 변수
// 0 : Specluar, 1 : Highlight
const bool _IsHighColorToSpecular = true;
// Specular Color에 Main LightColor를 반영할지를 정하는 변수
const bool _UseMainLightColorForSpec = true;
// Specular Power와 Half NdotH로 스펙큘러를 계산함
const float _HighColorMask =
lerp(
pow(abs(_HalfNdotH), exp2(lerp(11, 1, _SpecularPower))), // Specluar
1.0 - step(_HalfNdotH, 1.0 - pow(_SpecularPower, 5)), // Highlight
_IsHighColorToSpecular
);
// 프로퍼티에서 설정한 Specular Color를 스펙큘러 수치에 따라 조정(설정에 따라서 Main Light Color를 반영함)
const float3 _HighColorOnly = lerp(_SpecularColor.rgb, _SpecularColor.rgb * _MainLight.color.rgb, _UseMainLightColorForSpec) * _HighColorMask;
// Base Color로 Specular를 조정한다
half3 _FinalHighColor =
lerp(
saturate(_FinalBaseColor.rgb - _HighColorMask), // 이 부분은 수수께끼
_FinalBaseColor.rgb,
lerp(0.0, 1.0, _IsHighColorToSpecular)
)
+ _HighColorOnly.rgb;
// Specular를 더한다
_FinalColor.rgb += _FinalHighColor.rgb;
마무리
이것으로 Specular 구현에 대한 내용 마무리할까 한다
다음에는 림 라이트에 대해 정리해보려고 한다
참고 사이트
'Unity > URP or Shader 관련' 카테고리의 다른 글
URP로 Toon Shader 만들기 -Rim Light 2- (0) | 2023.05.26 |
---|---|
URP로 Toon Shader 만들기 -Rim Light 1- (0) | 2023.05.23 |
URP로 Toon Shader 만들기 -Specular 1- (0) | 2023.02.09 |
URP로 Toon Shader 만들기 -Three(Two) Tone Shading 2- (0) | 2023.02.06 |
URP로 Toon Shader 만들기 -Three(Two) Tone Shading 1- (0) | 2023.02.02 |