MPipeline 프레임워크
요약
MPipeline 프레임워크는 Unity 그래픽 프로그래머가 SRP를 활용하여 자체 렌더링 파이프라인을 개발할 수 있도록 돕는 디자인 패턴입니다. 이 프레임워크는 객체 지향 기반이며, ScriptableObject와 이벤트 시스템을 사용하여 결합도를 낮추고 팀 작업의 효율성을 높이는 데 중점을 둡니다. 본문은 초보자를 위한 'Helloworld' 튜토리얼을 통해 실제 구현 과정을 안내합니다.
핵심 포인트
- SRP를 활용한 자체 렌더링 파이프라인 개발 디자인 패턴 제공
- ScriptableObject와 이벤트 시스템으로 결합도를 낮추고 관리 용이성 확보
- Job System 지원 및 Unity Editor의 serialize 시스템 사용
- 튜토리얼을 통해 실제 'PureScreen' 구현 및 메인 파이프라인 연결 방법 제시
MPipeline Framework
개요:
- MPipeline 프레임워크는 Unity 그래픽 프로그래머가 SRP를 사용하여 자체 렌더링 파이프라인을 개발하기 위한 디자인 패턴입니다. 이러한 디자인 패턴을 개발하는 목표는 팀 작업의 효율성을 높이고, 다양한 렌더링 부분 간의 결합도를 줄이며, 프로젝트 리소스 관리를 돕는 것입니다. MPipeline은 객체 지향 기반 프레임워크로, Unity Editor의 serialize 시스템을 사용하여 데이터 저장 및 관리를 합니다.
특징:
- Scriptable Rendering Pipeline에 최적화되어 설계됨
- Job System 지원
- Toolbox 및 유틸리티 함수 지원
- 이벤트 시스템 디자인을 기반으로 하여 높은 수준의 결합도를 줄임.
초보자를 위한 튜토리얼:
1. Helloworld!
이 튜토리얼을 읽기 전에, 여러분은 이미 SRP와 CommandBuffer의 기본 API를 학습했기를 바랍니다. 첫 번째 "Helloworld" 이벤트는 순수 색상을 화면에 그리는 것이며, 이는 비교적 쉽게 할 수 있습니다. 먼저 "PureScreen.cs"라는 새 스크립트를 만들고 다음과 같은 코드를 작성합니다:

우리가 살펴볼 것은 이 줄들입니다. 선언했듯이, 모든 렌더링 이벤트는 ScriptableObject일 것이므로, 개발 중에 에디터에서 반드시 이러한 인스턴스를 생성하고 싶습니다. 그래서 다음과 같이 합니다: [CreateAssetMenu(menuName = "Demo/Pure Screen Color")]. 프로젝트 창에서 쉽게 하나를 만들 수 있습니다. 그런 다음 FrameUpdate 메서드에 두 줄의 코드를 작성할 것입니다. 이 메서드는 나중에 메인 파이프라인에 의해 호출되어 화면을 렌더 타겟으로 설정하고 이를 반(半)파란색, 반(半)녹색 색상으로 지웁니다. 필요한 경우가 아니라면 CommandBuffer를 수동으로 실행할 필요는 없습니다. 메인 파이프라인 코드가 대신 처리해 줄 것입니다.
프로젝트 폴더에 ScriptableObject 인스턴스를 가진 후, 두 번째 단계인 메인 파이프라인의 리소스를 생성하는 것을 시작할 수 있습니다. 프로젝트 창에서 마우스 오른쪽 버튼을 누르고 "Create Assets/MPipeline/Create Resources"를 클릭하면, 메인 파이프라인의 ScriptableObject가 주어집니다. 이것을 열면 다음과 같아야 합니다:

이전에 생성한 PureScreen 객체를 'Demo Pipeline Events' 배열로 그림에서 보여준 것처럼 드래그하면 첫 번째 파이프라인 구축이 완료됩니다! 이 객체는 이제 메뉴의 'Edit/Project Settings/Graphics'에 드래그할 수 있습니다. 하지만 이 파이프라인을 어떻게 사용해야 할까요? 답은 매우 간단합니다. 대상 카메라에 'PipelineCamera.cs' 컴포넌트를 추가하기만 하면 됩니다. 그러면 이 카메라는 사용자 지정 파이프라인에서 사용할 수 있게 됩니다. PipelineCamera.cs에는 'rendering path'라는 열거형(enum) 설정이 있는데, 이는 레거시 렌더링 파이프라인의 Camera.RenderingPath와 같습니다. 즉, unlit, forward, deferred 등과 같이 카메라마다 여러 다른 렌더링 경로를 가질 수 있다는 의미입니다. 이에 대해서는 나중에 논의하겠습니다.
2. 속성(Property)!
속성을 갖는 것은 렌더링 파이프라인에서 가장 중요한 단계입니다. 머티리얼(material)과 마찬가지로, PostProcessing이나 Skybox 모두 머티리얼이 필요합니다. 이제 렌더링 이벤트 내부에 속성 또는 여러 개의 속성을 생성하는 방법을 보여드리겠습니다. helloworld 단계에서는 'Init', 'CheckProperty', 'Dispose'라는 세 가지 메서드가 있는 것을 볼 수 있는데, 이는 메인 파이프라인이 초기화되고 해제될 때 호출됩니다. MonoBehaviour 클래스의 Awake와 OnDestroy와 같습니다. CheckProperty 메서드는 Unity 에디터가 실수로 네이티브 속성을 제거하거나 해제하는 것을 방지하도록 설계되었으며, 이 메서드는 에디터 모드에서만 호출됩니다. 따라서 Init 메서드 내부에 속성을 생성하고, 필요하다면 Dispose 메서드에서 이를 해제할 것입니다. 예를 들어, helloworld를 다시 수행하기 위해 머티리얼을 사용해 보겠습니다:

