Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

[NDC19] 모바일에서 사용가능한 유니티 커스텀 섭스턴스 PBR 셰이더 만들기

2.078 visualizaciones

Publicado el

NDC19에서 발표한 유니티 커스텀 섭스턴스 PBR 셰이더 만들기 관련 내용입니다. 셰이더 뿐 아니라 라이팅 모델에 대한 이야기도 함께 담고 있습니다. 커스텀 서피스 셰이더와 PBR에 대한 기본 지식이 있으면 이해하기 편합니다.

Publicado en: Tecnología
  • Sé el primero en comentar

[NDC19] 모바일에서 사용가능한 유니티 커스텀 섭스턴스 PBR 셰이더 만들기

  1. 1. 넥슨코리아 왓 스튜디오 박동민 모바일에서 사용가능한 유니티 커스텀 섭스턴스 PBR셰이더 만들기
  2. 2. 목차 1. 유니티 PBR 2. 간단 PBR개념 3. 라이팅모델 4. 커스텀 PBR 구현준비 5. 본격 구현 6. 유기체 확장
  3. 3. 발표자 소개 박동민 / 마둠파 넥슨코리아 왓스튜디오 소속 Technical Artist 게임업계 경력 10년차 NDC 발표는 처음 '마둠파 테크니컬 아트 연구소’ 네이버 블로그 운영중 https://blog.naver.com/mnpshino
  4. 4. 주의사항 오늘 발표는 아주 기술적인 이야기는 아닙니다 기술보다는 꼼수를 이용한 문제해결 이야기 약간의 아이디어와 집착. 그리고 노가다...
  5. 5. 그럼 시작하자마자 뜬금없이 질문하나 해볼게요 유니티라는 엔진은 PBR을 사용할 수 있습니다. PBR은 Physically Based Rendering - 물리 기반 렌더링이고요. 이것에 대한 자세한 설명 은 많은 분들이 다루셨으니 굳이 그 얘기를 하려는건 아니에요. 유니티에서 PBR을 사용하려면 Standard 라는 기본 셰이더를 사용하면 됩니 다. 여기까진 다들 아시는 내용이리라 생각해요.
  6. 6. 혹시.. 오늘 오신분들중에 (컬러 스페이스) 리니어 말고 감마에서 PBR해보신분 계신가요?
  7. 7. 리니어 스페이스와 감마 스페이스 사실 리니어 스페이스가 맞는 값 하지만 어두운곳에 민감한 사람 눈은 이것을 선형적으로 인지하지 않음 이것을 감마 코렉션 (2.2제곱) 하여 선형적으로 보이게끔 한것 왜 처음에 이런 질문을 드렸냐면, 유니티 컬러스페이스 기본 설정은 Gamma 이기 때문이죠 자세한 설명은 이 pt를 참고하세요- https://www.slideshare.net/jpcorp/ss-96115075
  8. 8. Environment Reflection은 0.5로 세팅 리니어와 감마에서 PBR이 어떻게 나오느냐 하면… 섭스턴스 페인터유니티 감마유니티 리니어 메탈릭 0, 러프니스 0.1, 베이스컬러 0.5일때 메탈릭 0, 러프니스 0, 베이스컬러 1일때
  9. 9. 빛을 돌리면… 섭스턴스 페인터유니티 감마유니티 리니어 메탈릭 0, 러프니스 0, 베이스컬러 1일때 보시다시피, 감마가 특히 느낌이 다릅니다
  10. 10. 리니어와 감마에서 PBR이 어떻게 나오느냐 하면(2) 섭스턴스 페인터유니티 (감마) 모델링 : 왓스튜디오 정희준님 (개인작업) 유니티 (리니어) 감마가 특히 허옇게 나옴. 리니어도 섭스턴스 페인터와 완벽하게 동일하지 않음
  11. 11. 유니티와 섭페를 비교해보며 알 수 있었던 것 유니티 감마는 물론이고 리니어도 섭스턴스 페인터와 동일하지 않다 결과값이 다르게 나오는걸 보면 서로서로 구현도 다르다는걸 알 수 있음 즉, 물리기반 셰이더가 사실은 물리적으로 완벽하게 옳은것은 아니라는 것 피지컬리 ‘퍼펙트’ 셰이더가 아니라 피지컬리 ‘베이스’ 셰이더 인것 물리적인 이론과 라이트모델을 고려했을 뿐. 사실은 근사값 대잔치 (실시간으로 돌아가야 하다보니…) 근사값 - ‘아...정확한건 아니지만...대충 이정도로 계산하니까 비슷해 보이는데…? 데헷?’ 의 줄임말
  12. 12. PBR은 리니어에서 하는게 상식입니다. 그러나... ● 감마 상태로 아주 오래 이어져 와서 리소스가 너무 많이 쌓여 컬러 스페이스를 바꾸는것이 부담스럽거나 ● 이미 출시가 된 상태(라이브중) 라 컬러 스페이스를 바꿀 수 없거나 ● 컬러스페이스를 어떻게 바꾸는지 모르거나 ● 중도 입사했는데 이미 감마상태거나 ● 등등등 ‘리니어로 바꾸세요’ 가 안되는 상황 상황이라는게 완벽하게 딱 맞아 떨어지면 좋겠지만 그렇지 않은 경우도 일어납니다. 위의 상황들이 생기지 말라는 법은 없죠. 알고보면 생각보다 꽤 많은 사람들이 고통받고 있다!
  13. 13. 감마에서 PBR을 해야하는 상황이... 오늘 발표할 내용들을 시작하게 된 동기가 되었음 감마에서는 방금 봤던 사례들처럼 섭스턴스 PBR느낌을 살리기가 어려워서 고쳐서 써야 하는데 Unity Standard 셰이더는 너무 방대하고 고치기가 어려움 그리고 저에게도...
  14. 14. 방대한 Standard Shader Include Tree 으아아ㅏ 이게뭐야 ㅏ
  15. 15. 감마에서 PBR로 퀄리티를 올리기란... Standard는 수많은 인클루드로 인해 코드보기 및 변경이 힘들고 수정하려면 GI함수를 건드려야 하는데 난이도가 높음 또한 아티스트가 의도한 대로 아웃풋 표현이 잘 안되니 어려움 그래서 Standard PBR은 과감히 포기하고 ‘수동으로라도 PBR 비슷하게 느낌을 내보면 어떨까’ 로 생각 바뀜 Specular / Glossiness 워크플로우 기반의 유사 PBR 셰이더를 만들기 시작
  16. 16. 3D 아티스트님께는 미안하지만... 고전적인 방식이지만….! 마...Specular Texture 도 있고….! CubeMap Reflection도 있고….! AO / IBL / Fresnel (Mask) Texture도 있고…! 거기에 딸린 많은 패러미터들도 있고…!
  17. 17. 하지만 PBR에서 3D 아티스트님은 섭스턴스를 사용 섭스턴스에도 Specular / Glossiness 워크플로우가 있긴하지만 Roughness / Metalic 워크플로우가 표준이자 대세. 모두 이것으로 작업함 일명 물질 화가 일명 물질 디자이너
  18. 18. fake PBR 셰이더의 한계 러프니스와 메탈릭 딱딱 넣어놓으면 알아서 계산해서 쨘 나오는것이 PBR 최고의 장점. 그러나 fake PBR이라면 ● 섭스에서 값 다 맞춰놨는데 엔진에서 또 만져야 하고 ● 작업자마다 느낌 다 달라서 통일이 안되고 ● 재질같은것들이 의도한대로 표현이 안됨 fake PBR 셰이더로는 PBR이 가진 장점을 발휘할 수 없음 결국 Roughness / Metalic 워크플로우 기반의 PBR 셰이더를 만들어야 한다!
  19. 19. 그래서 PBR 셰이더가 어떻게 계산되는지 공부 막 미마존에서 파는 PBR관련 책도 사서 보고 끙끙대다가 나는 그래픽스 프로그래머가 아니라 아티스트인데… 아티스트답게 해결해 보자! 하고 생각 아티스트에겐 ‘손’도 있지만 그보다 중요한 ‘눈’이 있다! 섭스턴스에서 머티리얼의 변화를 눈으로만 분석해보자! 근데 이책 좋아요 추천
  20. 20. 섭스턴스에서 값을 바꿔가며 변화를 체크해보니 알비도 / 러프니스 / 메탈릭 값의 변화에 따라 (인풋이 세개뿐. 게다가 메탈릭은 0/1만 사용) 변하는 값이 생각보다 몇개 없는것 같다 ● 스펙큘러 ● 큐브맵 ● 프레넬 이게 끝. 호오..? 전투력이 올라가는군요..?
  21. 21. 나는 아티스트니까 눈을 믿자 나믿눈믿 어차피 PBR도 진짜 물리적으로 계산하는 것도 아닌데 뭐 (근사값 대잔치) Albedo는 float3이니까 Luminance를 구하여 float로 치환하면 Albedo / Metallic / Roughness를 보간의 3항으로 사용할 수 있다. ● ex ) Specular = NdotH * lerp ( 0.5, 2, Luminance(Albedo)) ● ex ) Fresnel = (1-NdotV) * lerp ( 1, 0.2, Roughness) 이런 느낌으로 Albedo가 밝을때는 빛을 반사하므로 스펙큘러를 더 세게 해준다든지 표면이 거칠때는 프레넬 값을 감쇠시킨다든지 계산하면 되지 않을까?
  22. 22. 아티스트가 문제를 해결하는 두가지 길 1. 기술적으로 해결하거나 (머리가 고생) 2. 노가다로 해결하거나 (몸이 고생) 이번 경우(감마 PBR)는 기술적으로 답이 안나와서 스스로 생각하기에도 조금 미친짓을 해보기로 함 물리기반 셰이더와 똑같이 보이지만 전혀 안물리기반 셰이더를 만들어보기로 회사에서 내내 물리/수학 공부만 할 수 있는 상황도 아니고… 결과와 과정이 둘다 중요하지만 급하면 그런거 없다
  23. 23. 기왕 눈으로 보고 맞추는 김에 목표 대상은 섭스턴스 셰이더 유니티에서 섭스턴스와 다르게 나오는 것은 3D 아티스트의 오랜 고통 섭스턴스 페인터유니티 (감마) 그나마 최대한 비슷하게 맞춘게 이거...
  24. 24. 눈으로 보고 똑같이 만드는 것의 장점 복잡한 물리/수학 계산을 안해도 된다 감마든 리니어든 새로운 제3세계의 컬러스페이스든 눈으로 보고 맞추면 됨 HDR, 톤매핑 설정이 뭐든 간에 눈으로 맞추면 됨 독특한 라이팅 환경? 눈으로 맞추면 됨 눈매를 예리하게!
  25. 25. 일단 섭스턴스에서 모든 값을 캡쳐 메탈릭은 0과 1만쓰는것이 룰이지만 혹시나 중간값을 쓰는 경우가 있 을지도 모르니 보간으로 처리. (중간값은 캡쳐에서 뺀다) 베이스컬러가 0, 0.5, 1일때의 메탈릭 과 러프니스 값 변화에 따른 Specular, Fresnel, Cubemap Reflection 값의 변화를 체크한다 사실 PBR에서 이 세가지 리플렉션을 이렇게 따로 떨어트려 놓기는 애매하지만 셰이더에선 구현 편 의상 따로 나눌 것이기때문에 미리 따로 체크하도록 한다
  26. 26. 섭스턴스에서 각 패러미터 변화별로 이미지 캡쳐 베이스컬러가 0.5(회색) 일때 ● 금속은 반사가 강하고 비금속은 약하다 ● 비금속은 명암이 있지만 금속은 없다 ● 표면이 거칠수록 반사는 흐려지고 약해진다 ● 표면이 매끈할수록 스펙큘러가 좁아지며 밝기는 증가한다 ● 그래프는 정확한 수치가 아니라 의식의 흐름대로…
  27. 27. 섭스턴스에서 각 패러미터 변화별로 이미지 캡쳐 베이스컬러가 1(white)일때 ● 비금속일때 반사의 영향이 거의 없다 ● 금속일때는 디퓨즈가 없어서 그만큼 어두워지지만, 반사율이 높아 반사가 더 잘보인다 ● 금속 스펙큘러는 표면의 색에 영향을 받아서 흰색일때 굉장히 강하다
  28. 28. 섭스턴스에서 각 패러미터 변화별로 이미지 캡쳐 베이스컬러가 0 (Black)일때 ● 표면이 거칠면 금속은 완전 흑색이 되지만 비금속은 완 전 흑색이 되지 않는다. ● 비금속에서는 스펙큘러가 상당히 약해진다. ● 금속에서는 스펙큘러가 나타나지 않는다
  29. 29. 정리 - 디퓨즈 1. 비금속에는 디퓨즈(램버트)로 인한 명암이 생기지만 금속에는 없다. 2.금속일때는 디퓨즈가 없으므로 베이스컬러는 그만큼 어두워지고 대신 반사율이 높아진다 3. 베이스컬러가 어둡고 러프니스가 높아지면 금속은 디퓨즈와 리플렉션이 없어서 완전 흑색이 되지만 비금속은 디퓨즈가 있어서 살짝 밝다 Non Metal / Metal
  30. 30. 정리 - 스펙큘러 4.베이스컬러 색이 밝아질수록 스펙큘러가 강해진다 5.비금속의 스펙큘러 컬러는 흰색이고, 금속의 스펙큘러 컬러는 베이스컬 러(Albedo) * 라이트컬러 색이다 6. 그래서 금속의 베이스 컬러가 어두우면 스펙큘러가 나타나지 않는다 Non Metal / Metal
  31. 31. 정리 – 러프니스, 프레넬 7. 비금속도 매끄러우면 반사율이 조금 있다 러프니스가 0에 가까우면 미세면으로 인한 난반사가 많이 일어나지 않게 되어, 그만큼 리플렉션이 살짝 강해지기 때문. 하지만 금속만큼은 아니다 8. 프레넬은 금속/ 비금속 상관없이 어디에나 있다 roughness 0 / roughness 1 Non Metal / Metal
  32. 32. 왜 이런 결과가 나타나는지… 더 자세한 분석을 해보기 위해 PBR과 라이팅 모델에 대해서 간단히 알아보자 알고 만드는것과 모르고 만드는것은 분명 차이가 나기 때문
  33. 33. 간단 PBR 개념
  34. 34. PBR 개념 간단 정리 - Energy Conservation 디퓨즈 & 리플렉션 빛이 물체에 닿으면 일부는 반사, 일부는 산란, 일부는 흡수 1. 산란되는 녀석 - 디퓨즈 2. 반사되는녀석 - 스펙큘러, Fresnel등 3. 흡수되는 녀석 - Refraction(굴절), (뒷면에서 흡수) 투과 PBR에서 가장 중요한 것은 열역학 1법칙 (에너지 보존) Light >= Diffuse + Reflection + Refraction Albedo는 ‘반사’가 아니라 그냥 표면의 색일뿐 PBR에서는 굴절, 흡수는 생각하지 않고 크게 ‘디퓨즈’ 와 ‘리플렉션’ 만 생각한다
  35. 35. PBR 개념 간단 정리 - IBL ● 조금 더 사실적인 표현을 위해 디렉셔널 라이트에서 빛이 오는것이 아니라 큐브 맵 (환경맵) 에서 빛이 온다 (Image Based Lighting) ● 단일광원이 아니라 전방향광원 ● IBL source는 HDR로 만들어져 있어서 그 자체로 라이트를 포함하고 있다. (HDR - High Dynamic Range. 1이상의 밝기 정보를 포함)
  36. 36. PBR 개념 간단 정리 - 스펙큘러 ● HDR 환경맵 안에 포함되어있는 1 이상의 색상정보를 광원으로 인식하고 GGX나 베크만 방식 등으로 계산하여 환경맵의 밉맵에 그 결과값을 넣어놓 는다 (엔진이 해준다) ● 밉맵레벨이 높아지면 이렇게 계산된 스펙큘러를 볼 수 있다. ● 컨벌루전 타입을 Specular (Glossy Reflection) 으로 설정 ● 유니티 PBR에서의 스펙큘러는 HDR밉맵이 다가 아니라 디렉셔널 라이트 로 스펙큘러가 추가되기도 한다. ● 라이트로 추가된 스펙큘러도 GGX 밉맵 LOD만 제어해도 이렇게 스펙큘러가 GGX분포로 디렉셔널 라이트 두개를 추가해본 상태
  37. 37. PBR 개념 간단 정리 - Metallic 메탈릭 Metallic (금속성) 반사표를 보면 입사각이 90도에 가까울수록 모든 물체의 반사율이 올라감. (프레넬) 각도에 따라 변하는 비금속과 달리 금속은 입사각에 상관없이 거의 항상 위쪽 (반사율 높음) 반사율이 높아지면 에너지 보존 법칙에 의하여 Diffuse가 거의 없어짐 금속물질은 몇몇 파장을 흡수하므로 컬러 스펙큘러가 있다
  38. 38. PBR 개념 간단 정리 - Roughness 러프니스 Roughness (거칠기) 물체표면이 거칠면 거칠수록 • 난반사(Diffuse)가 심해지면서 • 정반사(Reflection)는 그만큼 약해짐 (빛의 총량은 같다) ( Diffuse 영향 up. Reflection 영향 down) 반사값 변화에 가장 큰 영향을 준다. 알기 쉬움
  39. 39. 라이팅 모델
  40. 40. 각 엔진들의 PBR구현 라이팅 모델 PBR에 대해서 알아보려면 라이팅모델에 대한 이해가 필수 출처 - https://blog.naver.com/PostView.nhn?blogId=tigerjk0409&logNo=221228897213 : 수학없는 PBS설명
  41. 41. 사실적인 표현을 위해 고안된 여러 라이팅 모델 Diffuse BRDF ● Lambert ● Oren - Nayer ● Disney Diffuse Reflection(Specular) BRDF ● Phong ● Blinn Phong ● Cook Torrance
  42. 42. BRDF? BTDF? BSDF? Bidirectional (양방향) Reflect (반사) Distribution (분포) Function (함수) 양방향(광원, 관찰자)간 반사 ‘분포’를 어떻게 할 것인지 계산하는 함수 사실 모든 라이트 모델이 양방향 반사계산을 하는 BRDF 모델 ● 디퓨즈 BRDF - 램버트, 오렌네이어, 디즈니 ● 리플렉션 BRDF - 퐁, 블린퐁, Ward , 쉬릭스, 쿡 토런스 PBR에서 디퓨즈는 램버트 or 디즈니 사용. 리플렉션은 쿡 토런스 모델 반사분포함수는 BRDF, 투과분포함수는 BTDF, 두개를 합쳐서 BSDF
  43. 43. 분포를 계산한다고요? 리플렉션이 분포 되어 있는 모양을 정의하는 함수 예를들어 블린퐁이라면 dot계산을 한번만 하니 cos 곡선의 분포대로 이미지가 결정될 것임. 계산에 따라 다양한 모양의 분포가 나오게 된다.
  44. 44. 디퓨즈 모델(1) - 램버트 Lambert ● 램버트 모델 - 가장 기본이 되는 실시간 디퓨즈 라이팅 모델 ○ 모든 방향으로 동일하게 난반사를 한다는 전제하에, 빛의 입사각만 고 려한 모델 ○ 물체 표면의 노멀과 빛의 방향과의 내적(Dot Product)을 이용하여 난반사(디퓨즈) 계산
  45. 45. 디퓨즈 모델(2) - 오렌 네이어 Oren-Nayer ● 오렌-네이어 모델 - 램버트에 미세표면(러프니스) 표현 추가 ○ 거친 표면의 diffuse를 구하기 위한 모델 ○ a값(러프니스)이 0일때는 램버트와 동일 ○ 러프니스가 증가하면서 램버트의 반전값과 (1 -NdotV : 림라이트같은 모양) 를 곱해준 값으 로 보간해준다 (빛이 퍼지는 것을 표현) ○ Lerp ( Lambert, Pow( (1-Lambert) * (1-NdotV/2) ,2) , Roughness) ○ (즉 러프니스가 올라갈수록 램버트의 영향력은 줄어들고 1-NdotV 의 영향을 받게된다) ○ 정통으로 구현하면 굉장히 복잡. 근사치를 사용하여 최적화한 구현
  46. 46. 디퓨즈 모델(3) - 디즈니 Disney ● 디즈니 BRDF ○ 램버트 방식은 관찰자의 위치가 고려되지 않았는데 이것을 고려해서 계산하는 방식. 또한 러프니스도 함께 고려한다 ○ 러프니스도 고려하여 계산 : 러프니스가 올라가면 오렌네이어처럼 빛이 퍼지는 효과가 나타난다. (램버트에서 1-NdotV의 모양으로 보간. 점차 1-NdotV의 영향력이 올라간다) ○ 계산량이 많아지므로 아무래도 무겁다 그 디즈니가 이 디즈니 맞음요 라푼젤 헤어 만들면서 고안한 모델 실제 첫 PBR 적용은 주먹왕 랄프 빛 회전 러프니스 값 변경시점 변화
  47. 47. 램버트, 오렌네이어, 디즈니 방식을 한번에 비교 러프니스값이 적으면 큰 차이가 없음. 러프니스 값이 늘어남에 따라 빛이 퍼지는 것이 다르다 (디즈니, 오렌네이어) 디즈니방식은 추가로 시점 변화에 따라서도 다르게 보임
  48. 48. 리플렉션 모델(1) - 퐁 Phong ● 퐁 반사 모델 ○ 카메라 방향과 빛의 반사 벡터와의 내적(Dot Product)을 이용 하여 스펙큘러 계산 ○ 반사 벡터 = -L + 2 * dot(N,L) * N (벡터의 투영을 이용하여 계산. Reflect()와 동일 ) ○ 빛이 앞에 있을때 정반사, 뒤에있을때 림라이트 느낌을 낸다 (실 제 빛과 비슷) – 물리적 정확성과 계산효율의 절충 모형 이건 Phong이 아니라 Pong 입니다
  49. 49. 리플렉션 모델(2) - 블린퐁 Blinn-Phong ● 블린 퐁 스펙큘러 모델 - 퐁에서 간략화! ○ 물체 표면의 노멀과 빛의 방향 + 카메라 방향 (하프벡터) 과의 내적을 이용하여 스펙큘러 계산 ○ 계산은 간략화 되었지만 퐁과 비교하면 광원이 휙 도는 부분(하 프벡터때문) 이 거슬림 ○ 퐁과 블린퐁은 모두 러프니스는 고려하지 않음
  50. 50. 리플렉션 모델(3) - 쿡 토런스 ● 쿡 토런스 모델 - 표면의 Roughness를 고려한 리플렉션 모델 ○ 공식 = 미세분포함수 * 기하감쇠 * 프레넬 / NdotV ○ 미세분포함수(D) - 미세면의 분포함수. 주로 베크만 방식이나 GGX방식을 사용한다 (스펙큘러의 ‘모양’을 계산 - Roughness를 이용하여 계산) ○ 기하감쇠계수(G) - 미세면에 입사한 빛이 다른 미세면에 그림자를 만드는 효과. (스펙큘러의 ‘퍼짐’을 계산 - 대부분 게임 엔진에선 Smith 방식을 사용 ) ○ 프레넬(F) - 측면에서 봤을때 반사율이 높아지며 밝아지는 효과. 원래는 꽤 복잡한 계 산이지만 근사로 구해도 별 차이 없음 (쉬릭스 방식) 출처 - Directx 9 셰이더 프로그래밍 (5-3. 금속 반사 모델) 이녀석이 NdotV
  51. 51. 리플렉션 모델(3) - 쿡 토런스 결국 기하 감쇠 계수(G)는 스미스 방식, 프레넬(F)은 쉬릭스 근사. 미세면(MicroSurface)의 D(Distribution-분포) 만 어떤 방식으로 계 산하느냐에 따라 결과가 달라진다 자세한 구현과 원리는 복잡하니 패스하고 요점만 ● Beckmann 분포 - 물리적으로 가장 정확하고 빠른 유형. ● GGX 분포 - 가장 큰 분산을 생성하며 금속의 정반사표현을 사실적으로 하고 싶 을때 사용한다. 베크만이든 GGX든 결국 코드 보면 거칠기(Roughness)를 이용해서 얼 마나 스펙큘러를 falloff 시킬것인지 계산하는것!
  52. 52. 다시한번 볼까요? 라이팅모델을 알고 다시 보면 조금 더 잘 보입니다. 유니티 (레거시) 스탠다드는 퀄리티 설정에 따라 Lambert / Disney 로 나뉘고, 언리얼도 Lambert를 주로 많이 쓰고 피부에만 Disney를 쓴다 출처 - https://blog.naver.com/PostView.nhn?blogId=tigerjk0409&logNo=221228897213 : 수학없는 PBS설명
  53. 53. 커스텀 PBR 구현준비
  54. 54. 섭스턴스 셰이더 구현 확인 C:Program FilesAllegorithmicSubstance Designer 5resourcesview3dshaderscommonpbr_ibl.glsl 을 열어서 확인 C:Program FilesAllegorithmicSubstance Designer 5resourcesview3dshaderslambertfs.glsl을 열어서 확인 미세노멀분포함수 : GGX사용 프레넬 : 쉬릭스 근사 사용 기하감쇠 : 스미스 방식 사용 쿡 토런스 디퓨즈 : 램버트 사용
  55. 55. 섭스턴스 셰이더와 게임엔진에서의 라이팅 환경 ● 섭스턴스 페인터 셰이더 = 섭스턴스 디자이너 셰이더 + 그림자 처리 ● 유니티에서는 그림자를 발생시키려면 라이트가 필요 ● 그림자는 보간으로 제어가능하게 해 두는 편이 좋음 (섭페도 이렇게 구현되어 있다) 커스텀셰이더 (그림자옵션추가)
  56. 56. 셰이더 작성 방식 : 커스텀 서피스 셰이더 왜 스탠다드가 아니라 커스텀 서피스 셰이더인가? ● 스탠다드는 감마에서 베이스컬러 재현력 떨어지고, 전체적으로 허옇게 나옴 ● 퍼포먼스 제어 가능 - 전처리, 멀티 컴파일과 셰이더피쳐를 이용하여 퍼포먼스 제어 ● 무엇보다 고치기 힘듦 왜 프레그먼트가 아니라 커스텀 서피스 셰이더인가? ● 다양한 환경에 대응하기 쉬움 (라이팅함수가 따로 있어서 포워드뿐 아니라 디퍼드까지 대응 가능) ● 포스트 프로세싱과도 잘붙음 - 프레그먼트는 분기별로 세팅을 잘 해주지 않으면 블룸제어가 어려움 ● 무엇보다 만들기 쉬움!!! - 아무리 좋아봤자 어려워서 만들지 못하면 도루묵
  57. 57. 내맘대로 계산하기 편하게 커스텀 라이팅모델 공식들을 다 대입하는것도 좋으나 섭스턴스와 다르게 보이면 말짱 꽝 이론을 베이스로 작업하되, 계산하기 쉽게 나눈다. ● 디퓨즈 : 섭스턴스 구현을 따라서 Lambert 방식으로 구현 (모바일 친화적) ● 리플렉션 : Specular / Cubemap(Metal / NonMetal) / Fresnel(Metal / NonMetal) PBR에서는 큐브맵이 라이팅 그 자체가 되지만 커스텀에서는 리플렉션을 계산하기 쉽게 성분을 나눠주도록 한다. 큐브맵 / 프레넬 / 스펙큘러 이렇게 나눈다 Lerp의 직관성을 위해 Roughness보다 Smoothness로 계산하고 추후에 반전하여 사용. 표면의 거칠 기가 높아질수록 리플렉션이 0에 가까워지니, Lerp(0, 1, Roughness) 보다 Lerp(0,1,Smoothness) 가 직관적이다. 계산하기 쉽게 CubeMap Reflection과 프레넬로 나눠줌 리플렉션
  58. 58. 스펙큘러 ● 큐브맵이 광원정보를 포함하고 있을 수도 있고 아닐 수도 있으므로, 큐브맵은 제외한 채로 스펙큘러 계산을 해 준다 ● 어차피 스펙큘러는 프로퍼티에서 제어 가능 ● 유니티 스탠다드 셰이더의 GGX 구현이 섭스턴스에 비해 좀 과한 구석이 있으므로 적당히 감쇠해서 계산 섭스턴스 디자이너 유니티 스탠다드 (감마) 과하다!
  59. 59. 선형보간, 비 선형 보간 보간의 3항은 아래 4가지 중 하나를 선택. ● 선형 (Linear) - 제일 많이 씀. ● 제곱(Pow) - Pow를 그대로 쓰면 무거우므로 직접 횟수만큼 곱해준다. 앞쪽값에 가중치 ● 제곱근(Sqrt) - 뒤쪽 값에 가중치를 두고 싶을때 ● 스무스스텝(SmoothStep) - 중간값보다 양쪽 끝에 가중치를 두고 싶을때
  60. 60. 유니티 씬 세팅 ● 컬러스페이스 감마 (추후에 리니어로도 전환) ● HDR 세팅 - 그래픽스세팅, 퀄리티 세팅, 카메라, 포스트 프로세싱 ● 라이트는 한개만 ● Environment Lighting (ambient) 값은 0.5 이하로 적당히 ● Environment Reflections 값은 0.5가 적절. 1로하면 너무 밝아진 다 ● 씬 세팅을 이상하게 하면 스탠다드 셰이더는 특히 굉장히 보기 흉해지 니 주의
  61. 61. 텍스처 병합 Albedo 의 알파채널에 Roughness 를 넣는다. PBR Texture 안에 AO, Metallic, Normal.xy를 넣는다. Normal.z 는 셰이더 안에서 계산. 이렇게 하면 총 5장의 텍스처를 2장으로 줄일 수 있다. 텍스처 샘플링수가 줄어들어 퍼포먼스 이득. 또한 메모리 사용량을 확 줄일 수 있다.
  62. 62. 구현결과와 과정
  63. 63. 섭스턴스와 아웃풋 비교 (1) 섭스턴스 디자이너 유니티 커스텀 유니티 스탠다드 (감마) Albedo : 1 Metalic : 1 Roughness : 0 Albedo : 1 Metalic : 1 Roughness : 1 어둡다!
  64. 64. 섭스턴스와 아웃풋 비교 (1) Albedo : 0.5 Roughness : 0 Metalic : 1 섭스턴스 디자이너 유니티 커스텀 유니티 스탠다드 (감마) Albedo : 0.5 Roughness : 0 Metalic : 0 어둡다!
  65. 65. 섭스턴스와 아웃풋 비교 (2) – 베이스1 메탈릭1 섭스턴스 디자이너 유니티 커스텀 유니티 스탠다드 (감마) 스펙큘러가 과하다! 프레넬이 없다!어둡다!
  66. 66. 섭스턴스와 아웃풋 비교 (2) – 베이스 0.5, 메탈릭 0 섭스턴스 디자이너 유니티 커스텀 유니티 스탠다드 (감마) 스펙큘러가 과하다!
  67. 67. 섭스턴스와 아웃풋 비교 (2) – 베이스 0.5, 메탈릭 1 섭스턴스 디자이너 유니티 커스텀 유니티 스탠다드 (감마) 어둡다! 프레넬이 없다!스펙큘러가 과하다!
  68. 68. 섭스턴스와 아웃풋 비교 (2) – 베이스0 메탈릭0 섭스턴스 디자이너 유니티 커스텀 유니티 스탠다드 (감마) 어둡다! 프레넬이 없다!스펙큘러가 과하다!
  69. 69. 섭스턴스와 아웃풋 비교 (2) – 베이스1 메탈릭0 섭스턴스 디자이너 유니티 커스텀 유니티 스탠다드 (감마) 이정도는 뭐…
  70. 70. 섭스턴스와 아웃풋 비교 (3) 섭스턴스 페인터 유니티스탠다드커스텀 섭스턴스 PBR 허옇다
  71. 71. 땅 셰이더도 커스텀 PBR로! 묘하게 칙칙하게 나오는 유니티 셰이더 선명하게 발색되는 커스텀 셰이더
  72. 72. 머티리얼 미리보기 최종 구현된 모습 ● 텍스처만 넣으면 옵션 건드릴 필요 없이 알아서 모두 계산된다. ● 옵션을 조절하고 싶다면 PBR Setting을 체크하면 상세 옵션이 나타나게 구현 (C#으로 ShaderGUI Editor 스크립트 구현) : 이렇게하면 GPU Instancing 항목이 나오지 않으 므로 추가 처리가 필요함 ● 체크해제하면 다시 중앙처럼 되고 변경한 값들은 다시 1로 고정됨 ● Using … Reflection 처리들은 최적화를 위한 처리들. 별 차이 없는 경우 계산하지 않게 ● 기본값은 모두 1로 맞춰놓음. 초기값이 헷갈리는 경우를 대비 ● 섀도우와 하프램버트, IBL Blur를 제외하고는 모든 값을 0~2 사이에서 제어하게 맞춰둠 짱 편하다!
  73. 73. 프로퍼티 설명 ● Roughness Amount : 러프니스 값 조절 (디버그용. 기본값 0 ) ● Metallic Amount : 메탈릭 값 조절 (디버그용. 기본값 1 ) ● Use Optimize : 각 리플렉션을 계산 할 것인가 (최적화) ● Use PBR Setting : PBR 커스텀 세팅을 사용 할 것인가 ● Normal Strength : Normal의 강도 제어 ● Shadow Amount : Cast Shadow & Receive Shadow 의 강도 ● Half Lambert Amount : 하프램버트 정도. 0일때는 램버트, 1일때는 하프램버트 ● Diffuse Boost : Diffuse Reflection을 보정할 수 있는 전체 보정값 ● Fresnel Power : 프레넬 영역 제어 ● Fresnel Intensity : 프레넬 밝기 제어 ● GGX Specular : 미세분포함수로 GGX를 사용. 디폴트는 BlinnPhong ● Specular Glossiness : 스펙큘러 번들거림 제어 ● Specular Intensity : 스펙큘러 밝기 제어 ● IBL Exposure : CubeMap Reflection 밝기 제어 ● IBL Blur Amount : CubeMap Reflection 흐려짐 제어
  74. 74. 커스텀 서피스 셰이더의 워크플로우 ● 버텍스 셰이더는 생략 (필요하다면 꺼내 쓸 수 있음) ● 픽셀셰이더는 Surf 함수와 Lighting 함수로 나뉘어 진다 ● Surf에서는 텍스처 샘플링 및 노멀Z계산, 메탈릭디퓨즈 계산 ● 다른 Reflection 처리는 전부 Lighting 함수로 넘겨서 계산 http://www.alanzucconi.com/2015/06/17/surface-shaders-in-unity3d/
  75. 75. 분기, 전처리 ● 필요한 옵션을 적당히 넣으면 된다. lightmap이 필요하면 해당 옵션을 지운다든지 ● 전처리로 인한 성능향상은 생각보다 크지 않다 ● 각종 최적화용 분기 따로 만들어 둠 ● 편의용 분기도 따로 만들어 둠 (옵션을 사용하지 않으면 기본값으로 자동으로 돌아감)
  76. 76. Surf 함수에서 해야 하는 일들 실질적인 리플렉션 구현은 Lighting 함수 안에 배치. Surf에서는… ● 텍스처 샘플링 및 서피스 아웃풋 연결 ● 노멀 z를 구하고 노멀강도 조절하는 프로퍼티 연결 ● 메탈릭속성을 띄면 프레넬이 증가하며 Diffuse반사가 거의 없어지는 부분 처리 ( Lighting 함수에서 계산하면 충분히 어두워지지 않는다) ● 러프니스 값에 따라 디퓨즈 영향이 바뀌는 부분은 그냥 눈으로 맞춤 메탈릭 수치 조절에 의한 디퓨즈 변화
  77. 77. Lighting 함수에서 해야 할 일들 디퓨즈 계산을 위한 ndotl, 스펙큘러 계산을 위한 ndoth, 프레넬 계산을 위한 ndotv를 미리 구해둔다. SurfaceOutpurPBR 으로부터 넘어온 값을 미리 변수에 담아둠
  78. 78. Lighting 함수 - 디퓨즈 리플렉션 ● 난반사는 ndotl을 이용한 램버트모델로 구현 ● 하지만 섭스 셰이더를 눈으로 봤을때는 하프램버트에 가까움 ● 눈으로 봤을때 비슷하니 하프램버트로 구현하되 램버트와 보간 가능하도록 설정 ● 어차피 만들어두면 음영이 강하게 지는 낮시간대 / 음영이 약한 밤시간대 제어를 할 수 있으니 프로퍼티로 빼둠 ● Surf 함수에선 금속성때문에 어두워지는 처리만 해 주었다면, Lighting 함수 에서는 Lambert 디퓨즈 리플렉션 계산을 해준다. ● Shadow 보간 처리도 해준다 하프램버트 수치 조절로 인한 디퓨즈 변화 섭스턴스는 NdotL이 약하게 들어가 있음 눈으로 봤을때는 HalfLambert 같은 느낌
  79. 79. Lighting 함수 - 큐브맵 리플렉션 ● 러프니스가 강해지면서 리플렉션이 블러리하게 보이는것은 멀티샘플링이 아니라 밉맵(LOD)을 활용. ● 리니어하게 하면 블러 단계가 초반에 확 일어나므로 sqrtSmoothness를 이용 (Roughness는 Smoothness의 반전값이라 sqrt가 초반가중치) ● 큐브맵이 HDR소스라면 HDR디코딩을 해야 색이 제대로 나온다. ● 편의를 위해 메탈 / 논메탈로 나누어 계산. 논메탈은 나중에 어두운 거친 표 면 표현때 또 쓰임. ● 애매한 부분은 눈으로 맞춤 밉맵 레벨 조절로 인한 리플렉션 블러
  80. 80. Lighting 함수 - 프레넬 ● 1-NdotV 계산(fresnelSrc) 에 Pow를 3정도 주고 (프로퍼티에서 0~6까지 조절가능하도록) 그냥 허옇게 더해지는 것이 아니므로 큐브맵 리플렉션을 곱해 준다. ● 금속/비금속일때, 베이스컬러가 어두울때 밝을때에 따라 예외상황이 많음 ● 위의 숫자들은 각 상황별로 눈으로 맞추면서 조절 ● 아예 제어하기 쉽게 금속성 프레넬과 비금속성 프레넬 두가지로 나눠서 구현 ● 마지막에 atten과 1을 0.5로 보간한 것은 그림자 부분에서 프레넬이 너무 밝게나와서 이상해지는 문제를 해결하기 위해 암부에 보정값을 넣은 것
  81. 81. Lighting 함수 - 스펙큘러 ● 스펙큘러는 성능에 따라 두가지 옵션중 선택가능하게 ○ 1. 블린퐁 스펙큘러 ○ 2. GGX 스펙큘러 ● 금속 / 비금속 에 따라 스펙큘러 컬러 달라지는 것 적용 ● 유니티(감마) 스탠다드 GGX 코드는 섭스턴스에 비해서 좀 과하므로 감쇠계산을 추가해줌 ● 라이트로 인한 스펙큘러가 거의 티가 나지 않을때는 최적화 옵션으로 꺼 주면 된다 GGX ON / OFF
  82. 82. Lighting 함수 - 스펙큘러 : 에너지 보존 ● 1 / (1 - smoothness) 를 해주어 Roughness 수치를 낮 게 가져갈수록 스펙큘러 영역이 아주 작은부분까지 줄어들도 록 구현 ● 스펙큘러 글로스니스가 올라갈수록 인텐시티도 같이 올라간 다 (에너지 보존 구현) ● Roughness나 Metalic 에 따른 보정값 계산 (눈으로 맞춤) 러프니스 조절에 따른 스펙큘러 값 조절
  83. 83. Lighting 함수 - 러프니스(스무스니스) 기반 병합 ● 1항은 IBL을 제외하고 전부 계산. (러프니스가 1일때이므로 IBL 이 나오지 않음) ● 2항은 IBL 위주로 계산 ● 어두운 비금속의 살짝 밝아지는 표현을 위해 빨간색 네모 안의 계산을 추가로 해줌 ● 3항에서 두번 곱하는것은 1항에 가중치를 두기 위함 ● 위 코드는 최적화 여지가 좀 더 있음
  84. 84. 이렇게 완성 섭스턴스 페인터 유니티 스탠다드 (감마)커스텀 섭스턴스 PBR 유니티 스탠다드 (리니어) V
  85. 85. 감마뿐 아니라 리니어에서도 눈으로 보고 맞춘다! 커스텀 PBR (리니어) 유니티 스탠다드 (리니어)섭스턴스 디자이너 IBL, Fresnel, Specular 에 곱해지는 값들 일부 수정하여 완성 V
  86. 86. 퍼포먼스 & 복잡도 체크 Xcode의 GPU 프로파일링을 이용하여 체크. 스탠다드 셰이더와 비교했을때 약 10%의 성능 향상 (모든 옵션 켠 상태) 유니티 스탠다드는 예상과 달리 생각보다 크게 무겁진 않았음
  87. 87. 유기체 확장
  88. 88. 기왕 이렇게 만든거 기능을 조금 더 추가해보자 PBR 셰이더의 약점(?)인 유기체 표현을 강화해보자! 피부 표현할때 음영이 너무 강하게 나오면 꽤 어색함. 후면에 SSS처리라도 해주면 조금 낫다 피부에 SSS, 머리카락에 Anisotropic Specular 공통으로 사용되는 코드가 많으므로 cginc를 만들어서 Include 하는 방식으로 구현하면 코드를 많이 줄일 수 있다.
  89. 89. CGINC 통합 관리 반복되는 데이터를 CGINC 파일로 몰아넣고 shader_feature 와 multi_compile 을 통한 분기처리 옷, 피부, 헤어, 눈, 프랍, 터레인등에 사용되는 다양한 계산들을 통합하여 관리 라이팅계산 수정할 일이 있을때, 각 셰이더에서 일일히 하지 않고 CGINC에서만 하면 된다
  90. 90. SSS의 원리 Sub Surface Scattering (표면하산란) 라이트 뒷쪽에서 피부에 빛이 투과되어 안쪽에서 산란이 일어나는듯한 느낌 두께(Thickness)맵을 이용하여 내부산란 계산을 근사함 두께맵 만드는 법 1. 모델의 면을 뒤집는다 2. AO맵 (혹은 Thickness맵 ) 을 굽는다 3. 구운 AO맵을 포토샵에서 반전해준다 출처 : https://www.alanzucconi.com/2017/08/30/fast- subsurface-scattering-2/ AO 반전 Thickness 반전
  91. 91. 구현 코드 SSS는 블린퐁에서의 하프벡터와는 다른 하프벡터를 쓴다. H = LightDir + ViewDir 가 아니라 H = LightDir + Normal * Distortion -H 벡터는 오른쪽이미지와 같이 빛을 받는 반대편에서 -L벡터를 향하게 되어 -L과 가까워질수록 세기가 약해짐 (반대편 림라이트같은 효과) 이 백라이트를 Thickness 맵과 곱해주어 두께가 두꺼운 부분은 나오지 않게 하고, 얇은부분만 투과가 되는것처럼 표현
  92. 92. 애니소트로픽 스펙큘러 (헤어) • 비등방성 • 입자들의 배치 상태에 따라 등방성/ 비등방성 재질이 결정 • 광선을 특정방향으로 왜곡하는 라이팅 모델 (보통 카지야 - 카이 모델을 이용한다) • 머리카락의 경우는 빛이 비추는 곳이 어둡고 외곽으로 퍼지면서 둥근모양을 그리며 밝음 • 앞에서 봤을때 가로, 위에서 봤을때 원형으로 생기는 스펙큘러 • 애니소트로픽은 빛을 받는 부분이 밝아지는 dot -> cos구현이 아님 • 빛을 받는 부분이 어둡고 점차 밝아지게 만들어야 함 -> sin으로 구한다!
  93. 93. 탄젠트, 바이 탄젠트 ● 노멀에 수직인 벡터를 탄젠트 라고 한다. (탄젠트 스페이스 노멀맵 말할때 그 탄젠트 맞음) ● 노멀에 수직이면 면에 접하므로 한국말로는 접선 ● 그렇게 치면 탄젠트 벡터가 한두녀석이 아니기때문에 그래픽스에서는 통상적으로 UV좌표와 비교하여 U좌표와 일치하는 벡터를 탄젠트, V좌표와 일치하는 벡터를 바이탄젠트라고 일컫는다 (바이노멀 보다 바이탄젠트가 맞는표현 - 바이탄젠트는 노멀이 아니라 탄젠트들중 하나이기 때문. ) ● 두번째 사진에서 빨간색이 탄젠트, 연두색이 바이탄젠트 ● 가로 스펙큘러를 넣어야 하는데 왜 탄젠트가 아니라 바이탄젠트? ● 가로벡터가 탄젠트이기때문에, 탄젠트 방향으로 스펙큘러가 향하려면 스펙큘러 모양은 세로로 긴 줄이 되어버림. 가로로 지나가는 스펙큘러를 구하려면 바이탄젠트 방향으로 구해야 한다. ● UV도 그래서 바이탄젠트방향(세로)으로 펴야 하는 것
  94. 94. 간단 구현설명 ● N과 T, N과 B는 직교(90도) 관계. ● dotTH는 T가 UV중 U벡터와 동일하므로 좌측으로 90도 회전 ● dotBH는 B가 UV중 V벡터와 동일하므로 아래로 90도 회전 ● 모양이 예상과 약간 다른것은 HalfVector이기 때문 ● 애니소트로픽은 dot에서 어두워진 부분 (90도 시프트) 을 반대로 밝게 만들어 주는것 ● dot은 |a||b|cosθ. 즉 코사인. 코사인의 90도 시프트는 Sin ● sinTH는 삼각함수를 사용하여 구할 수 있음 sinNH sinTH sinBH dotNH dotTH dotBH
  95. 95. 머리카락 스펙큘러 ● 머리카락은 보통 세로로 UV를 펴니 탄젠트가 아닌 바이탄젠트로 구해야한다. (세번째 구) ● Tanget -> Cross(Tangent, Normal) = BiTangent sinNH sinTH sinBH
  96. 96. 시프트 텍스처를 활용한 노멀 시프트 고주파, 저주파로 나눠 두번 겹침 (더해줌) 노멀 시프트, 포지션 옵셋 추가 • 노멀시프트 - 노멀을 위아래로 분산시켜준다 • 포지션 옵셋 – 고주파 스펙큘러의 위치를 컨트롤 해 준다 (라이트에 더해서 옵셋) 헤어는 알파소팅 문제를 해결하기 위해 2패스 디퍼드는 그랩패스를 추가해서 3패스
  97. 97. 커스텀 PBR 셰이더 장단점 정리 장점 1. 게임엔진에서 섭스턴스와 비슷한 느낌을 낼 수 있다 2. 디테일한 설정을 하고싶다면 PBR세팅 버튼을 누르면 된다 3. 세팅을 설정하기 귀찮다면 그냥 텍스처만 넣으면 된다 4. 가볍게 사용할 수 있다 (퍼포먼스, 메모리) 5. 감마, 리니어 어디에서든 퀄리티 저하 없이 사용할 수 있다 6. 복잡도가 낮아서 추가, 변경, 확장이 용이하다 7. 유기체 표현도 할 수 있다 단점 1.텍스처 병합이 귀찮다 2. cginc의 복잡도가 늘어날수록 셰이더 컴파일 시간이 오래 걸린다
  98. 98. 인용및 참고자료 라이팅모델 • Oren-Nayer (풍풍풍님, 포프킴님) – https://gamedevforever.com/93 , https://kblog.popekim.com/2011/11/blog-post_16.html • Disney – https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf • Phong – http://rapapa.net/?p=673 , https://en.wikipedia.org/wiki/Phong_reflection_model • Cook–Torrance – Dirext X 9 셰이더 프로그래밍, http://www.codinglabs.net/article_physically_based_rendering_cook_torrance.aspx , http://esprog.hatenablog.com/entry/2016/04/21/151242 , PBR • Lifeisforu 님의 그냥 그런 블로그 - https://lifeisforu.tistory.com/category/Graphics/Physically%20Based%20Rendering • Physically Based Rendering for Artist (Andrew Maximov님) - https://www.youtube.com/watch?v=LNwMJeWFr0U • 수학없는 PBR설명 (고정석님) - https://m.blog.naver.com/PostView.nhn?blogId=tigerjk0409&logNo=221228897213&proxyReferer=http%3A%2F%2Fm.facebook.com • PBR Diffuse Lighting for GGX + Smith microsurfaces - https://twvideo01.ubm-us.net/o1/vault/gdc2017/Presentations/Hammon_Earl_PBR_Diffuse_Lighting.pdf • Lighting Model (이진우님) - https://www.slideshare.net/JinWooLee2/lighting-model • Physically Based Rendering 기초!기초! (김혁님) - https://www.slideshare.net/Hybrid0/physically-based-rendering-51309337 그 외 • 감마가 어디감마 (대마왕님) – https://www.slideshare.net/jpcorp/ss-96115075 • SSS (Alan Zucconi님) – https://www.alanzucconi.com/2017/08/30/fast-subsurface-scattering-2/ • Hair Anisotropic (Kajiya – Kay) – http://developer.amd.com/wordpress/media/2012/10/Scheuermann_HairRendering.pdf
  99. 99. 끝 감사합니다

×