[iOS] Metal에서 GPU 컴퓨팅(10) Metal Shading Language로 기술된 라이프 게임 로직
11935 단어 iOSObjective-C금속XcodeGPU
지금까지 Metal의 GPU 컴퓨팅에 대해 해설 기사를 써 왔습니다.
[iOS] Metal에서 GPU 컴퓨팅 (1) 최소한의 코드 작성 및 특성 파악
[iOS] Metal에서 GPU 컴퓨팅 (2) 군지능
[iOS] Metal에서 GPU 컴퓨팅 (3) MTLDevice
[iOS] Metal에서 GPU 컴퓨팅 (4) MTKView
[iOS] Metal에서 GPU 컴퓨팅 (5) MTLLibrary
[iOS] Metal에서 GPU 컴퓨팅 (6) MTLCommandQueue
[iOS] Metal에서 GPU 컴퓨팅 (7) MTLCommandBuffer
[iOS] Metal에서 GPU 컴퓨팅 (8) MTLComputeCommandEncoder
[iOS] Metal에서 GPU 컴퓨팅 (9) MTLComputePipelineState
이 기사에서는 지난 번에 계속해서 Apple이 제공하는 샘플 코드에 대해 설명합니다.
취급하는 샘플 코드는, 전회와 같은 라이프게임의 앱, MetalGameOfLife입니다.
MetalGameOfLife
(실행 화면)
이번에는, 샘플 코드내에 에 기술된 라이프 게임의 로직에 대해서 해설을 실시합니다.
라이프 게임 자체에 관해서는 YouTube 등에서 동영상을 검색해 주시면 개관을 잡을까 생각합니다.
요약하면, 주위 매스눈의 개체수의 소밀에 의해 개체의 생사나 존속이 결정되는 프로그램입니다.
이 라이프 게임의 논리는 셰이더 내에서 컴퓨팅을위한 함수로 설명됩니다.
다시 말하지만, 이 샘플 코드는 주로 다음 파일로 구성되어 있습니다.
AAPLRender.h
AAPLRender.m
AAPLViewController.h
AAPLViewController.m
Sharder.metal
이 중 AAPLRender.m에는 병렬 컴퓨팅 및 드로잉의 CPU측의 로직이 Shader.metal에는 정점 셰이더, 프래그먼트 셰이더, GPU 컴퓨팅용 셰이더가 쓰여져 있습니다.
미리 텍스처의 각 점에 대응하는 thread가 할당되어 있기 때문에, 각 점에 대응하는 처리는 병렬로 행해집니다.
여기에서는 Shader.metal 내에서의 라이프 게임의 논리의 개소를 해설해 갑니다.
Shader.m에는 다음과 같은 설명이 있습니다.
Shader
kernel void game_of_life(texture2d<uint, access::sample> readTexture [[texture(0)]],
texture2d<uint, access::write> writeTexture [[texture(1)]],
sampler wrapSampler [[sampler(0)]],
ushort2 gridPosition [[thread_position_in_grid]])
{
ushort width = readTexture.get_width();
ushort height = readTexture.get_height();
float2 bounds(width, height);
float2 position = float2(gridPosition);
...
game_of_life 함수가 설명됩니다. kernerl로 쓰여지기 때문에 이것은 컴퓨팅을위한 함수입니다.
인수로서, 입력용의 텍스처, 출력용의 텍스처, 샘플러, 그리드내에서의 이 thread의 위치 (gridPosition)가 건네받고 있습니다.
flot2 형은 float 형의 2 차원 벡터입니다.
이 함수 외에, 주위의 셀의 생사 판정용의 구조체가 기술되고 있습니다. Metal Shading Language는 C++ 기반이므로 구조체를 사용할 수도 있습니다.
Shader
constant float2 kNeighborDirections[] =
{
float2(-1, -1), float2(-1, 0), float2(-1, 1),
float2( 0, -1), /* center */ float2( 0, 1),
float2( 1, -1), float2( 1, 0), float2( 1, 1),
};
또, 셀의 생사를 판정하는 정수를 설정하고 있습니다. 텍스처의 rgb를 이용하고 있기 때문에 원시를 0, 죽음을 255로 하고 있습니다.
Shader
constant int kCellValueAlive = 0;
constant int kCellValueDead = 255;
이들을 사용하여 다음 논리에서 주변의 살아있는 셀 수를 계산합니다.
Shader
ushort neighbors = 0;
for (int i = 0; i < 8; ++i)
{
// Sample from the current game state texture, wrapping around edges if necessary
float2 coords = (position + kNeighborDirections[i] + float2(0.5)) / bounds;
ushort cellValue = readTexture.sample(wrapSampler, coords).r;
neighbors += (cellValue == kCellValueAlive) ? 1 : 0;
}
그리고 다음 로직으로 셀의 생사를 판정하고 결과를 텍스처에 내보내고 있습니다.
Shader
ushort deadFrames = readTexture.read(uint2(position)).r;
...
bool alive = (deadFrames == 0 && (neighbors == 2 || neighbors == 3)) || (deadFrames > 0 && (neighbors == 3));
...
ushort cellValue = alive ? kCellValueAlive : deadFrames + 1;
...
writeTexture.write(cellValue, uint2(position));
cellValue가
alive ? kCellValueAlive : kCellValueDead가 아닌,
alive ? kCellValueAlive : deadFrames + 1; 나노하,
사망한 셀의 색을 서서히 변화시키기 위해서입니다.
따라서 라이프 게임과 같은 병렬 처리에 적합한 코드는 Metal Shading Language로 작성할 수 있습니다.
이번에는 라이프 게임의 샘플 코드 내에서의 라이프 게임의 논리의 해설을 실시했습니다.
다음 번 이후, 또 다른 개소에 대한 해설을 실시해 갑니다.
Reference
이 문제에 관하여([iOS] Metal에서 GPU 컴퓨팅(10) Metal Shading Language로 기술된 라이프 게임 로직), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/yuky_az/items/a2aba547c02b879d7b29텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)