



재질(Material) 시스템을 추가 했습니다.
SurfaceMaterial이라는 객체명을 가지고 있으며 엔진에서 클라이언트에는 ISurfaceMaterial이라는 인터페이스만 노출합니다.
쉐이더 시스템, 블렌드 상태, 깊이-스텐실 상태, 래스터라이저 상태 값을 미리 Json 포맷으로 세팅해놓으면 해당 json파일을 읽어서 세팅된 쉐이더와 여러 렌더 상태들을 세팅합니다.
유니티와 비슷하게 만들되.. 자체 포멧보다는 json5 포멧으로 만들었습니다.
자체 포멧으로 만들면 파서도 만들고 파서를 검증하는 루틴도 만들고 복잡해집니다.
실제 게임을 빌드할때는 Json을 binary로 만들어서 빌드 합니다.
추후에는 왠만하면 직접 json을 작성하는 것보다는 툴에서 json을 제작/세팅 하는 방법으로 진행할 예정입니다. (데이터에 수작업은 최대한 지양 합니다)
쉐이더에 연관된 매테리얼 시스템을 제작할때는 유니티나 언리얼이나 대충 3가지로 나눠서 제작하게 됩니다.
프레임 시작할때 세팅하는 쉐이더 파라미터 값
패스가 시작할때 세팅하는 쉐이더 파라미터값.
라이트 뷰행렬, 렌더 그룹 속성에 맞는 세팅값(그림자패스, 라이팅패스, 파티클 패스, 모델 패스 등등)
그리고 드로우 할때마다 변경되는 값
각 오브젝트의 월드 행렬 (위치, 회전, 스케일), 각 오브젝트의 상태값 (맞았을때 깜빡이거나, 독에 걸려서 어둡게 만들거나, 죽어서 디졸브 처리하거나)
위와 같이 3가지 또는 4가지로 나눠서 쉐이더 상태를 조절합니다. 이건 D3D 예제나 언리얼5 같은 복잡한 엔진이나 결국 다 비슷하게 처리합니다.
상태 수정을 자주 할수록 퍼포먼스가 느려지기 때문에.. 상태가 비슷한것 끼리 최대한 묶어서 변경을 줄여주는데요.. 이걸 '배칭 렌더링' 또는 '배칭 처리' 라고 부릅니다. 묶어서 그린다.. 뭐 이뜻이죠
저는 유니티의 SRP Batcher와 비슷하게 가려고 애초에 계획 했기 때문에 그와 비슷하게 갑니다.
다만 유니티는 범용엔진이라 클라이언트에게 허용하는 범위를 아주 넓게 해서 어쩔수 없이 메모리를 좀 많이 먹는 스타일 입니다.
저는 마테리얼당 최대 176바이트의 유저가 세팅할수 있는 범위를 두고 고정 메모리 블럭으로 묶어서 메모리 재할당 등을 최대한 배제하면서 배치 처리가 되도록 설계했습니다.
그래도 뭐.. 176바이트면 할거 다 할수 있습니다. 넘어가면.. 컴파일 레벨과 실행 레벨에서 오류 로그를 뿜어 낼수 있도록 했습니다.
모든 재질 파일은 동기, 비동기로 로딩할수 있고.. json 재질 소스를 비동기로 로딩 콜 한 후 아직 로딩이 안된 시점에 SurfaceMaterial을 json소스 포인터를 넘겨서 마찬가지로 비동기, 동기 로딩을 걸어도 자동으로 내부적으로 json비동기 끝나면 그다음 로딩이 실행되도록 만들었습니다.
json파서는 yyjson이라는 오픈소스를 얇게 래핑해서 사용합니다. yyjson은 C언어로 만든 최고의 json파서이고.. 정말 빠릅니다. 심지어 내부 힙할당은 제 엔진의 CoreService의 mimalloc으로 작성한 core_heap.h에서 메모리 할당을 하게 만들어서 기본 yyjson 소스보다 더 빠릅니다.
이제 마테리얼 시스템을 1차 완료 했으니 여기서 한번더 굳히기를 들어갑니다. 안정화 시키고 필요한 API 목록 문서와 Material Format문서를 만들어야 합니다.
세상 참 편해진게 클로드 코드에게 제 엔진의 구조를 모두 파악 시켜서 알아서 만들라고 하면 됩니다. 예전에는 직접 다 만드느라 시간 많이 보냈는데 딸깍후 몇분이면 완성이 되니.. 생산성에서 엄청난 차이가 납니다.
이제 Material 시스템이 만들어지면 기본적인 UI시스템을 만들 차례 입니다.
감사합니다. 혹 여기까지 작업한 소스코드 필요하신분은 따로 메모 보내주시면 보내드릴께요.. ai와 작업한 md파일까지 다 묶어서 드릴수 있는데.. 아직 완성된 코드는 아니라. ㅎㅎ