Ночное Виденье Добавление ночного виденья к одиночному моду Здесь описана часть кода которая многих заводила в тупик – Ночное Виденье. Summary Сей пример является единственным путем добавления ночного видинья к вашему моду. Credit should be given to Gnolfo Настройка консольных команд Откройте файл src/cl_dll/view_scene.cpp, и добавьте следующий текст в конец #ifdef'а //----------------------------------------------------------------------------- // Precache of necessary materials //----------------------------------------------------------------------------- #ifdef HL2_CLIENT_DLL Найдите 170 строчку(быстрый переход к строке ctrl+g) //Precache Night Vision CLIENTEFFECT_MATERIAL( "HUDoverlays/nightvision" ) Теперь переместитесь в конец (ctrl+end) и добавьте класс //nightfall - amckern - amckern@yahoo.com //NightVision static void ScreenOver_f( void ) { IMaterial *pMaterial = materials->FindMaterial( "HUDoverlays/nightvision", TEXTURE_GROUP_OTHER, true ); //Эту текстуру будем использовать для создания эффекта - never use an ext on material files { static bool bDisplayed = false; if( bDisplayed ) { // включает эффект view->SetScreenOverlayMaterial( NULL ); // Отключить источник света cvar->FindVar("mat_fullbright")->SetValue(0); CLocalPlayerFilter filter; C_BaseEntity::EmitSound( filter, 0, "Nightfall.NightVisOff" ); //проиграть звук выключения } else { // выключает эффект view->SetScreenOverlayMaterial( pMaterial ); //эту текстуру мы сделали указателем HUDoverlays/nightvision // активирует источник света cvar->FindVar("mat_fullbright")->SetValue(1); CLocalPlayerFilter filter; C_BaseEntity::EmitSound( filter, 0, "Nightfall.NightVisOn" );//проигрывает звук, показывающий игроку, что НВ включено } bDisplayed = !bDisplayed; //проверяет, включен или выключен режим fullbright(mat_fullbright) if (cvar->FindVar("mat_fullbright")->GetInt() == 1)//is it on? cvar->FindVar("mat_fullbright")->SetValue(0);//well turn it off. } } static ConCommand r_screenover( "r_screenover", ScreenOver_f ); Итак, теперь у нас готова булинная переменная(bool cvar (on/off)), которая включает\выключает эффекты НВ.Если вы прочитали комментарии, вы поняли – какая часть за что отвечает. Эта секция была переправлена чтобы отключить команду mat_fullbright. Должно быть звучит странно, что мы добавили функцию выключения первой, но иначе при загрузки карты, эффект применялся бы сразу. Звук Nightfall.NightVisOn / Nightfall.NightVisOff Следующий код в файле назван (nightfall_engine_sounds.txt), который в свою очередь должен быть указан в (game_sounds_manifest.txt) следующей строкой: "precache_file" "scripts/nightfall_engine_sounds.txt" Звуки загружаются со скриптом ("Nightfall.NightVisOn"); в player.cpp Вы так же можете использовать ивент engine->ClientCmd( "play your_effect_sound.wav\n"); если не умеете создавать скрипт со звуками. Обратной стороной команды является то, что игра будет каждый раз подтормаживать, загружая этот звук, поскольку прекэш звука невозможен прямиком из кода. Ночное Виденье с шейдерами Создание НВ с шейдерами требует следующего: HLSL пиксельные и вертыксные шейдеры C++ шейдер файл Материал, использующий шейдр Способ запустить материал из игры Предполагается наличие знаний по компиляции шейдеров, и описанной здесь программы Authoring_Shaders и здесь wraiyth (http://wraiyth.freesuperhost.com) для неоценимо полезных туториалов по HLSL. Вот код пиксельного шейдера: #include "common_ps_fxc.h" const HALF Brightness : register (c0); //this is a variable to set how bright the NV will be. sampler BaseTextureSampler : register( s0 ); //a sampler to get the texture this shader will be used on (in this case it will be a frame buffer) HALF4 main(float2 iTexCoord : TEXCOORD0) : COLOR //out main function { float4 vAdd = float4(0.1,0.1,0.1,0); // just a float4 for use later float4 cColor = tex2D(BaseTextureSampler,iTexCoord); //this takes our sampler and turns the rgba into floats between 0 and 1 cColor += tex2D(BaseTextureSampler, iTexCoord.xy + 0.001); // thses 3 lines blur the image slightly cColor += tex2D(BaseTextureSampler, iTexCoord.xy + 0.002); cColor += tex2D(BaseTextureSampler, iTexCoord.xy + 0.003); if (((cColor.r + cColor.g + cColor.b)/3) < 0.9) // if the pixel is bright leave it bright { cColor = cColor / 4; //otherwise set it to an average color of the 4 images we just added together } float4 cTempColor = cColor; //a new float4 cTempColor for use later float4 cFinal = cTempColor + vAdd; //adds the floats together cFinal.g = (cTempColor.r + cTempColor.g + cTempColor.b)/3; // sets green the the average of rgb cFinal.r = 0; //removes red and blue colors cFinal.b = 0; return cFinal * Brightness; // brighten the final image and return it } Сохраните в файл “post_nightvision_ps20.fxc”. Далее вершинный шейдер: #include "common_vs_fxc.h" void main( in float4 iPosition : POSITION, in float2 iTexCoord : TEXCOORD0, out float4 oPosition : POSITION, out float2 oTexCoord : TEXCOORD0) { oPosition=iPosition; oTexCoord=iTexCoord; } Сохраните файл как “PassThrough_vs20.fxc” и скомпилируйте оба шейдера. Далее C++ файл: #include "BaseVSShader.h" #include "post_nightvision_ps20.inc" #include "PassThrough_vs20.inc" //files generated by compiling the fxc files BEGIN_VS_SHADER( Post_NightVision, "Help for Post_NightVision" ) //Begin the shader BEGIN_SHADER_PARAMS SHADER_PARAM(NVLEVEL, SHADER_PARAM_TYPE_FLOAT, "1.0", "") //Это наш параметр шейдера, взятый из материала, названного NVLEVEL. Пропишите параметр “nvlevel” 10 в .vmt файле нашего эффекта. END_SHADER_PARAMS SHADER_INIT_PARAMS() //called after parameters have been initalised { } SHADER_FALLBACK //не ухудшать качество, (тестировалось только на DirectX9) { return 0; } bool NeedsFullFrameBufferTexture( IMaterialVar **params ) const //В нашем случае эффект нуждается в полном экране. { return true; } SHADER_INIT //initializes the shader { } SHADER_DRAW { SHADOW_STATE { pShaderShadow->EnableTexture( SHADER_TEXTURE_STAGE0, true ); //активирует SHADER_TEXTURE_STAGE0 pShaderShadow->EnableDepthWrites( false ); //depth writes aren't needed int fmt = VERTEX_POSITION; pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0, 0 ); //устанавливает формат вертексов для.fxc pShaderShadow->SetVertexShader( "PassThrough_vs20", 0 ); //устанавливает вершинный шейдер pShaderShadow->SetPixelShader( "post_nightvision_ps20" ); //устанавливает пиксельный шейдер DefaultFog(); } DYNAMIC_STATE { float Scale = params[NVLEVEL]->GetFloatValue(); //получает значение NVLEVEL и делает его переменной float vScale[4] = {Scale, Scale, Scale, 1}; //новая переменная, использующая значения NVLEVEL pShaderAPI->SetPixelShaderConstant(0, vScale); //применяет значение нашей переменной к переменной первого шейдера pShaderAPI->BindFBTexture( SHADER_TEXTURE_STAGE0 ); //set the shader texture to our frame buffer } Draw(); //draw the shader } END_SHADER Добавьте вышеописанное к проекту game_shader_generic_sample, или к тому, который создали вы, и откомпилируйте. Теперь создадим материал .vmt в папке с материалами вашего мода и в нем пишем: "Post_NightVision" { “$basetexture” “_rt_FullFrameFB” "$nvlevel" 10 //can be whatever value you want } Откроем view_scene.cpp в вашем проекте и добавим код внизу. //----------------------------------------------------------------------------- // NightVision //----------------------------------------------------------------------------- static void NightVision_f ( void ) { C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); //get the local player const Vector *vOrigin = &pPlayer->GetAbsOrigin(); //get the local players origin static bool bDisplayed; //static bool if ( bDisplayed ) { view->SetScreenOverlayMaterial( null ); //убирает значение оверлея экрана CLocalPlayerFilter filter; pPlayer->EmitSound(filter, 0, "TestMod.NightVisionOff", vOrigin); //и проигрывает звук } else { IMaterial *pMaterial = materials->FindMaterial( "NightVision", TEXTURE_GROUP_OTHER, true); //set pMaterial to our texture view->SetScreenOverlayMaterial( pMaterial ); //и проявляет оверлей на экран CLocalPlayerFilter filter; pPlayer->EmitSound(filter, 0, "TestMod.NightVisionOn", vOrigin); //и проигрывает звук } bDisplayed = !bDisplayed; // flip flop the bool } //night vision console command static ConCommand r_nightvision( "r_nightvision", NightVision_f ); //Консольная команда, запускающая функцию НВ. Поставьте ее на клавишу, прописав в консоли bind n r_nightvision. Компилируйте проект и у вас будет полностью работающий шейдер, управляющий ночным видиньем. Вы так же можете сделать прекэш звуков и материалов выщеуказанным способом.
Источник: http://developer.valvesoftware.com/wiki/NightVision |