Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Вопрос про glPolygonOffset и Z-Fighting (решено, надо 2 прохода, во втором отключить запись в depth buffer и сместить far plane) (2 стр)

Вопрос про glPolygonOffset и Z-Fighting (решено, надо 2 прохода, во втором отключить запись в depth buffer и сместить far plane) (2 стр)

Страницы: 1 2 3 Следующая »
Lion007Постоялецwww8 мая 20189:12#15
минимальную разницу для GL_LESS, в принципе, можно симулировать - через glDepthRange. Фактически в этом случае мы принудительно загрубляем z-буфер, и получается, что уж если LESS- то оно изрядно LESS :-)
но тут тоже могут быть фокусы... во-первых такая штука нормально сработает только в случае ортогональной проекции - в перспективе точность z-буфера и так скачет по глубине. во-вторых, неизвестно, как все эти квадратики должны взаимодействовать (в смысле z-буфера) с остальной картинкой.

если делать честно... скорее всего придется все-таки считать.
можно при генерации смещать полигончики к камере\от камеры пропорционально номеру полигончика (можно софтверно, а можно шойдером) - но это будет не совсем та геометрия, что заказано.
можно (это если совсем честно) добавлять полигончики не просто в порядке генерации, а разложить по кучкам, соответствующим отдельным полоскостям
после этого опять же возможны варианты...
- если отсортировать плоскости по глубине - то можно вообще z-тест отключить
- либо собирать батчики по плоскостям (в один - все плоскости где по одному полигону, остальные отдельно) и заюзать стенсил

в общем, надо бы понимать, что это такое и как оно должно с остальной картинкой взаимодействовать

Great V.Постоялецwww8 мая 20189:39#16
Роман Шувалов
А ты сам то знаешь какой полигон должен быть сверху, а какой снизу? У них есть "приоритет"?
Там точно нужен буфер глубины? Если рисовать просто по порядку - то и проблем не будет. Следующие полигоны будут затирать предыдущие.
Как вариант можно рисовать сначала с GL_LESS, а потом со своим "GL_EQUAL" с небольшой погрешностью, чтобы полики перекрывались в порядке рисования.

Правка: 8 мая 2018 9:41

foxesПостоялецwww8 мая 201810:13#17
Роман Шувалов
Если поделить на Z в шейдере вектора вершин после умножения на модельную и видовую матрицы, то получишь все треугольники в одной плоскости без искажения перспективы. В результате получишь глубину всех вершин равную 1. После этого ты можешь задать отдельным треугольникам или выбранным плоскостям ручную глубину, использовав для этого параметр W. То есть для каждой отдельной геометрии ты задашь свое значение W и домножишь на него в шейдере. Но тогда изначально их порядок глубины будет полностью нарушен.
Роман ШуваловУчастникwww8 мая 201811:49#18
clc
> можно в стенсил отрисовывать первые объекты и запрещать рисовать "конфликтующие"
Отрисовка за 1 проход, и вообще, модель сама содержит самопересечения и это один VBO.

Delfigamer
> Будет очень смешно, если с GL_LEQUAL всё внезапно заработает.
Было бы смешно, но, к сожалению, не за работало. И это логично.

Lion007
> минимальную разницу для GL_LESS, в принципе, можно симулировать - через glDepthRange.
Получится ровно тот же файтинг. Значения-то одинаковые. Неконтролируемая разница  +/- 0.00001 превратится в неконтролируемую разницу +/- 0.01.

Great V.
> А ты сам то знаешь какой полигон должен быть сверху, а какой снизу? У них есть "приоритет"?
Тот, который нарисован последним (в порядке отрисовке - как будто depth test выключен). Но можно и тот, который первым, если по каким-то причинам это будет проще реализовать.

> ты можешь задать отдельным треугольникам или выбранным плоскостям ручную глубину
Ручную одинаковую глубину - не решит проблему (я же не знаю, какие плоскости пересекаются, а какие нет). Вот если бы можно выполнить Depth Test, а уже после него менять глубину, вот это я и ищу.

Great V.Постоялецwww8 мая 201811:53#19
Роман Шувалов
Так как на счет:
> Как вариант можно рисовать сначала с GL_LESS, а потом со своим "GL_EQUAL" с
> небольшой погрешностью, чтобы полики перекрывались в порядке рисования.
?
Сейчас вот прочитал и понял, что написал как наркоман.
В общем на первом проходе ты просто рисуешь все с GL_LESS. Рисовать можно только глубину, цвета не надо.
На втором - рисуешь с цветом, тест глубины делаешь кастомный GL_EQUAL с небольшой погрешностью  (чтобы решить конфликты, которые возникают при файтинге).
Имхо, это все решает.

Правка: 8 мая 2018 11:56

Роман ШуваловУчастникwww8 мая 201812:24#20
Great V.
> На втором - рисуешь с цветом, тест глубины делаешь кастомный GL_EQUAL с небольшой погрешностью
И получу, что обе плоскости ибо отсекутся либо прорисуются. Они же одинаковые.

А "самодельный" depth test во фрагментном шейдере (if ... discard) будет сильно медленный? Мне надо сравнивать одно значение, а в depth buffer вписывать другое. Чтобы следующий объект уже не прошел сравнение.

