В общем, решил я похвастаться своей недавней наработкой. Долгое время был уверен, что если я хочу нормальный свет от фонарика, то надо либо движок менять, либо писать с нуля свой рендерер. Но в итоге за несколько дней попыток "по-приколу посмотреть че из этого выйдет" с помощью некоторых костылей и предыдущих наработок мне удалось сделать то, что в итоге получилось.
Кратко о том, как это работает. Все рисуется в DrawNormalTriangles и DrawTransparentTriangles. Так как стены уже отрисованы, вместо того, чтобы освещать стену, я рисую на этой стене декаль с текстурой альбедо самой этой стены по маске спроецированной текстуры фонарика, ну и дитейл текстуру для полноты картины. Нужно перебирать все видимые сурфейсы, отсекать те, которые точно не должны быть освещены, делать клиппинг по краям стены, к полученным вертексам применить трансформации в зависимости от ненулевых angles и origin энтити, а потом все это рисовать в аддитивном режиме. Линейное затухание света сделать с помощью черного туманчика. Достаточно функционала opengl 1.3, понадобится мультитекстурирование и GL_ENV_COMBINE. Но проще сделать через шейдер, будет производительнее, гибкая настройка, и туманчик не тужен.
Плюсы данного способа:
1. Вы получите красивый фонарик как фпараное. Правда без теней. Тоже как фпараное.
Минусы:
1. Полигоны света рисуются вторым проходом после рендеринга геометрии, поэтому на высокополигональных картах может сильнее просаживаться фпс при включении фонаря. На стандартных картах ХЛ и подобных все летает. На моих только в паре мест наблюдается небольшая просадка, но там в целом надо карту оптимизировать.
2. Чтобы красиво освещать модельки, придется все-таки написать кастомный рендерер студиомоделей. Но если лень с этим разбираться (как мне), можно все так же освещать модель по ее оригину.
3. Рандомно-тайлящиеся текстуры. Так как surf->texture->name - это всегда имя текстуры, которой вы окрасили стену в редакторе (как правило, это первая "-0texname"), а таблица рандомных чисел для тайлинга генерируется движком при запуске игры, то узнать, какая именно текстура сейчас рисуется на стене, мы не можем, и нам придется рисовать первую. Это не выглядит вырвиглазно и даже не всегда заметно. А если вы не используете такие текстуры, то это вовсе не проблема. С анимированными текстурами такой проблемы нет, там все легко считается.
На последнем скриншоте телефон на столе и стул - модельки. Если интересно посмотреть, как это выглядит в динамике, могу записать видео.
__________________ Никогда не поздно сделать мод под хл1
Забыл их упомянуть. У меня в моде кастомные декали, и их поведение с фонарем согласовано. А вот стандартные декали будут просвечиваться. Тут придется либо переписывать рендеринг декалей, либо искать способ рисовать уже нарисованные на поверхности декали. Вроде у структуры msurface_t есть указатель на декали.
__________________ Никогда не поздно сделать мод под хл1
Sigurth очень здорово. Такой фичи не хватало очень многим модам хл на протяжении всех лет существования голдсорса. Во многих из них хоть глаз выколи, ничего не видно.
Как я понял, всё равно приходится линковать либу, и делать вызовы Opengl32.dll из клиентки? Это же нереализуемо средствами движкового API?
Ku2zoff писал: Как я понял, всё равно приходится линковать либу
Ну можно и динамически подгружать, эта либа ж всегда есть в системе.
Но в софтварном режиме работать не будет, конечно.
Цитата:
Ku2zoff писал: Такой фичи не хватало очень многим модам хл на протяжении всех лет существования голдсорса.
Кастомные декали есть мало где, а вот освещение декалей тут реальная проблема. Я вот не уверен, что пасс фонарика не "съедает" декали на сурфасах - они вроде рисуются сразу же после самого сурфаса в голсорсе.
А ты уверен? Может быть можно просто настроить мультитекстурирование и проекционную текстурную матрицу (ну или вершинный шейдер) и просто сделать draw call на клиентке?
Ku2zoff писал: Это же нереализуемо средствами движкового API?
Средствами движка сделать не получится. Так что да, придется подгружать opengl32.dll и работать с opengl напрямую.
Цитата:
XaeroX писал: А ты уверен? Может быть можно просто настроить мультитекстурирование и проекционную текстурную матрицу (ну или вершинный шейдер) и просто сделать draw call на клиентке?
Я пока еще не углублялся в этот вопрос. Но попробую такой способ.
Цитата:
XaeroX писал: освещение декалей тут реальная проблема
Вот так будут выглядеть стандартные декали. Не уверен, что буду пытаться их подружить. Но может быть мне станет интересно, и я попробую. Ну или если будет спрос на тутор или кому-нибудь помочь в мод затащить.
__________________ Никогда не поздно сделать мод под хл1
XaeroX писал: Попробуй убрать аттенуацию вообще - тогда декали пропадут?
Да, тогда фонарик полностью перекроет декали. Они рисуются сразу с сурфейсом. В любом случае придется рисовать "освещенные" декали вручную.
Кстати, огромное спасибо за наводку насчет освещение моделей. Перед вызовом StudioDrawPoints настраиваю фонарик вторым текстурным юнитом, и включаю шейдер, где уже смешиваю мой фонарик с вертексным освещением. Уже есть результаты, осталось потестировать, но пока артефактов не наблюдаю.
На скриншоте дерево - модель с оригином в самом низу, листва с альфа каналом.
__________________ Никогда не поздно сделать мод под хл1