17
Karma
0
Rating

User

WBOIT в OpenGL: прозрачность без сортировки

0
Ну да, я вообще никому не советовал бы использовать WBOIT с альфа > 0,5. В статье это всё объясняется с картинками :)

WBOIT в OpenGL: прозрачность без сортировки

0
Благодарю за то, что указали на отсутствие гамма-коррекции. Я полез разбираться с этой темой и многое для себя уяснил. У меня и правда отсутствовала гамма-коррекция, и это, наверное, было заметно по плохому антиалиасингу. Вычисления с цветом происходили в линейном пространстве, потом к ним применялась LUT монитора, к этому добавлялась низкая точность хранения тёмных тонов в 8-битном буфере, и получались рваные края примитивов. Теперь цвета преобразуются в линейное пространство перед отправкой в OpenGL, а при выводе на экран — в sRGB (аппаратно). Выглядит получше.

Непонятно, почему в Qt по умолчанию происходит вывод в рендербуфер с линейным цветовым пространством, и для поддержки sRGB приходится настраивать QOpenGLWidget.

В своём рабочем проекте я это тоже исправил (приятно открывать для себя мир; у нас ни одного синьора в команде, вот и приходится наступать на грабли:)). Там тоже улучшился антиалиасинг и фильтрация текстур. Ещё раз спасибо!

Если всё ещё интересно, как выглядит аддитивный блендинг с нормальной гамма-коррекцией, то вот, что у меня получилось:



Внизу слева обычный аддитивный блендинг (Вы правы, в белый мы теперь вываливаемся медленнее), справа — с экспозицией 1.0 - exp(-0.8*c).

Теперь пара слов для тех, кто ещё считает, что WBOIT — это аналог аддитивного блендинга, с той же областью применения. Вот на этой картинке сверху видно, что тёмные цвета (у длинных радиальных треугольников с жёлтыми кромками) при аддитивном блендинге практически не влияют на результирующий цвет (именно потому что они тёмные, т.е. имеют маленькие числовые значения). При использовании WBOIT их вклад в результирующий цвет пропорционален значению opacity, они реально могут затемнить свой кусок экрана. Мы вычисляем взвешенную сумму цветов, значит, результат никогда не выйдет за пределы цветов, которые мы смешиваем. Это позволяет использовать метод для рендеринга прозрачных объектов. Аддитивный блендинг (хоть с экспозицией, хоть без) подходит для рендеринга источников света. Результат может выйти за пределы смешиваемых цветов, как в тёмную, так и в светлую сторону.

У меня вышло, что аддитивный блендинг с экспозицией по сравнению с WBOIT — это минус 2 текстуры, минус 1 фреймбуфер, и шейдер конечного постпроцессинга чуть попроще. Положа руку на сердце, это не сильно упрощает рендеринг. К тому же, коэффициент экспозиции надо подбирать для каждой конкретной сцены.

WBOIT в OpenGL: прозрачность без сортировки

0
Если я правильно понял, то это и есть то, что я нарисовал в предыдущем комментарии. Без деления на получается взвешенная сумма цветов вместо взвешенного среднего. Т.е. мы умножаем цвет каждого фрагмента на его альфу, складываем всё это и выводим на экран. Сложная конструкция из фреймбуферов нужна как раз для того, чтобы, во-первых, поделить на , во-вторых, особым образом смешать цвета прозрачных и непрозрачных объектов, раз уж мы решили рисовать их отдельно.

WBOIT, как и обычный блендинг, — это интерполяция; они не допускают того, чтобы цвет вышел за рамки смешиваемых цветов, поэтому они и используются для рендеринга прозрачных объектов. Аддитивное смешивание, насколько я знаю, рекомендуется применять для рисования источников света (частиц огня, например). Оно приводит к бесконтрольному осветлению цветов. Чем больше фрагментов смешивается, тем светлее получается результирующий цвет, вплоть до белого (в большинстве случаев). Это видно на картинке из предыдущего комментария. Единственное, что есть общего с WBOIT — это то, что нет необходимости в сортировке.

WBOIT в OpenGL: прозрачность без сортировки

0
Если просто из формулы (2) убрать деление на , то выглядит это так:


Вы это имели в виду?

Комитет Госдумы: за лайки и репосты сохранится уголовная ответственность

0
Вы думаете, что такие штрафы в Германии — это правильно?

Корпоративный синдром

+4
1. Если у вас тупые правила, то глупо винить тех, кто их исполняет. Виноват тот, кто их внедряет. Светлана Владимировна, конечно, красиво и пафосно всех отругала, но вина в первую очередь на ней лежит. Если это, конечно, она утвердила конкурс.
2. Сергей тоже хорош. Пытается победить в споре за счет того чтобы унизить и высмеять, вместо того чтобы спокойно аргументировать. Это всё приемы голимой демагогии, присущей политиканам и пропагандистам. На конструктивный лад топ-менеджеров это совещание точно не настроило. А только подготовило почву для еще большей грызни, интриганства и прочих прелестей корпоративной жизни.

