momodudu.zip
Metal 스터디(5) - MSL에서 packed_float 과 non-packed_float의 차이 본문
Non-Interlaved vertex를 그리는 쉐이더를 작성중에.. 이런 문제를 발견했다.
#include <metal_stdlib>
using namespace metal;
struct VertexIn {
float3 position;
float4 color;
};
struct VertexOut {
float4 position [[position]];
float4 color;
};
vertex VertexOut vertex_main(const device VertexIn* vertex_in [[ buffer(0) ]],
unsigned int vid [[vertex_id]]) {
VertexIn in = vertex_in[vid];
VertexOut out;
out.position = float4(in.position.position, 1.0);
out.color = in.color;
return out;
}
fragment float4 fragment_main(VertexOut interpolated [[stage_in]] ) {
return interpolated.color;
}
일단 쉐이더 코드는 위와 같다. 별로 어려운 코드는 아니고, 그냥 들어온 vertex마다 컬러값과 position값을 그대로 리턴해주는 코드다.
vertex data는 하나당 (x,y,z,r,g,b,a)를 가지고 있고, 각 좌표값은 (0, 1, 0) / (1, -1, 0) / (-1, -1, 0) 이고, 각 정점의 색은 모두 blue다. 화면에 가득차는 파란 삼각형이 나와야한다.
결과가 계속 이렇게 나와서 조금 찾아보다보니..
struct VertexIn {
float3 position;
float4 color;
};
위에서 작성한 쉐이더를 보면, VertexIn 내부가 float3 의 position과 float4의 color로 이루어져있는데, 구조체 패딩이 맞지 않다. 물론 vertex buffer에 집어넣을때도 패딩은 고려하지 않았다.
Metal에서 이런 데이터 구조는 정확한 결과값을 "보장하지않는다"라고 한다. 패딩이 맞춰져 있지 않을 경우, 그 데이터들이 다닥다닥 붙어있을거라는 보장이 없다는 말이다. 즉, 잘될수도 있고 안될수도 있는데 내 경우는 안됐던 것이다.
이러한 문제를 해결하기 위해서, msl에서는 packed type을 제공하는데, float3 -> packed_float3을 써준다면 데이터들이 다닥다닥 붙어있는것을 보장해줄 수 있다고 한다.
struct VertexIn {
packed_float3 position;
packed_float4 color;
};
packed_float type으로 바꾸어주면 간단히 해결된다.
혹은, 처음부터 패딩을 잘 맞춰서 쉐이더에서 불필요한 값을 빼고 쓰는 해결방법도 있다.
요즘 너무 좋은 프로그래밍 언어만 썼더니 이런부분에 문제가 있을거라곤 생각도 못했다;;
'ios > Metal' 카테고리의 다른 글
Metal 스터디(7) - Matrix 적용해보기 ( Projection Transform ) (0) | 2022.02.10 |
---|---|
Metal 스터디(6) - matrix 적용해보기 ( Model Transformation ) (0) | 2022.02.10 |
Metal 스터디 (4) - MSL (0) | 2022.02.08 |
Metal 스터디 (3) - Rendering Pipeline (0) | 2021.11.26 |
Metal 스터디(2) - Vertex Descriptions / Metal Coordinates System (0) | 2021.11.24 |