потеря точности буфера глубины на iOS - PullRequest
0 голосов
/ 21 сентября 2018

Я выполняю очистку глубины с помощью очень простой функции фрагмента:

struct VertexOut {
    float4 position  [[ position ]];
};

fragment void depthPeelFragment(VertexOut in [[ stage_in ]],
                                depth2d<float, access::read> previousDepth)
{
    float4 p = in.position;
    if(!is_null_texture(previousDepth) && p.z <= previousDepth.read(uint2(p.xy)))
    {
        discard_fragment();
    }
}

(мой пиксельный формат буфера глубины MTLPixelFormatDepth32Float)

Это хорошо работает на моем Mac.В каждом проходе я отправляю одну и ту же геометрию, и в конце концов больше не пишутся фрагменты, и процесс завершается.Например, в тестовой сфере есть два прохода с одинаковым количеством фрагментов, записанных в каждом проходе (передняя и задняя полусферы).

Однако на iPad процесс не завершается.Есть некоторые (не все) фрагменты, которые, несмотря на то, что они были визуализированы в предыдущем проходе, не удаляются в последующих проходах.

Какие различия платформ могут вызвать это?

Является ли координата z атрибута position всегда значением, записанным в буфер глубины?

По словам инженера Apple, это не логарифмический буфер глубины.

Обратите внимание, чтоЯ не могу просто ограничить количество проходов (я не использую это для OIT).

Обновление:

Вот как выглядит текстура глубины на 3-м проходечерез захват графического процессора (зеленый цвет представляет границы визуализированной геометрии):

Depth texture for test sphere

Распределение точек делает это похожим на проблему точности с плавающей запятой.

Более того, если я добавлю эпсилон в предыдущий буфер глубины:

p.z <= previousDepth.read(uint2(p.xy))+.0000001

, то процесс на iPad будет прекращен.Однако результаты недостаточно точны для последующего использования.

...