Работаю над освещением частиц:
Используется процедурная сферическая карта нормалей — то есть, каждый биллборд системы частиц интерпретируется пиксельным шейдером как виртуальная сфера. Планируются и пользовательские карты нормалей.
Реализовано путем отброса пикселей с прозрачностью ниже порогового значения при рендеринге частиц в теневую карту. Конечно, такая техника не позволяет рендерить прозрачные тени от дыма, но и такой результат все же лучше, чем полное отсутствие теней или, тем более, тени в виде квадратиков.
В ближайшее время планирую реализовать поддержку кубических карт с полноценным интегрированием Монте-Карло (сейчас используются равнопромежуточные карты с простым box-фильтром, формируемые стандартным mip-генератором OpenGL, что, конечно, дает достаточно далекий от физически корректного результат, хотя и визуально приемлемый). Также обдумываю вариант загрузки кубической карты из файла DDS, что позволяет строить мип-уровни в сторонних утилитах типа CubeMapGen.
Вскрылись проблемы с работой движка под macOS — поскольку у меня нет возможности тестировать его под этой ОС, поддержка Mac отныне не гарантирована. Но буду благодарен, если кто-то исследует эту проблему и предложит решение.
Одновременно я начал работу над поддержкой отложенного освещения и уже добился результата. Заодно реализовал SSAO, мягкие частицы и улучшил функцию неба, что заметно на высоких значениях шероховатости.
Скорее всего, отложенный рендер полностью заменит кластерный. Для прозрачных объектов я планирую ввести классический прямой метод освещения с отбором ближайших к объекту источников света.
Кстати, модель средневекового дома (и еще несколько моих игровых моделей) вы можете купить по более чем скромным ценам на CGTrader, чем поддержите мой проект по созданию современного 3D-движка для D.
Изменения в dlib:
Пост-обработка в Dagon теперь стала намного проще — все встроенные фильтры легко включаются/выключаются и настраиваются при помощи специального API, являющегося частью класса BaseScene3D. Есть и возможность добавлять свои фильтры.
vec4 shadowCoord = shadowMatrix * vec4(eyePosition + eyeNormal * height * 0.3, 1.0);
Таким образом, мы создаем фейковую точку, расположенную выше реальной поверхности, и тень для нее будет рассчитываться как если бы поверхность была действительно рельефной. Эффект особенно заметен на краях тени, углах и скруглениях — там, где при обычном расчете теневых координат была бы сплошная тень, появляются освещенные участки:
Главный недостаток метода — расчет теневых координат происходит пофрагментно, а не повершинно, но на современном железе это не слишком большая жертва.
Не знаю, использовалась ли такая техника раньше, и как она называется — может быть, что-то вроде height-corrected shadow mapping?