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 이다.

what is 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하여 그래픽카드에게 작업을 지시한다.

실습 결과

실습 결과

reference

Tags:

Categories:

Updated:

Comments