티스토리 뷰
안녕하세요 :) Zedd입니다.
Metal을 공부해야 할 일이 생겨서..기본적인 용어들(?)을 공부해보려고 합니다.
오늘 공부는 www.raywenderlich.com/7475-metal-tutorial-getting-started#toc-anchor-011
를 보면서 할 예정이고, 나오는 용어들을 정리하려고 합니다!
Metal이 뭐지..? -> zeddios.tistory.com/932
별 도움이 안될 수도 있지만..읽어보시면 좋을 것 같습니다 👀
Core Animation -> CA어쩌고
Photos -> PH어쩌고
다들 프레임워크 축약?을 해당 프레임워크 안에 있는 타입이나 그런것들의 prefix로 붙잖아요?
Metal역시 MTL어쩌고 이런식으로 시작하나봐요.
MTLDevice
그래픽을 그리거나 병렬 계산을 수행하는데 사용하는 GPU에 대한 Metal 인터페이스 라고 합니다..뭔소리야
MTLDevice는 그냥 GPU에 직접 연결하는 인터페이스라고 생각하세요.
이 MTLDevice객체를 가지고 필요한 다른 Metal객체(command queues, buffers, textures 등)을 만들 수 있다고 합니다!
그리고 Metal이 앱에 제공하는 고유한 기능을 쿼리하고, 모든 Metal기능을 이 MTLDevice로!! 실행 할 수 있다고 합니다.
얼핏보면 class, struct같지만, MTLDevice는 프로토콜이에요!
MTLDevice를 가지고 다른 Metal객체를 만들려면 초기화를 해야하는데,,MTLDevice를 채택하고 있는 특정 타입으로 초기화해야겠죠?
문서에서는 MTLCreateSystemDefaultDevice()를 사용하라고 하네요(iOS 및 tvOS에서는)
MTLDevice 객체는 Metal에서 무엇이든 할 수있는 go-to 객체이므로
앱과 상호 작용하는 모든 Metal 객체는 런타임에 획득 한 MTLDevice 인스턴스에서 가져옵니다.
MTLDevice가 만든 객체는 비싸지만 영구적입니다.
대부분은 한 번 초기화되고 앱 수명 동안 재사용되도록 설계되었습니다.
뭐 그렇다고 합니다?!
그럼 만들어보자.
Metal을 import해주고
문서가 하라는데로 MTLCreateSystemDefaultDevice를 사용하여 만들어주었습니다.
CAMetalLayer
iOS에서는 화면에 보이는 모든것이 CALayer에 의해 지원되잖아요!?
다양한 CALayer서브클래스가 있죠. 저번에 공부한
Metal을 사용하여 화면에 무언가를 그리고 싶으면, CAMetalLayer라는 CALayer서브클래스를 사용해야합니다.
그럼 써봅시다.
코드는 전부 www.raywenderlich.com/7475-metal-tutorial-getting-started#toc-anchor-011에 나와있으니까 굳이 gist로 만들진 않을게요.
가장 중요한 부분은 metalLayer의 device프로퍼티에 방금 우리가 만든 MTLDevice객체를 넣어주는 겁니다.
다른 부분은 굳이 설명하진 않겠슴
"Everything in Metal is a triangle"
Metal의 모든 것은 삼각형이래요. 지금 여기서 할 거는 2차원의 삼각형을 만드는 건가봐요.
Metal에서 기본 좌표계는 정규화된 좌표계이기 때문에, 기본적으로 (0, 0, 0.5)를 중심으로 2x2x1 cube를 보고있다....??
왜 (0, 0, 0.5)가 중심이지?,,,
순간 뇌정지 와서..동료분이 알려주심 ㅎ 감사합니더,,,
지금 만들 거는 3차원이 아니라 2차원의 삼각형이기 때문에 Z가 0일때를 생각해보면
이런식으로 삼각형 정점의 좌표가 나오게 됩니다.
삼각형을 그릴려면 세 꼭지점을 알아야하잖아요!!!!!!!!!! 우리가ㅡ 그릴건 2D 삼각형이니까 저 꼭지점들을 알아야하는겁니다.
그래서 이렇게 세 꼭지점을 정의해줍시다.
그리고 이 데이터를 MTLBuffer라고 하는것으로 옮겨서 GPU로 보내야한대요!?!?!?
그럼 MTLBuffer가 필요하겠군,..
꼭짓점 데이터 크기를 바이트 단위로 가져와야한다고 합니다. vertexData 요소의 크기에 배열의 요소 수를 곱하면 된대요..?
그리고 아까 만들었던 MTLDevice객체세어 makeBuffer를 호출하여 MTLBuffer를 초기화해줍니다.
이렇게하면 GPU에서 새 버퍼를 만들어 CPU에서 데이터를 전달 할 수 있다고 해여. 자세한 건 모르겠음ㅋ
이 MTLBuffer는 "vertex shader"라고 하는 작은 프로그램의 input이 된다고 합니다!
그럼 vertex shader라는 것도 만들어야겠군...
일단 vertex shader가 뭔지 알아봅시다.
vertex shader는 GPU에서 실행되는 작은 프로그램으로, Metal Shading Language라고 하는 C++과 같은 언어로 작성되어있다고 해요!
vertex shader는 꼭짓점(vertex)당 한 번 호출되며,
해당 위치의 vertex 정보(ex. 색상 또는 질감 좌표(texture coordinate) )를 가져와서
잠재적으로(potentially) 수정된 위치 및 기타 데이터를 반환해야한대여ㅛ...?;;
간단한 vertex shader는 전달 된 위치와 동일한 위치를 반환한다고 합니다.
"vertex shader는 꼭짓점(vertex)당 한 번 호출되며" 라고 했으니 저희꺼는 3번 불리겠네요.
우리껀 간단(?)하니까 전달 된 위치와 동일한 위치를 반환하는 것을 볼 수 있죠.
이해가셨죠!?
그럼 본격적으로 vertex shaders를 만들어봅시다.
Metal파일을 클릭하고, 이름은 Shaders로 해주세요.
그럼
이런 파일이 만들어진 것을 볼 수 있습니다.
와 #include개오랜만이내;';;';;;
using namespace std 치던게 엊그제같은데,,,,,,,,,,,,\
이 코드를 넣어주세여
1. vertex float4 basic_vertex
모든 vertex shaders는 "vertex" keyword 로 시작해야한대요. 그래서 vertex로 시작한 것을 볼 수 있죠.
vertex로 시작하면 아ㅣ이친구는 vertex shaders구나~~ 라고 생각하는 부분
함수는 vertex의 최종 위치를 반환해야하는데, 여기서는 float4로 지정해줬네요.
그런다음 basic_vertex라는 함수 이름을 지어줬습니다. 나중에 이 이름을 사용해서 shader를 찾는다고 합니다.
2, 3은........진짜 음...설명해도 제가 잘 모르겠어서 넘어가겠습니다. 알아서들 보시길 ㅎ 암튼 2, 3은 보시다시피 함수의 파라미터입니다!
사실 몰라도 될 것 같아서 넘어갔는데 막 Metal의 핵심이고;;;;;이러면 ㅈㅅ;
4. 암튼 vertex array받아서 거기 vid꺼 리턴한다......ㅋ....당연히 float4로 리턴해줘야겠죠.
1.0은 왜 들어가있냐 -> 3D math에 필요하다고 함.
자 그럼 vertex shaders은 만들었고..이제 뭔가 그만만들고 싶은데 계속 뭔가를 만들어야하네요..
vertex shader가 완료되고 나면,
Metal은 화면의 각 fragment(픽셀이라고 생각하면 됨)에 대해 다른 shader를 호출한다고 합니다.
이 다른 shader를 만들어야함 **
그 이름은 fragment shader입니다..
개간단하게 fragment shader의 역할을 말하자면!!!!!!!!!
각 fragment의 최종 색상을 반환하는 겁니다.
간-단하게 하고싶으니 각 fragment을 흰색으로 만들어주겠슴
아까 만든 Shaders.metal에
요 함수 추가 ㄱ
vertex shaders가 "vertex"라는 keyword로 시작했다면..
fragment shader는 "fragment"라는 keyword로 시작합니다.
fragment shader의 역할은 모ㅓ다...? 최종색상 반환하는거임
half4를 리턴하게 했네요. half4는 4성분 색상 값이라고 생각하시면 됩니다. RGBA)
4성분이니까 half4(1.0)이면
(1, 1, 1, 1)이 최종적으로 리턴되게 됩니다. 이게 흰색임.
아 이제 끝났나 ^^./;;;?
ㄴㄴ아님
vertex shader랑 fragment shader를 만들었으면
다른 configuration data와 함께 "render pipeline"라는 특수한 객체로 결합해야한다고 합니다..ㅎ ㅏ...ㅋ...
근데 Metal의 펀쿨섹한 점 중 하나
: shader가 precompile되고 render pipeline configuration이 처음 설정 한 후에 컴파일이 된다는 점.
왜인지는 모르겠지만 이건 모든것을....매우 효율적으로 만든다고 하네요...
ViewController에 가서
요 프로퍼티를 정의해주세요.
device.makeDefaultLibrary를 호출하면 프로젝트에 포함된 precompile된 shader에 접근할 수 있대요!
그래서 vertex shader랑 fragment shader를 가져왔네요.
그런다음 render pipeline configuration을 설정해줍니다.
그래서 위에서 shader를 넣어주네요.
마지막으로 pipelineState를 만들어서 넣어주네요.
아니 삼각형 만들기 개어렵내
MTLCommandQueue를 만들어야합니다.
MTLCommandQueue는 GPU에서 실행 할 명령 버퍼를 구성하는 대기열(queue)이라고 생각하시면 됩니다.
GPU가 한번에 하나씩 뭔가를 실행하도록 하는 친구...ㅇㅋ??
MTLDevice객체를 이용하여 간단하게 만들어줍니다.
이제 뭔가를 설정(?)하는 코드는 다 끝난거에요!
-
Create a Display Link
-
Create a Render Pass Descriptor
-
Create a Command Buffer
-
Create a Render Command Encoder
-
Commit your Command Buffer
이제 이런 작업을 다 하면 삼각형 한ㄷ개.....를 그릴 수 있게 됩니다. 아니 메탈 씨
1) Creating a Display Link
CADisplayLink를 초기화하고, gameloop라는 것을 만들어줍시다.
이제 gameloop는 각 프레임마다 render를 호출하게 됩니다.
2) Creating a Render Pass Descriptor
이제 MTLRenderPassDescriptor를 만들어야한대요.
MTLRenderPassDescriptor는 렌더링 할 texture, clear color, 기타 configuration을 구성하는 객체라고 해요.
render안에 넣어줍시다.
metalLayer에서 nextDrawable()를 호출하면 화면에 무언가를 표시하기 위해 그려야하는 texture가 반환댄대요.
clearColor에 들어가는 색상은 녹색이에요.
3) Creating a Command Buffer
이제느 Command Buffer를 만들어야 하는데여,
Command Buffer는 프레임에 대해 실행하려는 render command 목록이라고 생각하시면 됩니다.
cool한 점은 command buffer를 커밋할 때 까지는 실제로 아무일도 일어나지 않는다는 사실/!?!? 뿌슝빠슝
그래서 내가 하고싶은 작업이 발생하는 시점을 세밀하게 제어 할 수 있대요.
뭔가 command buffer는 아까 이야기한 command queue랑 비슷해보이잖아요?
그 commandQueue을 이용하여 command buffer를 만듭니다. render메소드 끝에 넣어주세요.
4) Creating a Render Command Encoder
command Queue에 뭔가 command가 들어가야 얘가 실행을 하든지 말든지 할거 아님 ㅡㅡ
그 command를 만들어봅시다.
render command를 만들려면 render command encoder라는 객체를 사용하면 됩니다.
이렇게 Encoder를 만들어줍니다.
여기서 가장 중요한 부분은 drawPrimitives(type:vertexStart:vertexCount:instanceCount:)
여기입니다.
여기서 vertex buffer를 기준으로 GPU에 삼각형 set을 그리도록 지시하는 겁니다.
우리는 하나만 그릴거니가 instanceCount를 1로 넘겨준거 ㅇㅇ
(근데 딱히 instanceCount를 바꿔도 아무런 변화가 없네요..)
끝나면 endEncoding을 호출해주면 됩니다.
5) Committing Your Command Buffer
아까 뭐랬죠?
Command buffer의 cool한 점은
command buffer를 커밋할 때 까지는 실제로 아무일도 일어나지 않는다..였습니다.
어이어이 "커밋"하는거냐,...
역시나 render의 끝에 commit을 해줍시다.
그리고 빌드하면
큼..살짝 뿌듯 ㅋ...
이ㅏ 튜토리얼에서는 shaders, devices, command buffers, pipelines등등에서 배웠죠?
이게 Metal에서의 가장 중요한 개념인가봐요.
뭔가 저도 그렇고 아마 여러분들도 그러시겠지만, 이해가 안가는 코드들이 많았잖아요..!!!
아직 Metal에 대해서 잘 모르니까 당연한거라고 생각합니다!
다만 각 shaders가 어떤 역할을 하는지 알았고,
MTLDevice가 중요하구나~ 라는것도 알았고..
Command Queue와 Buffer가 어떤 느낌인지 알았으니
지금은 그걸로 충분하다고 봅니다 하하
이 지식을 기반으로 store.raywenderlich.com/products/metal-by-tutorials
이 책을 사면 될 듯...ㅋ
-
Apple’s Metal for Developers page, with tons of links to documentation, videos and sample code
-
Apple’s Metal Programming Guide
-
Apple’s Metal Shading Language Guide
-
The Metal videos from WWDC 2014
이런 링크들도 있으니 확인해보세요..!!
다시한번 말하지만 모든 소스코드는
www.raywenderlich.com/7475-metal-tutorial-getting-started#toc-anchor-008
를 출처로 합니다.
+ ) medium.com/@avinashselvam/introduction-to-metal-apples-own-gpu-framework-606cd2f0dd97
여기에도 중요한 개념들이 잘 설명되어 있는듯.
'공부' 카테고리의 다른 글
Github Actions에서 사용할 Token만들기 (3) | 2020.06.17 |
---|---|
Metal ) Custom Core Image Filter (0) | 2020.06.16 |
Github Actions ) Archive and export (2) | 2020.05.25 |
[AVCaptureDevice setActiveColorSpace:] Not supported - use activeFormat.supportedColorSpaces' (2) | 2020.05.12 |
Color Asset을 코드로 만들어보자 (3) | 2020.04.29 |
- Swift
- swift delegate
- 스위프트
- Git
- FLUTTER
- 회고
- 제이슨 파싱
- github
- WWDC
- SwiftUI
- fastlane
- IOS
- WKWebView
- actor
- ios 13
- Xcode
- Combine
- UIBezierPath
- 스위프트 문법
- swift tutorial
- iOS delegate
- swift 공부
- swift array
- Accessibility
- WidgetKit
- np-hard
- swift3
- 피아노
- swift sort
- np-complete
- Total
- Today
- Yesterday