* 교재 제목 : Metal by Tutorials second edition (Beginning Game Engine Development with Metal)
Questions
1. Metal에서는 vertex shader, fragment shader 대신 vertex function, fragment function이라는 용어를 사용한다. *.metal 쉐이더 파일에 vertex shader에 해당하는 vertex function, fragment shader에 사용하는 fragment function을 한 번에 저장하고 사용하는 게 일반적이어서 그런가?
(이를테면 이런 식이다)
#include <metal_stdlib>
using namespace metal;
struct VertexIn {
float4 position [[ attribute(0) ]];
};
vertex float4 vertex_main(const VertexIn vertex_in
[[ stage_in ]]) {
return vertex_in.position;
}
fragment float4 fragment_main() {
return float4(1, 0, 0, 1);
}
let vertexFunction = library.makeFunction(name: "vertex_main")
let fragmentFunction = library.makeFunction(name: "fragment_main")
2. Model I/O basic 3D shape는 각각의 3D모델 데이터를 다 가지고 있는 것일까? (mesh를 로드할 때 vertex descriptor도 자동으로 생성한다고 후술, mesh가 정점의 간단한 리스트를 포함하는 버퍼 즉 vertex buffer도 가지고 있다고 후술)
let mdlMesh = MDLMesh
sphereWithExtent: [0.75, 0.75, 0.75],
segments: [100, 100],
inwardNormals: false,
geometryType: .triangles,
allocator: allocator)
3. (swift) try만 있는 건 정체가 뭐지?
let library = try device.makeLibrary(source: shader, options: nil)
4. draw call
renderEncoder.drawIndexedPrimitives(
type: .triangle,
indexCount: submesh.indexCount,
indexType: submesh.indexType,
indexBuffer: submesh.indexBuffer.buffer,
indexBufferOffset: 0)
"Here, you're instructing the GPU to render a vertex buffer consisting of triangles with the vertices placed in the correct order by the submesh index information."
5. MTKView의 drawable을 command buffer에 넘겨주면 연결된(?) render pass descriptor(그러니까 MTKView의 descriptor 참조)가 이 drwable을 갖게 되는 것인가?
let view = MTKView(frame: frame, device: device)
let commandBuffer = commandQueue.makeCommandBuffer()
let renderPassDescriptor = view.currentRenderPassDescriptor
let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor)
let drawable = view.currentDrawable
commandBuffer.present(drawable)
"MTKView provides a render pass descriptor that will hold a texture called the drawable."
"You get the drawable from the MTKView."
"The MTKView is backed by a Core Animation CAMetalLayer and the layer owns a drawable texture which Metal can read and write to."
6. draw call에서 렌더가 일어나진 않는다. 렌더는 GPU가 command buffer의 모든 command를 받고 나서 이루어진다. 그게 여기?
commandBuffer.commit()
Archives
- Metal 렌더링의 프로세스는 앱의 크기나 복잡도에 상관 없이 같다고 볼 수 있다.
- (Xcode) PlaygroundSupport는 assistant editor에서 live view를 보게 해준다. (playground에서 Metal 코드를 실행하면 live view로 결과를 볼 수 있음)
- MetalKit는 Metal을 보다 쉽게 사용할 수 있게 해주는 프레임워크이다. 텍스처를 로드하고, Metal 버퍼로 작업할 수 있게 해주며, Model I/O 프레임워크와 interfacing한다.
- (swift) guard : 조건이 false일 때 구문을 실행하는 조건문, 조건을 그대로 적어서 가독성이 높다. guard 조건 else { 구문}
- (swift) let : 상수 선언 (재할당 불가) > var : 변수
- MTLClearColor로 MTKView의 clearColor를 설정
let view = MTKView(frame: frame, device: device)
view.clearColor = MTLClearColor(red: 1, green: 1, blue: 1, alpha: 1)
- primitive : Model I/O basic 3D shape, 큐브, 구, 실린더, 토러스 등이 있다. (OpenGL에서 primitive가 point, line, triangle 등의 drawing primitive를 일컫는 용어라는 점을 기억하면 좋을듯)
- MTKMeshBufferAllocator는 mesh data를 위한 메모리를 관리한다.
- Metal에서 MDLMesh가 반환하는 mesh를 사용하려면, Model I/O mesh를 MetalKit mesh로 바꾸어야 한다.
let mesh = try MTKMesh(mesh: mdlMesh, device: device)
- (os) descriptor : linux나 unix 계열 시스템(맥은 unix 기반)에서 process가 file을 다룰 때 사용하는 추상적인 정수 값, 파일을 지칭한다. 참고로, unix에서는 디렉토리, 소켓, 파이프, 블록 디바이스, 캐릭터 디바이스 등 모든 객체가 파일로 관리된다.
- pipeline state를 설정하는 것은 GPU에게 state가 변경될 때까지 아무것도 변하지 않을 것이란 걸 알려주는 것이다. pipeline state에는 GPU가 어떤 pixel 포맷을 사용해야 하는지, depth 렌더링을 해야하는지, shader function 등 GPU가 필요한 모든 정보를 포함한다.
- .vertexDescriptor : GPU에게 메모리에서의 정점들의 레이아웃을 알려준다.
- "In a real app, you might create several pipeline states to call different shading functions or use different vertex layouts."
- (swift) delegate method : 번역하자면 대리 매소드, c++의 함수 포인터와 비슷한 개념
- MTKView는 매 프레임마다 실행되는 delegate method를 가지고 있다.
- render pass : 그림자, light, 반사 등의 복잡한 계산을 각각의 render pass에서 분리하여 수행한다. 예를 들어, shadow render pass는 3D 모델의 전체 scene을 렌더하지만 grayscale shadow 정보만 유지한다. 다른 render pass는 모델을 색상 전체로 렌더한다. 이 두가지 텍스처를 합쳐서 하나의 결과물로 screen에 보여주는 것이다.
- command buffer : GPU가 실행할 모든 command를 저장한다.
let commandBuffer = commandQueue.makeCommandBuffer()
- attatchment : 렌더 목적지 (render destination) 데이터로, 저장할 텍스처나 render pass에서 텍스처를 유지할지 말지 등의 정보를 필요로 한다.
- render pass descriptor : MTKView의 render pass descriptor의 레퍼런스로 사용, attatchment를 가지고 있다.
- render pass descriptor를 사용하여 render command encoder를 만든다.
- render command encoder : GPU가 정점을 그리기 위해 필요한 모든 정보를 가지고 있다.
- 아래 코드에서 offset은 vertex 정보가 시작하는 버퍼에서의 위치를, index는 vertex shader function이 해당 버퍼를 몇번째 index로 가지는지를 나타낸다.
renderEncoder.setVertexBuffer(mesh.vertexBuffers[0].buffer, offset: 0, index: 0)
- submesh : mesh는 submesh로 이루어진다. material이라고 생각해도 된다.
- 더 이상 draw call이 없을 것이란 뜻 :
renderEncoder.endEncoding()
Words
* integrate : 통합하다
* take into account : 고려하다
'Study Archives > Metal' 카테고리의 다른 글
[Metal] 3D Models (0) | 2022.08.07 |
---|
댓글