Я визуализирую примитивы Points, которые частично перекрываются. Фрагментный шейдер затеняет части каждого примитивного квадрата Point прозрачными (сплошной центральный круг). Точечный примитив, не перекрывающий другие точечные примитивы, затеняется ожидаемым образом (прозрачные области квадрата показывают фон).
Когда такой точечный примитив перекрывает другой точечный примитив, поведение является неожиданным. в частности: прозрачная область не показывает непрозрачный цвет непрозрачного примитива точек, а вместо этого очищает его и показывает цвет фона.
Другими словами, точечные примитивы с более высоким идентификатором вершины очищают ранее заштрихованные фрагменты точечных примитивов с более низким идентификатором вершины.
Примитивы точек кодируются следующим образом:
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 мая 2016 г.:
Я смог включить фиксированное смешивание функций с этими дополнениями к моему дескриптору конвейера рендеринга:
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;
И теперь все выглядит так, как ожидалось: