간략하게 소개를 하자면, 동일한 mesh를 공유하는 여러 물체를 그릴 때, 하나씩 draw를 호출하여 그리는 것보다 한번의 draw에 동일한 물체들을 한번에 다 그리는 것이 더 효율적입니다. 렌더러는 각 개체에 대한 위치 및 색을 따로 보관하고, 이를 적용하여 그릴 수 있습니다. 먼저 instancedatabuff부터 만들어, 각 개체가 가진 고유한 특성을 저장하게 해야합니다.
for ( size_t i = 0; i < kMaxFramesInFlight; ++i )
{
_pInstanceDataBuffer[ i ] = _pDevice->newBuffer( instanceDataSize, MTL::ResourceStorageModeManaged );
}
그 후에, 필요한 데이터를 _pInstanceDataBuffer에 적절하게 채워넣어 줍니다. 그 후에 이를 setVertexBuffer로 등록을 하고, draw 함수를 호출할 때 drawIndexedPrimitives를 호출하여, indexbuffer가 사용한 draw 함수를 호출해야 합니다.
pEnc->setVertexBuffer( pInstanceDataBuffer, /* offset */ 0, /* index */ 1 );
pEnc->drawIndexedPrimitives( MTL::PrimitiveType::PrimitiveTypeTriangle,
6, MTL::IndexType::IndexTypeUInt16,
_pIndexBuffer,
0,
kNumInstances );
이를 vertex function에서 사용할 때는 다음과 같이 사용합니다.
v2f vertex vertexMain( device const VertexData* vertexData [[buffer(0)]],
device const InstanceData* instanceData [[buffer(1)]],
uint vertexId [[vertex_id]],
uint instanceId [[instance_id]] )
{
v2f o;
float4 pos = float4( vertexData[ vertexId ].position, 1.0 );
o.position = instanceData[ instanceId ].instanceTransform * pos;
o.color = half3( instanceData[ instanceId ].instanceColor.rgb );
return o;
}
[[instance_id]] 한정자는 실행시간에 개체값을 가지며, 이는 instanceDataBuffer에서 값을 가져오는데 활용됩니다.
'Projects > Metal - Document' 카테고리의 다른 글
Metal-cpp 07 : Texture Surfaces (0) | 2022.08.25 |
---|---|
Metal-cpp 05 : Render 3D with Perspective Projection (0) | 2022.08.25 |
Customizing Render Pass Setup (0) | 2022.08.22 |
Tailor Your Apps for Apple GPUs and Tile-Based Deferred Rendering (0) | 2022.08.22 |
Metal-cpp 02 : Store Shader Arguments in a Buffer (0) | 2022.08.07 |