Как не надо писать код

0
Почему в примере «про move и лямбду» выводятся только 3 строчки в cout?

«return std::move(f);» в теле лямбды конструирует временный объект типа Foo («Foo(Foo&&)» или «Foo(const Foo&)» — не важно). Это 3-я строчка. Дальше нужно из этого временного объекта сконструировать объект f2. Значит, должна быть 4-я строчка?

Learn OpenGL. Урок 5.3 — Карты теней

0
Я придумал использовать GL_LINEAR, чтобы избавиться (вообще!) от одной из этих проблем — зависимости смещения от скалярного произведения dot(normal, lightDir), которое авторы статьи добавляют в шейдер. Я могу себе представить ситуацию, когда такая зависимость создает дополнительные артефакты.

Если автору использовать GL_NEAREST было удобно для статьи (и только), то он бы, может быть, написал в конце пару слов о GL_LINEAR. Я задал тот же вопрос в комментариях к оригинальной статье. Там все обсуждения велись 2-3 года назад, так что вряд ли они даже заметят. Но если ответят что-нибудь интересное, напишу здесь перевод.

Learn OpenGL. Урок 5.3 — Карты теней

+1
Почему используется фильтр GL_NEAREST? Я так понимаю, что при использовании GL_LINEAR зигзагообразная линия на 7-м рисунке превратится в прямую, и «муаровые узоры» исчезнут? Я немного поигрался с этим примером. Если применить линейную фильтрацию:
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

то при небольшом смещении (bias = 0.005) муаровые узоры не появляются при любых углах освещения (я менял координату Y в переменной lightPos). И это логично, что при линейной интерполяции смещение не должно зависеть от угла освещения. Углы у теней получаются слегка скругленные, а «peter panning» из-за маленького смещения почти незаметен.

Так почему не использовать линейную фильтрацию?

Флаги в аргументах функций

-1
Ну, Вы уже зашли туда, где нужен объект с тремя состояниями в качестве параметра, а статья все-таки про флажки.

Автор пишет, что использовать в качестве флагов перечисления или tagged_bool — это вопрос личных предпочтений. Почитайте комментарий ARNAUD к оригинальной статье — я его тоже перевел.

Флаги в аргументах функций

+1
Комментаторы в оригинальной статье тоже это заметили. После самой статьи я привожу перевод нескольких таких комментариев с ответами автора.

Флаги в аргументах функций

+2
Имеются в виду контекстные преобразования.

Есть один момент, который не все знают. Если объявить оператор преобразования как explicit:

    struct A {
        explicit operator bool() { return false; }
    };


то компилятор не сможет делать неявные преобразования:

    auto foo = [](bool) { return; };

    A a;
    foo(a); // не компилируется


А контекстные — сможет:

    while (a);
    do { if (a) assert(false); } while (a);
    assert(!a && (a || true));
    for(a ? 5 : 6; a;);
    // кроме того, explicit operator bool допускает использование объектов
    // класса в выражениях static_assert и noexcept

Создание параметрических объектов базы в nanoCAD Механика (Часть 3)

+1
Было бы здорово увидеть ссылки на предыдущие части в начале статьи, а не в тексте.

Сумма сумм арифметических прогрессий

0
Да, у меня как раз та же задача, что с шарами и перегородками. Ответ на нее — C из N по l. Это тут все заметили, кроме меня. Спасибо.

Насколько я понял, динамическое программирование — это метод решения рекуррентной зависимости. Если реализовать эту зависимость без рекурсии и с минимальной (но достаточной) мемоизацией, то получится ДП. У меня тут две зависимости (формулы для r > 0), реализованные просто через рекурсивные функции. Это дело техники — реализовать их с помощью ДП. Главная сложность в том, чтобы получить сами зависимости. Или я что-то упускаю?

Я совсем не мастер оценивать сложность, но думаю, для 1-й формулы она будет пропорциональна r(l — 1), а для второй — пропорциональна l(n — 2r — 1). Это с мемоизацией, конечно же.

Сумма сумм арифметических прогрессий

0
Я думаю, что разобрался с доказательством. Там применяется метод мат. индукции 2 раза: сначала по l, потом по n. Я исправил статью. Формулы остались те же, но добавились пояснения.

Сумма сумм арифметических прогрессий

0
Да, там одна формула встречалась в статье 3 раза, и в ней была опечатка. Уже исправил. Спасибо!

Насчет доказательства еще подумаю. Но, как указали выше, это число сочетаний. Так что формула доказана без всякой мат. индукции.

Сумма сумм арифметических прогрессий

+1
Не то чтоб не изучал, а просто забыл ее напрочь. Это и правда число сочетаний.

Чувствую себя идиотом. А Вам спасибо.