Перекрывающиеся примитивы Metal Point и смешивание
Я отрисовываю примитивы Points, которые частично перекрываются. Фрагмент шейдера затеняет части каждой точки примитивного прозрачного квадрата (сплошной центр круга). Точечный примитив, который не перекрывает любой другой точечный примитив, как и ожидалось, оттенками (прозрачные области квадрата показывают фон).
Когда такой точечный примитив перекрывает другой точечный примитив, поведение является неожиданным. в частности: прозрачная область не показывает непрозрачный цвет примитива unlerlying точек, но вместо этого очищает его и показывает цвет фона.
Другими словами, точечные примитивы с большим номером вершины очищают предварительно затененные фрагменты точечных примитивов с меньшим номером вершины.
Примитивы точек кодируются так:
command_encoder.drawPrimitives(.Point, vertexStart: 0, vertexCount: stroke.count)
А вершинные и фрагментные шейдеры выглядят так:
vertex OutVertex vertex_func(constant InVertex* vertex_array [[buffer(0)]],
constant Uniforms& uniforms [[buffer(1)]],
uint vid [[vertex_id]]) {
OutVertex out;
InVertex in = vertex_array[vid];
// transform vertex into NDC space
out.position = uniforms.projection * float4(in.position.x, in.position.y, 0, 1);
out.pointSize = 60;
return out;
}
fragment float4 fragment_func(OutVertex vert [[stage_in]], float2 uv[[point_coord]]) {
float2 uvPos = uv;
uvPos.x -= 0.5f;
uvPos.y -= 0.5f;
uvPos *= 2.0f;
float dist = sqrt(uvPos.x*uvPos.x + uvPos.y*uvPos.y);
float circleAlpha = 1.0f-dist;
half4 color = half4(0.0f, 0.0f, 1.0f, 1.0f);
color *= circleAlpha;
return float4(color.r, color.g, color.b, circleAlpha);
}
Результаты выглядят так:
Я хотел бы узнать, как предотвратить очистку перекрывающихся прозрачных областей, но сохранить прозрачность на заднем плане.
Спасибо.
Обновление 25.05.16:
Я смог включить фиксированное смешивание функций с этими дополнениями к моему дескриптору конвейера рендеринга:
rpld.colorAttachments[0].blendingEnabled = true
rpld.colorAttachments[0].rgbBlendOperation = .Add;
rpld.colorAttachments[0].alphaBlendOperation = .Add;
rpld.colorAttachments[0].sourceRGBBlendFactor = .One;
rpld.colorAttachments[0].sourceAlphaBlendFactor = .One;
rpld.colorAttachments[0].destinationRGBBlendFactor = .OneMinusSourceAlpha;
rpld.colorAttachments[0].destinationAlphaBlendFactor = .OneMinusSourceAlpha;
И теперь все выглядит так, как ожидалось: