Делаю классические стёкла с преломлениями. Копия экрана, сдвиг её текстурных координат с учётом вклада нормалмапы. Всё хорошо, всё работает.
Теперь у нас допустим пять стекол, одно за другим. Чтобы они все корректно рендерились их надо отсортировать по дальности и сделать при каждой отрисовке свою копию экрана (в которой уже будет результат отрисовки предидущего стекла). Копирование экрана хоть и не слишком затратная операция, но 4-5 копирований в кадре уже ощутимо съедают фпс. Я когда-то давно придумал такую оптимизацию - рисуем весь мир в отдельный FBO, а его colorbuffer даём шейдеру в качестве копии экрана. Т.е. таким образом у нас получается R\W-текстура. Вчера вот дошли руки сделать, я посмотрел на результат и понял что не учёл одну весьма важную вещь. Поскольку GPU мультипоточный, а преломления провоцируют чтение тех участков текстуры, которые обрабатывает соседний конвейер, то в результате, пока один читает, другой пишет и на стекле возникает такая забавная сетка из мигающих пикселей, похожих на битую видеопамять. По этой сетке даже можно определить какой конвейер какой кусок экрана обрабатывает. Т.е. накрылась медным тазом моя оптимизация, не реализовать её таким образом.
Поделитесь опытом, как вы оптмизировали копирование экрана в текстуру несколько раз за кадр. И еще вопрос. glCopyTexSubImage на CPU работает или на GPU?
Сколько я видел в играх, никто это не решает. В лучшем случае влияние оказывает ближайшее стекло.
Executor
> Я когда-то давно придумал такую оптимизацию - рисуем весь мир в отдельный FBO,
> а его colorbuffer даём шейдеру в качестве копии экрана.
Глупости. Каждое стекло должно учитывать преломления стёкол за ним.
> Поскольку GPU мультипоточный, а преломления провоцируют чтение тех участков
> текстуры, которые обрабатывает соседний конвейер, то в результате, пока один
> читает, другой пишет и на стекле возникает такая забавная сетка из мигающих
> пикселей, похожих на битую видеопамять.
Нет, так не бывает. glCopyTex(Sub)Image синхронизирует.
> Поделитесь опытом, как вы оптмизировали копирование экрана в текстуру несколько
> раз за кадр.
В новой волатиле вспаглидишь, буквально на днях закончил это дело.
> И еще вопрос. glCopyTexSubImage на CPU работает или на GPU?
Зависит от драйвера. Обычно на GPU. Но с синхронизацией.
> Advanced: Тема повышенной сложности или важная.
В чём сложность-то?
>>Глупости. Каждое стекло должно учитывать преломления стёкол за ним.
Правильно. Для того и придумал.
>>Нет, так не бывает. glCopyTex(Sub)Image синхронизирует.
Перечитай еще раз предложенный мной механизм.
1. создаем FBO, в который рисуем все трехмерные объекты (когда весь 3D нарисован, переключаемся на основной буффер и рендерим FSQ)
2. во время отрисовки стёкол для преломления используем текстуру колорбуффера нашего FBO
3. таким образом он считывает с нее всё что уже нарисовано, пропускает через шейдер и тут же рендерит в нее снова. TexImage\SubImage в этой технике вообще неиспользуются.
4. этот закольцованный механизм хорошо работает, если преломлений нет (умножение на колорбуффер убирает свечение стекла в темноте), но! Как только мы начинаем делать преломления, то координаты чтения заведомо выходят их области действия текущего конвейера. Тем не менее с ошибкой совмещенного доступа ничего не валится (возможно потому что Nvidia), а всего лишь мигают те пиксели, в которые одновременно пишет один конвейер и читает другой.
>>В новой волатиле вспаглидишь, буквально на днях закончил это дело.
та этож в конце года, ни раньшы. Да и толку мне глядеть, мне делать надо.
>>В чём сложность-то?
Ну вон выше уже ответили - никто не решает. Было бы легко, все бы решали. Логично?
Кстати вопрос по теме, как правильно перевести upper-left координаты скиссора в формат, понятный glCopyTexSubImage?
Ублюдство какое-то. Почему они начинаются с левого нижнего угла?
g-cont
> таким образом он считывает с нее всё что уже нарисовано, пропускает через
> шейдер и тут же рендерит в нее снова. TexImage\SubImage в этой технике вообще
> неиспользуются.
А, ну с FBO я тут не работаю. Не придумал, как совместить это с постоянным чтением экрана (преломляющих стёкол-то может быть много, и все они отсортированы).
Всё равно, впервые слышу про какие-то конвееры. Вроде до сих пор многопоточные драйверы реализованы не везде, и, как любит говорить документация, "it's up to implementation".
> та этож в конце года, ни раньшы.
Ну ты всё равно до конца года будешь баги в п2 исправлять.
> Ну вон выше уже ответили - никто не решает. Было бы легко, все бы решали.
> Логично?
Ну если даже я решаю - значит, все решают?
> Ублюдство какое-то. Почему они начинаются с левого нижнего угла?
Ублюдочный OpenGL. В D3D такого нет. Я всегда говорил тебе, что D3D лучше, а ты не верил.
Сделать дисторшн-буффер, рисовать стёкла back-to-front, накапливать искажение кастомным блендом. Потом где-нибудь в постпроцессе применять дисторшн-буффер.
Battle Angel Alita
Этот алгоритм не работает по очевидной причине - между искажающими стёклами могут быть обычные прозрачные, ничего не искажающие полигоны.
Battle Angel Alita
Интересный вариант, но возможны артефакты, так как на момент применения distortion, в backbuffer будет уже отрисованное стекло, то есть по сути получится, что в преломление попадет стекло, для которого применяется distortion (к тому же попадет стекло, которое было отрисованно уже поверх и никак не могло попасть в преломление). Если не будет особо палевно, то метод выглядит очень оптимальным.
Моласар
> > Ублюдство какое-то. Почему они начинаются с левого нижнего угла?
> Ублюдочный OpenGL. В D3D такого нет. Я всегда говорил тебе, что D3D лучше, а ты
> не верил.
Ну полная фигня. Как тебя учили в школе графики строить ? :)
innuendo
В OpenGL координатные системы текстуры и экрана отличаются. Это ненормально же.
Такие проблемы в реалтайме никто не решает. И надо сказать правильно делают.
Качество картинки с труъ преломлениями в большинстве случаев не сильно отличается от качества с first-only искажениями. А вот производительность, от отрисовки в правильном порядке все эти отдельные текстуры, даст о себе знать.
Так что вся эта труъита нужна только для приложений _не_реального_ времени, и стараться сделать подобное эквивалентно честному расчету глобального освещения или отражений.
Ещё один "никтонерешаетщик". :)
Причём тут производительность, если стекла, например, всего два, но одно за другим? Фпс в пять раз упадёт от лишнего копирования, наверное?
Executor
> Сколько я видел в играх, никто это не решает. В лучшем случае влияние оказывает ближайшее стекло.
> Такие проблемы в реалтайме никто не решает. И надо сказать правильно делают.
+1
Моласар
> Фпс в пять раз упадёт от лишнего копирования, наверное?
В пять не пять, но упадет. Ради чего это? Что бы ты сам выбрал в игре - плавность, или преломления от пяти стекол?
Sergio
> Что бы ты сам выбрал в игре - плавность, или преломления от пяти стекол?
Я всегда выбираю наилучшее качество при сбалансированной под заданный минимальный уровень железа производительности.
Странно, мне казалось, что так делают все адекватные разработчики.
Плавность же обеспечивается ограничением фпс на психологически важной отметке 60 долларов за баррель, для динамичных шутеров - 100.
Sergio
> +1
Ясно-понятно. Значит, надо записать поддержку многослойных преломлений в фичелист. А я-то думал, это маст-хэв, не заслуживающий отдельного упоминания. :)
Тема в архиве.