primitive 화면에 그리기
C++ - Metal
Render Pipeline
MTL::RenderPipelineState
객체는 graphics state, vertex와 fragment shader fucntion을 정의한다. 이 객체에 필요한 모든 정보가 준비되고 command buffer에 commit되면 렌더링 파이프라인이 시작된다.
Rendering Pipeline의 단계는 다음과 같다.
- Vertex Fetch
- Vertex Processing
- Primitive Assembly
- Rasterization
- Fragment Processing
- Framebuffer
위에서 vertex processing과 fragment processing은 프로그래머에 의해(shader) 조작될수 있는 단계이며 나머지는 자동으로 진행된다. 일련의 단계(stage)를 거치며 좌표로 이루어진 vertex data가 다른 형태의 데이터로 변한다.
Vertex Fetch
Metal buffer로부터 primitive data(triangles, lines, points)를 읽어 Scheduler unit으로 전달한다.
Vertex Processing
Vertex data들이 사용자에 의해 정의된 연산에 의해 계산된다. 조명 효과 계산(lighting), 변환(transformation), texture mapping이 진행된다. Distributer라는 하드웨어 유닛에 의해 정점 block들이 Primitive Assembly로 전달된다.
Primitive Assembly
Vertex Processing 단계에서 전달된 vertex block들이 지정된 primitive로 조립(assemble)된다. Metal API는 다섯 가지의 primitive를 제공한다. Patch
Point
Line
Line Strip
Triangle
Triangle Strip
이다.
Strip은 여러 개의 점을 한 번에 연결하여 전달하여 기본 도형을 만든다.
Rasterization
화면에 출력해야할 장면(2D, 3D)을 픽셀(2D)로 표현한다. 임의의 두 정점 사이의 기울기를 계산하고 그룹화하여 primitive를 구성한다. 그리고 가시성 테스트를 진행하여 화면에 출력되지 않아도 되는 부분을 계산한다. 마지막으로 각 fragment의 속성값을 계산한다.
Fragment
픽셀 한 개의 색을 표현하기 위한 데이터 집합이다. 일반적으로 다음과 같은 정보가 포함된다.
- 픽셀의 위치
- 색상
- depth
- 법선 벡터
phong shading
각 fragment에서의 법선벡터는 각 정점에서의 법선벡터를 보간하여 구한다. -> O(3KN)
그리고 각 픽셀에서의 색을 계산한다.
goraud shading
각 fragment에서의 색은 각 정점에서의 색을 보간한다. -> O(KN)
(K는 픽셀의 수, N은 정점 개수)
Fragment Processing
모든 fragment의 색을 계산하여 framebuffer에 저장한다.
렌더링 과정 요약
Renderer 객체 생성
애플리케이션이 시작될때(main event loop 시작 직후) applicationDidFinishLaunching
함수가 ViewDelegate
객체를 생성한다. ViewDelegate
객체의 생성자가 Renderer
객체를 생성한다.
Renderer::buildShaders
-MTL::RenderPipelineDescriptor
객체 초기화Renderer::buildBuffers
-Mesh
객체와MTL::RenderPipelineState
객체 초기화 -> RenderPass 객체- Mesh - vertexBuffer와 colorBuffer를 가진다.
renderPass 객체에 MTL::RenderPipelineDescriptor
를 연결한다.
Renderer::draw 함수 실행
60FPS라면 이 함수는 1초에 60번 호출된다.
CommandBuffer
객체는 MTLCommandEncoder
객체를 포함한다. MTLCommandEncoder
객체는 GPU에서 실행될 작업의 유형을 지정한다.
MTL::RerderCommandEncoder
- GPU에서 렌더링 작업을 수행MTL::ComputeCommandEncoder
- GPU에서 계산 작업을 수행
Renderer 객체가 생성될때 buildShaders 함수에 의해 생성된 renderPass 객체에 담긴 정보를 MTL::RenderCommandEncoder
객체에 전달하고 primitive의 종류를 결정한다.
commit하여 그래픽카드에게 작업을 지시한다.
Comments