보시다시피, 우리는 일반 직렬화된 값인 "unlitShader"에서 재질을 로드하고 있습니다. PipelineResources에도 일부 속성을 저장하고 로드할 수 있습니다. PipelineResources에 리소스를 저장하는 장점은 개발팀이 고유한 리소스를 관리할 수 있다는 것이고, 단점은 이러한 동작이 더 많은 결합(coupling)을 초래할 수 있다는 것입니다. 현재는 데모를 위해 지역 변수에서 재질을 생성하기만 했습니다. 코드를 컴파일한 후에는 새로운 셰이더를 리소스에 추가하고 파이프라인을 로드할 수 있습니다 (작업을 할 때는 항상 파이프라인을 언로드해야 합니다. 그렇지 않으면 오류나 충돌이 발생할 수 있습니다):

3. SRP의 API 사용!
앞서 선언했듯이, MPipeline은 SRP 기반 프레임워크이므로, 구조체인 PipelineCommandData에서 필요한 데이터를 전달했습니다:

주석이 충분히 명확하므로, 화면에 간단한 순수 색상 파이프라인을 그릴 수 있습니다:

여기에는 매우 간단하고 명확한 데모 코드가 있으며, 태그가 "LightMode" = "Unlit"인 단일 패스만 그리면 됩니다. 결과는 다음과 같이 보입니다:

기능:
이벤트 종속성:
우리는 결합을 피하기 위해 이러한 디자인 패턴을 사용하려고 노력하고 있지만, 깊이 텍스처(depth texture)와 같이 유용하고 필요한 일부 결합은 존재합니다. 예를 들어 SSAO 후처리(post processing)는 깊이 맵(Depth Map), 법선 맵(Normal Map), 스페큘러 맵(Specular Map) 등 지오메트리 버퍼(Geometry Buffer)가 필요할 것입니다. 하지만 이 맵들은 이전 이벤트에서 생성되었기 때문에, 만약 GBuffers가 없으면 만족스럽지 않은 결과가 나올 것이므로, 우리는 다른 이벤트에 대한 종속성 표시를 갖고자 합니다:

RequireEventAttribute를 사용하면 메인 프레임워크가 렌더링 경로 목록에서 대상 이벤트 유형을 찾았을 때, 이 두 이벤트 사이에 연결이 생성됩니다. 이 예시에서는 'LightingEvent'가 비활성화되면 항상 'VolumetricLightEvent'도 비활성화되므로, 'Enabled' 속성은 항상 False가 됩니다.
다른 이벤트를 가져오는 것도 때로는 필요하기 때문에 다음과 같은 API를 갖추고 있습니다:
MPipeline.RenderPipeline.GetEvent<T>(PipelineResources.CameraRenderingPath path) where T : PipelineEvent
MPipeline.RenderPipeline.GetEvent(PipelineResources.CameraRenderingPath path, Type targetType)

여러 렌더링 경로 사용하기:
위에서 언급했듯이, 일반적으로 하나의 프로젝트에는 다양한 유형의 렌더링 경로가 있을 수 있습니다. PipelineResources.cs의 소스 코드를 변경하여 쉽게 여러 렌더링 경로를 가질 수 있으며, 먼저 PipelineResources.cs의 열거형(enum)에 사용할 수 있는 여러 경로를 추가해야 합니다:

현재는 PipelineCamera.cs에서 경로를 선택할 수 있게 되므로, 전역 딕셔너리에 PipelineEvent 배열을 추가해야 합니다:

Job 시스템 지원:
멀티스레딩을 통해 성능상의 이점을 얻을 수 있는 일부 계산을 수행하기 위해 job system을 사용하고 싶습니다. job system을 사용하려면 PipelineEvent.cs의 PreRenderFrame 메서드를 오버라이드하여 작업(job) 일정을 잡을 수 있으며, JobHandle.ScheduleBatchedJobs()는 모든 PreRenderFrame 메서드가 완료된 후 그리고 어떤 FrameUpdate 메서드가 시작되기 전에 호출됩니다. Unity 공식 튜토리얼에 따르면 ScheduleBatchedJobs를 가능한 적게 호출해야 하므로, 예약된 job들은 함께 배치되어야 합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 GitHub GameDev의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기