Successfully reported this slideshow.

정희석, 셰이더 리소스 빌드 자동화 할 수 없나요?, NDC2013

2,199 views

Published on

Published in: Technology
  • Be the first to comment

정희석, 셰이더 리소스 빌드 자동화 할 수 없나요?, NDC2013

  1. 1. 셰이더 리소스 빌드 자동화 할 수 없나요?넥슨 N스퀘어개발본부W엔지니어링팀정희석2013. 04.24
  2. 2. 버블파이터마비노기2정희석blackclover@nexon.co.kr20082011
  3. 3. 이 발표는새로운 기술에 대한 내용이 아니라직접 구현에 따른 경험 공유
  4. 4. 셰이더 코드 조합컴파일빌드 시스템 및 바이너리 최적화목차
  5. 5. 셰이더 코드 조합
  6. 6. 작은 코드 블럭을 더해가는 방식Micro ShaderUber ShaderShader Editor (Material Editor)일반적으로 사용하는 코드 조합 방식
  7. 7. 모든 기능을 가진 코드에서 기능 별로 빼가는 방식Micro ShaderUber ShaderShader Editor (Material Editor)일반적으로 사용하는 코드 조합 방식
  8. 8. 전용 툴 사용하여 Code GenMicro ShaderUber ShaderShader Editor (Material Editor)일반적으로 사용하는 코드 조합 방식
  9. 9. 마비노기2는 in-house rendering engine요구 기능의 상한에 대해 고려 가능관리 가능한 조합 개수 예측전담 프로그래머 직접 관리
  10. 10. 더하기 조합 빼기 조합혼합하여 사용#include “...”#include “...”#if …#endif
  11. 11. #include “CommonStage.shader”#include “MeshStage.shader”#if CompileOption.VTLighting.Enable#endif…………#if CompileOption.VTSkinning.Enable#endif#if CompileOption.Shadow.Enable#endif#if CompileOption.MotionBlur.Enable#endif………………
  12. 12. 옵션을 조절하는 메타데이터 파일.ShaderSetting옵션 중복 기록을 피하기 위한 상속 관계LOD 관리
  13. 13. ShaderSetting [.Version = 1.BaseSetting = “CommonMesh”LOD [CompileOptions [CompileOption [.Name = “AlphaTest.Enable”.Value = true]…]]LOD […]]LOD 0LOD 1상속부모에도 옵션이 있다면값을 Override
  14. 14. 하지만 렌더러, 머신 환경에 따른 조합은 고려 하지 않음이렇게 조합을 통해 실제 컴파일 하여 사용하는 셰이더는약 60개
  15. 15. Cloth.shader캐릭터 렌더러 프랍 렌더러서로 다른 조합 옵션 필요
  16. 16. VTMeshRenderer.ShaderSettingStaticMeshRenderer.ShaderSetting……렌더러 전용 ShaderSettingC++에서렌더러별로 오버라이드
  17. 17. 그래픽 카드와 같은 머신 환경 마다 다른 분기셰이더 코드에서#if Platform.* ~ #endif 형태머신 환경을 반영하여전처리 과정에서 치환C++에서
  18. 18. 개발 편의그래픽 환경 설정일반 옵션도 전역으로 변경이 필요한 경우C++에서예외적으로 적용
  19. 19. 셰이더 컴파일
  20. 20. 사용 시점에 실시간 컴파일?
  21. 21. 초기 로딩 시 느린 응답 속도
  22. 22. 3 Step 비동기 로드전처리 태스크컴파일 태스크CreateShader태스크#include처리, 옵션 값 치환컴파일 하여 바이너리 생성(가장 오래 걸림)DirectX 접근
  23. 23. 3 Step 비동기 로드전처리 태스크컴파일 태스크CreateShader태스크[백그라운드][백그라운드][메인]
  24. 24. 이제 셰이더 로딩 중에도 클라이언트 응답은 한다그러나 여전히 진행은 느리고반복되는 로딩에 의한 생산성 저하
  25. 25. 매번 로딩을 하지 않게 하면 되겠지?
  26. 26. 컴파일 된 바이너리를 파일로 저장이름바이너리 Key조합된 소스코드의 해시 값최초 한번만 로딩, 이후에는 저장된 바이너리 로드
  27. 27. 반복 실행 시 빨라진 로딩 속도
  28. 28. 여전한 문제바이너리 존재 여부 체크를 위해 전처리 작업 필요조합의 수만큼 바이너리 파일들이 생김릴리즈 문제
  29. 29. 빌드 시스템 및 바이너리 최적화
  30. 30. 빌드 서버CruiseControl.NETSource ControlPerforce프로젝트 빌드 시스템 구성
  31. 31. 최적화 및 릴리즈를 위해사용할 바이너리를 미리 빌드 해놓자그런데 어떤 조합으로 빌드를 시켜야 할까?
  32. 32. 완전한 자동화 시키고 싶으니각 옵션 예상 값들을 모두 조합 시켜보자
  33. 33. #include “CommonStage.shader”#include “MeshStage.shader”#if CompileOption.VTLighting.Enable#endif…………#if CompileOption.VTSkinning.Enable#endif#if CompileOption.Shadow.Enable#endif#if CompileOption.MotionBlur.Enable#endif……truefalsetruefalsetruefalsetruefalse조합이 많지만시도...
  34. 34. 컴파일 실패 속출모든 조합으로 컴파일을 해보니…당연히 여러 기능들을 분류 하다 보니컴파일 되지 않는 조합 존재
  35. 35. 그래서 컴파일 되지 않는 조합은Skip 해가며 진행 시도
  36. 36. 3시간이 넘도록 컴파일이 끝나지 않았다
  37. 37. C++에서 제어하는 조합의 범위를조합 목록을 자동으로 결정하는 것은 힘들다고 판단수동으로 관리하기로 결정
  38. 38. ShaderBuild [.ShaderSetting = "Shader://VTMeshRenderer.shaderSetting"BuildOptions [BuildOption [.Name = "VTLighting.Enable"Build .Value = trueBuild .Value = false]BuildOption [.Name = "VTSkinning.Enable"Build .Value = trueBuild .Value = false]…빌드 할 옵션 값 리스트Permutation 조합렌더러 세팅
  39. 39. 빌드 되는 바이너리 최적화 필요?
  40. 40. 앞에서 컴파일 된 바이너리를 조합 수만큼 파일로 저장하고저장된 바이너리를 다시 읽어 오는 경우2. 소스코드가 다르더라도 바이너리가 같을 수 있음1. 저장된 바이너리를 찾기 위해서 소스코드 조합을 마쳐야 함
  41. 41. 굳이 옵션 조합 결과인 소스코드로 구분할 필요가 없다해당 소스코드를 만드는 것은 조합 옵션 리스트다
  42. 42. 바이너리 Key옵션 리스트의 Hash값이름 CompileOption.Lighting.Enable=True,CompileOption.Skinning.Enable=False,……
  43. 43. 바이너리들을 번들 파일로 통합
  44. 44. 번들 파일 구조 (x 셰이더 수)Version옵션 리스트 Hash값 : File Offset옵션 리스트 Hash값 : File Offset…바이너리바이너리…OffsetOffsetOffset
  45. 45. 각 번들 파일 별 용량: 약 700kb빌드 결과총 용량: 약 50mb빌드 시간: 약 1시간 ~ 1시간 반 정도
  46. 46. 이제까지 셰이더는 DX Effect 포맷 사용VS, PS를 구분해서 최적화를 할 수가 없다컴파일이 편하다테크닉
  47. 47. HLSL로 VS, PS 따로 컴파일을 하고테크닉 정의를 자체 포맷으로 만들자
  48. 48. Technique구문은 DX9이 아닌 DX11 기반메타 데이터였던 ShaderSetting에 정의
  49. 49. Techniques [Technique [.Name = "Default"Passes [Pass [.RasterizerState = "NoCull".DepthStencilState = "DepthTestOnly".BlendState = "AlphaBlend".SamplerStatePS0 = "PointClamp".VertexShader = "DefaultVSMain".PixelShader = "DefaultPSMain".HullShader = "null".GeometryShader = "null".DomainShader = "null"컴파일 할 메인 함수DX9에선 사용 안 함State는 따로 정의
  50. 50. 번들 파일을 다시 최적화 해보자이제 서로 다른 셰이더 파일 조합끼리도같은 VS, PS 바이너리를 사용할 수 있다
  51. 51. 번들 인덱스 파일 구조 (x 셰이더 수)Version옵션 Hash값 : File Offset옵션 Hash값 : File Offset…함수이름 : 바이너리 File Offset함수이름 : 바이너리 File Offset…OffsetOffsetOffset번들 바이너리 파일 구조 (1개)Version바이너리…OffsetOffsetOffset바이너리
  52. 52. 빌드 결과바이너리 파일 용량: 약 700kb인덱스 파일 용량: 개당 약 70kb총 용량: 약 3MB
  53. 53. 서버 부하와긴 빌드 시간 때문에데일리 빌드로 새벽에 수행CruiseControl.NET 으로 빌드 시스템에 등록
  54. 54. 빌드된 바이너리를찾을 수 없다고에러가 나요에러나요!연봉협상할 때 보자
  55. 55. 수동으로 관리 하던 빌드 리스트에 항목이 누락되었나?
  56. 56. 알고 보니 누군가 셰이더를 고쳐서 체크인다시 빌드만 하니 정상 동작
  57. 57. 새로운 조합에 대한 리스트 추가가 필요한지단순히 빌드가 안된 것인지
  58. 58. 빌드 전략 수정작업자빌드 서버1. 코드 체크인2. 로컬로 컴파일하도록 클라이언트 Config On팀원3. 문제 없이 실행4. 새벽 빌드 후 다시 클라이언트 Config off
  59. 59. 정말 조합이 없을 때만 오류가 발생그 때 새로운 조합만 추가해주면 됨
  60. 60. 요약
  61. 61. 요약- 관리하기 쉽게 적절한 기준으로 조합 룰을 정하자- 리소스 로드는 응답속도 빠르도록 최적화 하면 할 수록 좋다- 복잡한 시스템 때문에 완전한 빌드 자동화를 하기 힘들다면문제점을 찾기 쉽고, 관리가 편리한 시스템을 구성하자
  62. 62. 감사합니다

×