Lion007Постоялецwww8 мая 201812:29#21
Роман Шувалов
> Получится ровно тот же файтинг.
не совсем. z-Буфер - он целочисленный. если у него достаточно высокая точность - то для накладывающихся полигонов мы получаем "дребезг" за счет разницы в растеризации полигонов и округления. если мы загрубляем z-буфер достаточно - то этот дребезг может съесться.  в пиковой ситуации - когда у нас range нулевой - мы вообще для всего на свете получим строго одинаковый Z и никакого файтинга.
а с ненулевым... артефакты все равно возможны - за счет округления - но чует мое сердце, что будет их заметно меньше.

glDepthRange(0.0, 1.0)

+ Показать

glDepthRange(0.0, 0.1)

+ Показать

glDepthRange(0.0, 0.01)

+ Показать

кстати, неожиданно подумалось - а ведь того же эффекта можно добиться просто в пиксельном шейдере, округляя глубину до нужной точности (0.1, 0.01, 0.001 - сколько захочется)

Правка: 8 мая 2018 12:38

Роман ШуваловУчастникwww8 мая 201812:54#22
Lion007
> не совсем. z-Буфер - он целочисленный.
Даже при твоем glDepthRange(0.0, 0.01) у меня слегка видны артефакты при повороте камеры. В любом случае такие мелкие диапазоны не годятся, SSAO слетит.

> в пиксельном шейдере, округляя глубину до
Насколько я помню, запись в gl_DragDepth крайне не рекомендуется, т.к. сажает производительность (не проверял).

foxesПостоялецwww8 мая 201812:59#23
Роман Шувалов
> Ручную одинаковую глубину - не решит проблему (я же не знаю, какие плоскости
> пересекаются, а какие нет). Вот если бы можно выполнить Depth Test, а уже после
> него менять глубину, вот это я и ищу.
Это как раз исправит зубчики, тем что трианглы будут выровнены относительно экрана и даже если они будут в одной плоскости, то лагов не будет. Ты можешь взять одну из вершин отдельной фигуры за эталон глубины и установить ее другим вершинам этой фигуры. Но придется увеличить буфер передавая для каждой из вершин эталонную вершину - центр фигуры.

Правка: 8 мая 2018 13:34

Lion007Постоялецwww8 мая 201813:12#24
Роман Шувалов
да я, в общем, и не настаиваю - говорю же, надо понимать, что это такое и зачем оно нужно.

запись в gl_fragDepth, насколько помню, отшибает ранний z-тест, что, кмк, в данном случае не сильно критично - оно обчно на тяжелых шейдерах актуально.

можно действительно попробовать нечто вроде того, что камрад Great V предлагал - сначала отрисовать как есть в depth-буфер, а потом подключить его как текстурку и рисовать по EQUAL с точностью.
что будет веселее - изменение плубины фрагмента или дискард - это фиг его знает, проверять надо...

foxesПостоялецwww8 мая 201813:18#25
Lion007
То есть отрисовать два раза буфер с рандомными плоскостями, первый раз без смешения для заполнения глубины, а второй раз добавить glPolygonOffset. Это конечно может прокатить, но если будут близко другие плоскости то артефакты просто переползут на другое место.

Правка: 8 мая 2018 13:19

Lion007Постоялецwww8 мая 201813:39#26
foxes
нет, без всякого полигон-офсета.
насколько помню, в нормальной ситуации из буфера глубины в шойдере читать не дают, от этого и весь головняк.
поэтому первый проход - просто формируем буфер глубины. вот как оно нарисовалось, со всеми артефактами, так и будет.
а на втором проходе подключаем этот буфер глубины как текстурку, читаем из нее значение - и если оно равно (с заданной точностью) глубине фрагмента - то рисуем. не равно - дискардим.
foxesПостоялецwww8 мая 201813:48#27
Lion007
> а на втором проходе подключаем этот буфер глубины как текстурку, читаем из нее
> значение - и если оно равно (с заданной точностью) глубине фрагмента - то
> рисуем. не равно - дискардим.
Так это тоже самое, те же грабли только с боку, ту же погрешность (заданную точность) можно выставить через glPolygonOffset. По тому же принципу получается что если есть третья плоскость без артифакта, то благодаря погрешности она может его добавить.
Сам смотри есть ли разница между добавлением погрешности так
if (z+eps<=depth)

или добавить тот же eps через glPolygonOffset с отключением записи глубины.

Получается если с сравнением (z<depth) артефактов в отдельных частях не было, то нет гарантии что их также не будет с (z+eps<=depth)

Правка: 8 мая 2018 14:21

Lion007Постоялецwww8 мая 201815:26#28
foxes
а, вона ты о чем... ну, при таком раскладе да, можно и через оффсет. и никакой головной боли с текстурами.
но, вообще говоря, все эти фокусы будут работать тем лучше, чем "параллельнее" плоскость полигончика  плоскости экрана. а если углы большие - то фсе равно фигово получится - между соседними пикселями будет большой зазор по глубине, и в него непременно провалится артефакт :)
foxesПостоялецwww8 мая 201815:27#29
Lion007
Вот об этом я выше написал, как можно выровнять относительно экрана без излома перспективы.

Правка: 8 мая 2018 15:28

Страницы: 1 2 3 Следующая »

/ Форум / Программирование игр / Графика

2001—2018 © GameDev.ru — Разработка игр