Pull to refresh
16
0
Send message

Какие все? В Азербайджане одна ТЭЦ есть только в Баку, насколько я знаю, и к ней подключён не весь город. В Грузии и в Армении центрального отопления вообще нет.

Справились бы и без Йоты. Отрубили бы электричество, Интернет, заглушили бы вайфай и сотовую связь. А скорее всего, просто приняли бы на входе или выходе из квартиры, и сразу забрали бы телефон.
Ну да, я вообще никому не советовал бы использовать WBOIT с альфа > 0,5. В статье это всё объясняется с картинками :)
Благодарю за то, что указали на отсутствие гамма-коррекции. Я полез разбираться с этой темой и многое для себя уяснил. У меня и правда отсутствовала гамма-коррекция, и это, наверное, было заметно по плохому антиалиасингу. Вычисления с цветом происходили в линейном пространстве, потом к ним применялась LUT монитора, к этому добавлялась низкая точность хранения тёмных тонов в 8-битном буфере, и получались рваные края примитивов. Теперь цвета преобразуются в линейное пространство перед отправкой в OpenGL, а при выводе на экран — в sRGB (аппаратно). Выглядит получше.

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

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

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



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

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

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

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


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

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

Если автору использовать GL_NEAREST было удобно для статьи (и только), то он бы, может быть, написал в конце пару слов о GL_LINEAR. Я задал тот же вопрос в комментариях к оригинальной статье. Там все обсуждения велись 2-3 года назад, так что вряд ли они даже заметят. Но если ответят что-нибудь интересное, напишу здесь перевод.
Почему используется фильтр 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» из-за маленького смещения почти незаметен.

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

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

Есть один момент, который не все знают. Если объявить оператор преобразования как 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

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

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

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

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

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

Information

Rating
Does not participate
Registered
Activity