Modera 329 Опубликовано 18 апреля, 2022 Играю тут в НС 2010, там есть прозрачный аномальный бизон, которым вооружаются враги в невидимых экзоскелетах. Симпатичная штуковина. Однако если эту пушку взять в руки, то вместо прозрачного бизон станет просто блестящим, с текстурой воды. Дело в том что если просто назначить прозрачные шейдеры худовой модели оружия, то модель сильно уедет вперёд. Это связано с тем, что все худовые модели в сталкере рисуются с уменьшенным, в два раза примерно, углом обзора, для того чтобы нивелировать эффект рыбьего газа, который возникает если рисовать худ с полным углом обзора, что можно лицезреть в таких играх как крайзис и сурвариум, и это одна из причин почему я считаю их отстоем. Однако с прозрачными шейдерами уменьшение угла обзора почему-то не срабатывает, и получается то что можно видеть на скрине выше. Чтобы это пофиксить нужно создать специальный костыльный шейдер прозрачности для худа, который рисует всё с уменьшенным углом обзора. В модели аномального бизона для прозрачности используется шейдер models\pautina, на его основе и будем делать. Поэтому лезем в gamedata\shaders\r1 и находим там файл models_pautina.s. Если его открыть можно увидеть такой код: function normal (shader, t_base, t_second, t_detail) shader:begin ("model_distort4ghost","particle") -- particle_alphaonly : sorting (3, true) : blend (true,blend.srccolor,blend.invsrcalpha) : aref (true,0) : zb (true,false) : fog (false) : distort (false) shader:sampler ("s_base") :texture (t_base) end function l_special (shader, t_base, t_second, t_detail) shader:begin ("model_distort4ghost","particle_distort") : sorting (3, true) : blend (true,blend.srcalpha,blend.invsrcalpha) : zb (true,false) : fog (false) : distort (true) shader:sampler ("s_base") :texture (t_base) shader:sampler ("s_distort") :texture ("pfx\\pfx_dist_glass") //:texture (t_base) -- ("pfx\\pfx_dist_glass2" end function normal (shader, t_base, t_second, t_detail) shader:begin ("model_def_lplanes","base_lplanes") : fog (false) : zb (true,false) : blend (true,blend.srccolor,blend.one) : aref (true,0) : sorting (2, true) shader:sampler ("s_base") :texture (t_base) end Во первых, тут у нас две функции normal, что конечно является ошибкой разработчиков в самом деле используется только одна, вторая, поэтому первую лучше удалить чтобы не путаться. НО это нам с прозрачностью на худе не поможет. Дальше нужно поменять имя вершинного шейдера, которое идёт первым параметром функции shader:begin, ведь именно там применяются все транформации, в том числе и угол обзора. Я заменил model_distort4ghost и model_def_lplanes на model_distort4ghost_hud, в итоге получился такой файл: function l_special (shader, t_base, t_second, t_detail) shader:begin ("model_distort4ghost_hud","particle_distort") : sorting (3, true) : blend (true,blend.srcalpha,blend.invsrcalpha) : zb (true,false) : fog (false) : distort (true) shader:sampler ("s_base") :texture (t_base) shader:sampler ("s_distort") :texture ("pfx\\pfx_dist_glass") //:texture (t_base) -- ("pfx\\pfx_dist_glass2" end function normal (shader, t_base, t_second, t_detail) shader:begin ("model_distort4ghost_hud","base_lplanes") : fog (false) : zb (true,false) : blend (true,blend.srccolor,blend.one) : aref (true,0) : sorting (2, true) shader:sampler ("s_base") :texture (t_base) end Сохраняю его под именем gamedata\shaders\r1\models_pauhuda.s, имя нового шейдера прозрачности для худа будет models\pauhuda. Обратите внимание что в оригинале использовалось два разных вершинных шейдера (model_def_lplanes и model_distort4ghost), но я буду использовать только один, т.к. они всё-ровно не сильно отличаются. Дальше самое интересное, нужно создать вершинный шейдер. Делать его будем на основе model_distort4ghost, поэтому копируем model_distort4ghost.vs и переименовываем его как model_distort4ghost_hud.vs, и смотрим что у него внутри: #include "common.h" #include "skin.h" struct vf { float4 hpos : POSITION; float2 tc0 : TEXCOORD0; // base float4 c0 : COLOR0; // color }; vf _main (v_model v) { vf o; o.hpos = mul (m_WVP, v.pos); // xform, input in world coords o.tc0 = v.tc.xy; // copy tc // calculate fade float3 dir_v = normalize (mul(m_WV,v.pos)); float3 norm_v = normalize (mul(m_WV,v.norm)); float fade = 0.9*abs (dot(dir_v,norm_v)); o.c0 = fade; return o; } ///////////////////////////////////////////////////////////////////////// #ifdef SKIN_NONE vf main(v_model v) { return _main(v); } #endif #ifdef SKIN_0 vf main(v_model_skinned_0 v) { return _main(skinning_0(v)); } #endif #ifdef SKIN_1 vf main(v_model_skinned_1 v) { return _main(skinning_1(v)); } #endif #ifdef SKIN_2 vf main(v_model_skinned_2 v) { return _main(skinning_2(v)); } #endif И где же здесь применяется угол обзора? А вот в этой строчке: o.hpos = mul (m_WVP, v.pos); // xform, input in world coords Тут нужно немного пояснить что к чему. Угол обзора заключен в матрице m_WVP, которая на самом деле является комбинацией трёх основных матриц m_W, m_V, и m_P. Так же в шейдерах доступны и другие комбинации этих матриц, m_WV к примеру. Буквы W, V, P это первые буквы от слов World, View, Projection. Не буду сильно вдаваться в подробности того как это работает и для чего нужно, скажу только что угол обзора находится в m_P. Если взглянуть на функцию создания такой матрицы, то можно узнать что: a) для конструирования матрицы на нужен угол обзора, соотношение сторон екрана, а так же дистанция ближней и дальней отсекающих плоскостей б) угол обзора и соотношение сторон можно получить обратно из готовой матрицы путём нехитрым математических вычислений ( отношение сторон как m_P[1][1] / m_P[0][0], а угол как atan( 1.0 / m_P[1][1] ) ) С этими знаниями уже можно выцарапать угол и соотношение сторон из готовой матрицы m_P, поделить угол на два и сконструировать новую матрицу m_P_fix с исправленным углом обзора, а плоскости отсечения можно не трогать. Чтож, меньше слов, больше дела. Модифицируем наш вершинный шейдер model_distort4ghost_hud таким образом: #include "common.h" #include "skin.h" struct vf { float4 hpos : POSITION; float2 tc0 : TEXCOORD0; // base float4 c0 : COLOR0; // color }; vf _main (v_model v) { vf o; float hud_fov = 0.45; float aspect_ratio = m_P[1][1] / m_P[0][0]; float half_fovy = atan( 1.0 / m_P[1][1] ); float4x4 m_P_fix = m_P; m_P_fix[1][1] = 1.0 / tan(half_fovy * hud_fov); m_P_fix[0][0] = m_P_fix[1][1] / aspect_ratio; float3 view_pos = mul(m_WV, v.pos); o.hpos = mul (m_P_fix, float4(view_pos, 1)); // xform, input in world coords o.tc0 = v.tc.xy; // copy tc // calculate fade float3 dir_v = normalize (mul(m_WV,v.pos)); float3 norm_v = normalize (mul(m_WV,v.norm)); float fade = 0.9*abs (dot(dir_v,norm_v)); o.c0 = fade; return o; } ///////////////////////////////////////////////////////////////////////// #ifdef SKIN_NONE vf main(v_model v) { return _main(v); } #endif #ifdef SKIN_0 vf main(v_model_skinned_0 v) { return _main(skinning_0(v)); } #endif #ifdef SKIN_1 vf main(v_model_skinned_1 v) { return _main(skinning_1(v)); } #endif #ifdef SKIN_2 vf main(v_model_skinned_2 v) { return _main(skinning_2(v)); } #endif Тут конструируется матрица m_P_fix с уменьшенным до 45% углом обзора, потом точка из модели (v.pos) трансформируется сначала стандартной матрицей m_WV (комбинацией m_W и m_V), а уже потом исправленной матрицей m_P_fix. Строго говоря значение переменной hud_fov (0.45) должно быть равным значению одноимённой консольной команды hud_fov. В финальной версии игры эта команда заблокирована, а значение константно и никогда не меняется. Впрочем, всякие движковые моды типа FOV switcher могут его менять. Ну всё, шейдер готов, осталось только указать его в модели. Лезем в геймдату, открываем gamedata\meshes\weapons\bizo1\wpn_bizon_hud1.ogf через СДК, или по старинке через хекс-редактор, меняем все шейдеры models\pautina на models\pauhuda, а потом смотрим на результат: А вот так эта модель выглядит с родными текстурами оружия, вместо текстуры воды: Короче вот готовый пример прозрачного шейдера для худа + модель аномального бизона которая его использует (для Народной Солянки 2010): https://drive.google.com/file/d/1W4R28ON2x8z1u_xlw2ACOdfi-9YEYGra/view?usp=sharing А задачу создания такого шейдера для R2 рендера я оставляю вам в качестве домашнего задания, гегеге. 1 2 1 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Mad Hikki 343 Опубликовано 18 апреля, 2022 Когда-нибудь кому то пригодится Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
I am dead 1 182 Опубликовано 18 апреля, 2022 Обычный шейдер прозрачности это какая то шутка? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Modera 329 Опубликовано 18 апреля, 2022 31 минуту назад, I am dead сказал: Обычный шейдер прозрачности это какая то шутка? С обычным шейдером будет вот такой вытянутый результат. Хотя с тем что я предложил тоже есть баг, модель может исчезать в стене если вплотную встать. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Policai 1 323 Опубликовано 19 апреля, 2022 Осталось понять зачем в Сталкере прозрачное оружие..))) 1 Группа мода в VK Мод делался и тестировался на железе i5-11400, 32Гб ОЗУ, Radeon RX580 Разрешение 2560 х 1440. ВСЕ на максималке Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
denis2000 951 Опубликовано 19 апреля, 2022 Policai Дело не в прозрачном оружии (хотя помню как неказисто выглядело "невидимое" оружие призраков в руках ГГ). Когда мы делали ХУД-использование предметов ГГ крайне не хватало нормального шейдера с прозрачностью для бутылки с водкой например. 1 Путь во мгле. Связь времен."Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
I am dead 1 182 Опубликовано 19 апреля, 2022 (изменено) 10 часов назад, Modera сказал: С обычным шейдером будет вот такой вытянутый результат. Хмм, как жаль что у меня такого бага нету... Дополнено 0 минут спустя Дополнено 5 минуты спустя Наверное я что то делаю не так... Изменено 19 апреля, 2022 пользователем I am dead Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Modera 329 Опубликовано 19 апреля, 2022 14 часов назад, I am dead сказал: Хмм, как жаль что у меня такого бага нету... Дополнено 0 минут спустя Дополнено 5 минуты спустя Наверное я что то делаю не так... Значит в некоторых движках эту бяку исправили. Но в ванильном ТЧ и ЧН точно есть. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
denis2000 951 Опубликовано 20 апреля, 2022 7 часов назад, Modera сказал: Но в ванильном ТЧ и ЧН точно есть. И в оригинальном ЗП тоже. А уж как и где это исправляли другой вопрос. Путь во мгле. Связь времен."Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты