일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- URP로 변경
- 작업 집합
- 3d
- Private Bytes
- Cartoon Rendering
- OculusMotionVectorPass
- Specular
- VR
- Cell Look
- working set
- ASW(Application SpaceWarp)
- Rim Light
- Virtual Byte
- URP
- 메모리 누수
- 개인 바이트
- 벡터
- 게임 수학
- Windows Build
- Three(Two) Tone Shading
- Toon Shader
- Cell Shader
- 가상 바이트
- ColorGradingLutPass
- 프로그래밍 기초
- AppSW
- C언어
- Today
- Total
WinCNT
URP로 Toon Shader 만들기 -Three(Two) Tone Shading 2- 본문
URP로 Toon Shader 만들기 -Three(Two) Tone Shading 2-
WinCNT_SSS 2023. 2. 6. 16:21저번 글에 이어서 Power와 Feather로 컨트롤하는 Three Tone Shading의 구현에 대해서 정리하고자 한다
Power와 Feather로 컨트롤하는 Three Tone Shading의 구현
특별한 것 마냥 따로 빼긴 했지만 개념 자체는 다른 방법과 똑같다
즉, 왼쪽(Diffuse)의 값을 오른쪽으로 바꾸는 것!
다만 일반적인 Lambert가 아니라 Half Lambert를 사용하며,
Power와 Feather란 프로퍼티로 음영의 경계선을 컨트롤한다는 점이 다를 뿐
일단 하나씩 살펴보자
Half Lambert
Half Lambert에 대해서는 다른 좋은 글이 너무 많으므로 자세한 설명은 생략한다
(참고 사이트를 참고해주세요)
위키피디아에 따르면 Half Lambert는 서브서피스 스캐터링(Subsurface scattering, SSS)의 간이 NPR모델로 사용된다고 기재되어 있다
(물리적으로 올바르지 않지만 카툰 렌더링은 물리적 올바름을 추구하지 않으니 상관 없음)
코스트도 얼마 들지 않으면서 화사한 느낌을 줄 수 있다고 한다
뭐 일단 어려운 설명은 둘째치고 평범하게 Lambert로 만들면 음영이 차지하는 부분이 너무 커서 Power 프로퍼티의 조정 값이 너무 한쪽으로 쏠리게 된다…
실제 사용할 것을 생각하면 Half Lambert가 여러모로 적당하다고 할 수 있다
Power와 Feather
Power는 음영의 범위, Feather는 경계선이 흐린 정도를 조정하는 프로퍼티로 정의한다
step()와 smoothstep()로 비교하자면 Power은 1로 스텝하는 경계선을 컨트롤하고,
Feather는 0과 1의 경계의 보간 레벨을 컨트롤한다
Power는 0 ~ 1를 범위를, Feather는 0.0001 ~ 1의 범위로 둔다
(Feather는 나누기에 사용하기 때문에 0이 되면 안 됨)
실제로 사용한 코드와 그로 인한 결과 그래프는 다음과 같다
float y(float x) {
float shadePow = 0.5;
float shadeFeather = 0.0001;
float halfLambert = 0.5 * cos(x) + 0.5;
float shadeMask = (shadePow - halfLambert) / shadeFeather;
shadeMask = saturate(shadeMask);
float ret = mix(0.0, 1.0, shadeMask); // mix == lerp(HLSL)
return ret;
}
float y(float x) {
float shadePow = 0.7;
float shadeFeather = 0.1;
float halfLambert = 0.5 * cos(x) + 0.5;
float shadeMask = (shadePow - halfLambert) / shadeFeather;
shadeMask = saturate(shadeMask);
float ret = mix(0.0, 1.0, shadeMask); // mix == lerp(HLSL)
return ret;
}
위의 코드를 이용하니 step()과 smoothstep()와 비슷한 그래프를 만들 수 있었다
그리고 Power와 Feather 값의 변화로 그래프를 컨트롤할 수 있다는 것도 확인할 수 있었다
Half Lambert를 뒤집는 이유?
사실 위의 그래프는 step(), smoothstep()의 그래프와 다른 점이 있다
바로 그래프의 결과가 뒤집혀 있다(-1를 곱하)는 것!
실제로 위의 값을 출력해보면 아래와 같은 느낌이 된다
실제로 음영이 생길 부분은 하얗고 반대로 밝아야할 부분은 어두워진 것을 알 수 있다
왜 이런 짓을 하는 걸까……안 뒤집고 그대로 쓰면 안 되나?
개인적인 추측이지만 Half Lambert를 뒤집는 이유는 음영을 만들기 위해서가 아니라
음영인 부분을 판정하기 위해 Half Lambert를 뒤집는 것으로 생각된다
즉, 계산 결과가 하얀색(1.0)이면 음영으로, 검정색(0.0)이면 기본색이라 판정하는 것이다
(물론 이는 코딩하는 사람이 바꿀 수 있는 기준이라고 생각한다)
Three Tone Shading 구현하기
Two Tone Shading이면 위의 방법으로 이미 끝나지만, Three Tone Shading이면 한 단계 더 필요하다
그렇다고 딱히 어려운 공정이 필요한 것은 아니다
먼저 1음영과 2음영 중 어느 것을 음영의 색으로 할 것인지 결정하고,
그 음영 색과 기본 색 중 어느 색으로 최종적으로 출력할 것인지 결정하면 된다
// 1음영과 2음영 중 어느 것을 음영의 색으로 할 것인지 결정
const float _Shadow1And2Mask = saturate((_ShadowPower2 - _HalfLambert) / _ToonFeather1stTo2nd);
half4 _FinalBaseColor = lerp(_ShadowColor1, _ShadowColor2, _Shadow1And2Mask);
// 음영 색과 기본 색 중 어느 색으로 최종적으로 출력할 것인지 결정
const float _FinalShadowMask = saturate((_ShadowPower1 - _HalfLambert) / _ToonFeatherBaseTo1st);
_FinalBaseColor = lerp(_BaseColor, _FinalBaseColor,_FinalShadowMask);
픽셀 쉐이더에서 위의 코드를 구현하면 아래와 같은 Two Tone Shading를 표현할 수 있다
마무리
이것으로 Three Tone Shading 구현에 대한 기본적인 내용을 정리해보았다
사실 실제로 색을 지정하는 경우는 거의 없고 텍스처를 사용하는 경우가 대부분이겠지만
그에 대해서는 나중에 실제로 구현할 때 다시 정리해 보려고 한다
다음에는 스펙큘러 라이트나 림 라이트에 대해 정리해보려고 한다
참고 사이트
https://gamedevforever.com/150
'Unity > URP or Shader 관련' 카테고리의 다른 글
URP로 Toon Shader 만들기 -Specular 2- (0) | 2023.04.17 |
---|---|
URP로 Toon Shader 만들기 -Specular 1- (0) | 2023.02.09 |
URP로 Toon Shader 만들기 -Three(Two) Tone Shading 1- (0) | 2023.02.02 |
URP로 Toon Shader 만들기 -카툰 렌더링에 대해서- (0) | 2023.01.30 |
URP 쉐이더 파일 작성 (0) | 2023.01.23 |