[Metal] Apple의 Metal 입문하기

2025. 11. 2. 16:00·Apple/Metal
728x90
반응형

안녕하세요! 피피아노입니다 🎵

 

iOS 개발을 하시는 분들 중에 그래픽이나 게임 관련을 작업하시는 분들이라면 한번 쯤은 들어보셨을 Metal에 대해서 포스팅을 작성해보려고 합니다.

 

Metal은 2014년에 애플이 공개한 API로 그래픽 성능을 최대한 끌어올리기 위해 만든 API입니다.

 

물론 그 전에는 그래픽 성능을 끌어올리기 위한 방법이 없었던 건 아니고 OpenGL(Open Graphics Library)이라는 게 있었는데 2018년도부터 OpenGL이 deprecate가 되어서 더 이상 쓰이지 않게 되었습니다.

 

OpenGL ES는 여러 플랫폼에서 동작하는 범용성을 추구합니다. 하지만 Metal은 애플 생태계에 특화되어 설계되었습니다.(애플이 만들었으니 당연한 말 같기도..)

 

Metal의 핵심 구성 요소

Metal 앱을 구축하려면 7개의 핵심 컴포넌트를 이해해야 합니다.

MTLDevice - GPU와의 연결 고리

var device: MTLDevice!
device = MTLCreateSystemDefaultDevice()

MTLDevice는 GPU와 소통하는 일종의 창구입니다. 모든 Metal 객체는 이 디바이스를 통해 생성됩니다. 컴퓨터의 메인보드처럼 모든 컴포넌트가 연결되는 중심점이라고 생각하시면 됩니다.

CAMMetalLayer - 화면에 그리는 캔버스

iOS에서 화면에 표시되는 모든 것은 CALayer 위에 그려집니다. Metal을 사용하려면 특별한 레이어인 CAMetalLayer가 필요합니다.

metalLayer = CAMetalLayer()
metalLayer.device = device
metalLayer.pixelFormat = .bgra8Unorm
metalLayer.framebufferOnly = true

픽셀 포맷 설정이 흥미로운데, bgra8Unorm은 각 색상 채널에 8비트씩 할당하고 정규화된 값(0~1)을 사용한다는 의미입니다.

 

버텍스 버퍼 - 형태를 정의하는 데이터

3D 그래픽의 모든 것은 삼각형으로 이루어집니다. 복잡한 모델도 결국 수많은 삼각형의 조합입니다.

let vertexData: [Float] = [
   0.0,  1.0, 0.0,  // 상단 꼭짓점
  -1.0, -1.0, 0.0,  // 좌하단
   1.0, -1.0, 0.0   // 우하단
]

Metal의 좌표계는 정규화되어 있어 화면 중앙이 (0, 0)이고 좌하단이 (-1, -1), 우상단이 (1, 1)입니다. 이 데이터를 GPU가 이해할 수 있도록 MTLBuffer로 변환해야 합니다.

쉐이더 - GPU에서 실행되는 미니 프로그램

쉐이더는 GPU에서 실행되는 작은 프로그램입니다.

C++과 유사한 Metal Shading Language로 작성됩니다.

버텍스 쉐이더

버텍스 쉐이더는 각 꼭짓점마다 한 번씩 호출되어 위치를 계산합니다.

vertex float4 basic_vertex(
  const device packed_float3* vertex_array [[ buffer(0) ]],
  unsigned int vid [[ vertex_id ]]) {
  return float4(vertex_array[vid], 1.0);
}

프래그먼트 쉐이더

화면의 각 픽셀(프래그먼트)마다 호출되어 색상을 결정합니다.

fragment half4 basic_fragment() {
  return half4(1.0);  // 흰색 반환
}

렌더 파이프라인 - 모든 설정 결합

렌더 파이프라인은 쉐이더와 각종 설정을 하나로 묶은 객체입니다. Metal의 큰 장점 중 하나는 이 파이프라인을 미리 컴파일하여 실행 시 오버헤드를 최소화한다는 점입니다.

let pipelineStateDescriptor = MTLRenderPipelineDescriptor()
pipelineStateDescriptor.vertexFunction = vertexProgram
pipelineStateDescriptor.fragmentFunction = fragmentProgram
pipelineStateDescriptor.colorAttachments[0].pixelFormat = .bgra8Unorm

커맨드 큐 - GPU 작업 대기열

커맨드 큐는 GPU에 전달할 명령들을 순서대로 관리합니다.

commandQueue = device.makeCommandQueue()

 

렌더링 프로세스

실제 렌더링은 매 프레임마다 아래 단계들을 거치게 됩니다.

1. 디스플레이 링크 설정

timer = CADisplayLink(target: self, selector: #selector(gameloop))
timer.add(to: RunLoop.main, forMode: .default)

화면 주사율에 맞춰 렌더링 함수를 호출합니다.

 

2. 랜더 패스 설정

무엇을 어디에 그릴지 정의합니다.

let renderPassDescriptor = MTLRenderPassDescriptor()
renderPassDescriptor.colorAttachments[0].texture = drawable.texture
renderPassDescriptor.colorAttachments[0].loadAction = .clear

 

3. 커맨드 버퍼 생성

이번 프레임에 실행할 명령 목록을 준비합니다.

let commandBuffer = commandQueue.makeCommandBuffer()!

 

4. 렌더 인코더로 그리기 명령 기록

실제 그리기 명령을 인코딩합니다.

let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor)!
renderEncoder.setRenderPipelineState(pipelineState)
renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, index: 0)
renderEncoder.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: 3)
renderEncoder.endEncoding()

 

5. 커맨드 버퍼 제출

모든 준비가 끝나면 GPU에 작업을 제출합니다.

commandBuffer.present(drawable)
commandBuffer.commit()

감사합니다.

 

잘못된 내용이 있거나 더 좋은 내용 피드백은 언제나 환영합니다!

궁금하신 부분은 댓글로 질문 부탁드립니다!

728x90
반응형

'Apple > Metal' 카테고리의 다른 글

[Metal] Metal API 알아보기  (0) 2025.10.31
'Apple/Metal' 카테고리의 다른 글
  • [Metal] Metal API 알아보기
P_Piano
P_Piano
Apple 생태계 개발자가 되기 위한 학습과 경험의 기록
    반응형
    250x250
  • P_Piano
    피피아노의 개발 일지
    P_Piano
  • 전체
    오늘
    어제
    • 분류 전체보기 (218)
      • Apple (136)
        • iOS (23)
        • visionOS (5)
        • Swift (71)
        • UIKit (2)
        • SwiftUI (25)
        • RxSwift (2)
        • Xcode (5)
        • Metal (2)
      • C언어 (5)
      • C++ (8)
      • Dart (1)
      • Python (3)
      • JavaScript (17)
      • Git (1)
      • CS (39)
        • 디자인 패턴 (6)
        • 네트워크 (20)
        • 운영체제 (8)
        • Database (5)
        • 자료구조 (0)
      • IT 지식 (2)
      • IT 뉴스 (4)
      • 출처 표기 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    연산자
    Xcode
    제어문
    SWIFT
    변수
    visionOS
    네트워크
    swiftUI
    프로퍼티 래퍼
    Apple
    비동기
    이니셜라이저
    ios
    옵셔널
    티스토리챌린지
    Initializers
    함수
    배열
    프로세스
    자바스크립트
    스위프트
    Vision Pro
    운영체제
    데이터베이스
    UIKit
    클래스
    디자인패턴
    오블완
    코딩테스트
    프로그래머스
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
P_Piano
[Metal] Apple의 Metal 입문하기
상단으로

티스토리툴바