Source SDK

Source SDK

Not enough ratings
Visión nocturna "Motor Source" (desactualizado)
By H-H-G-M
   
Award
Favorite
Favorited
Unfavorite
Resumen
Este ejemplo es un intento muy temprano (funciona), y sólo una de las muchas maneras de conseguir que el Modo de Visión Nocturna funcione con su mod.
Configuración del ConVar
Abre el archivo src/cl_dll/view_scene.cpp, y añade el siguiente código al final de este ifdef

//----------------------------------------------------------------------------- // Precache de materiales necesarios //----------------------------------------------------------------------------- #ifdef HL2_CLIENT_DLL

Se encuentra alrededor de la línea 170 (para ir a un número de línea rápidamente, pulse ctrl+g)

//Visión nocturna Precache CLIENTEFFECT_MATERIAL( "HUDoverlays/nightvision" )

Ahora salta al final de la página (ctrl+fin) y añade esta clase

//nightfall - amckern - amckern@yahoo.com //NightVision static void ScreenOver_f( void ) { IMaterial *pMaterial = materials->FindMaterial( "HUDoverlays/nightvision", TEXTURE_GROUP_OTHER, true ); //Esta es la textura que vamos a utilizar para el "efecto" - nunca utilice una extensión en los archivos de material { static bool bDisplayed = false; if( bDisplayed ) { // apagarlo view->SetScreenOverlayMaterial( NULL ); // Deactivate the 'light' cvar->FindVar("mat_fullbright")->SetValue(0); CLocalPlayerFilter filter; C_BaseEntity::EmitSound( filter, 0, "Nightfall.NightVisOff" ); //reproducir el sonido de apagado } else { // turn it on view->SetScreenOverlayMaterial( pMaterial ); //this is the HUDoverlays/nightvision texture we made a pointer to above // Activate the 'light' cvar->FindVar("mat_fullbright")->SetValue(1); CLocalPlayerFilter filter; C_BaseEntity::EmitSound( filter, 0, "Nightfall.NightVisOn" ); //On we go - play a sound to let the player know that the NV is on } bDisplayed = !bDisplayed; //comprobar si se ha desactivado o activado el 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 );

Así que lo que hemos hecho aquí es establecer una cvar bool (on/off) que activa o desactiva el efecto de visión nocturna. Si lees los comentarios, entenderás lo que hace cada parte.

Esta sección ha sido editada para mantener el truco Fullbright como un truco, para evitar que la gente lo explote - el código ha sido actualizado desde el suministrado en los comentarios.

Puede sonar extraño tener la función de apagado primero, pero no quieres que el jugador esté corriendo por el juego con la visión nocturna encendida desde el momento en que aparece.
El sonido
Nightfall.NightVisOn / Nightfall.NightVisOff

Este código está llamando al archivo de script nightfall_engine_sounds.txt que a su vez está precargado en game_sounds_manifest.txt así

"precache_file" "scripts/nightfall_engine_sounds.txt"

Los sonidos son precacheados con PrecacheScript("Nightfall.NightVisOn"); en la función precache del player.cpp, por si te preguntas por qué el juego se retrasa cuando vas a usar el efecto de sonido.

Siempre puedes usar un evento de sonido directo como engine->ClientCmd( "play your_effect_sound.wav/n"); si no sabes cómo hacer un sonido soundscript. La desventaja de esto es que el juego siempre se retrasará mientras carga el archivo de sonido por primera vez, y por lo que se entiende, no hay manera de precargar un archivo de sonido directamente dentro del código.
Visión nocturna con sombreadores
La creación de nightvision con un shader requiere 5 cosas, los archivos HLSL de píxeles y vértices del shader, el archivo C++ del shader, el material que utiliza el shader y una forma de activar el material desde el juego. Esto asume que has configurado y sabes cómo compilar los shaders como se muestra aquí. El crédito va para wraiyth por sus increíbles y útiles tutoriales sobre HLSL.

El sombreador de píxeles:

#include "common_ps_fxc.h" const HALF Brightness : register (c0); //esta es una variable para establecer lo brillante que será la NV. sampler BaseTextureSampler : register( s0 ); //un muestreador para obtener la textura sobre la que se utilizará este shader (en este caso será un frame buffer) HALF4 main(float2 iTexCoord : TEXCOORD0) : COLOR //out main function { float4 vAdd = float4(0.1,0.1,0.1,0); // sólo un float4 para usarlo después 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); // these 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; //de lo contrario, configúralo con un color promedio de las 4 imágenes que acabamos de sumar } float4 cTempColor = cColor; //un nuevo float4 cTempColor para su uso posterior float4 cFinal = cTempColor + vAdd; //añade los flotadores juntos cFinal.g = (cTempColor.r + cTempColor.g + cTempColor.b)/3; // establece el verde como la media de rgb cFinal.r = 0; //elimina los colores rojo y azul cFinal.b = 0; return cFinal * Brightness; // aclarar la imagen final y devolverla }

Save this as post_nightvision_ps20.fxc.

Next up the vertex shader:

#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; }

Guarda esto como PassThrough_vs20.fxc y compila los 2 shaders.

A continuación el archivo C++:

#include "BaseVSShader.h" #include "post_nightvision_ps20.inc" #include "PassThrough_vs20.inc" //archivos generados al compilar los archivos fxc BEGIN_VS_SHADER( Post_NightVision, "Help for Post_NightVision" ) //Comienza el sombreado BEGIN_SHADER_PARAMS SHADER_PARAM(NVLEVEL, SHADER_PARAM_TYPE_FLOAT, "1.0", "") //Este es nuestro parámetro de shader tomado del archivo de material llamado NVLEVEL, escriba "$nvlevel" 10 por ejemplo en el .vmt END_SHADER_PARAMS SHADER_INIT_PARAMS() //se llama después de la inicialización de los parámetros { } SHADER_FALLBACK //no se retrocede a nada (sé que esto funciona en dx9, no se ha probado en otros) { return 0; } bool NeedsFullFrameBufferTexture( IMaterialVar **params ) const //¿Esto necesita la pantalla completa? en nuestro caso sí { return true; } SHADER_INIT //inicializa el sombreador { } SHADER_DRAW { SHADOW_STATE { pShaderShadow->EnableTexture( SHADER_TEXTURE_STAGE0, true ); //enables SHADER_TEXTURE_STAGE0 pShaderShadow->EnableDepthWrites( false ); //las escrituras en profundidad no son necesarias int fmt = VERTEX_POSITION; pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0, 0 ); //establece el formato de los vértices para el .fxc pShaderShadow->SetVertexShader( "PassThrough_vs20", 0 ); //establecer el sombreador de vértices pShaderShadow->SetPixelShader( "post_nightvision_ps20" ); //establecer el sombreado de píxeles DefaultFog(); } DYNAMIC_STATE { float Scale = params[NVLEVEL]->GetFloatValue(); // obtener el valor de NVLEVEL y convertirlo en un float float vScale[4] = {Scale, Scale, Scale, 1}; //nuevo float utilizando los valores de NVLEVEL pShaderAPI->SetPixelShaderConstant(0, vScale); //set the first shader variable to our float pShaderAPI->BindFBTexture( SHADER_TEXTURE_STAGE0 ); //set the shader texture to our frame buffer } Draw(); //dibujar el sombreador } END_SHADER

Añade esto al proyecto game_shader_generic_sample (o cualquier otro que estés usando) y compílalo.

Ahora crea un material en la carpeta de materiales de tus mods, todo lo que necesita es un archivo .vmt:

"Post_NightVision" { "$basetexture" "_rt_FullFrameFB" "$nvlevel" 10 //can be whatever value you want }

Ahora abre view_scene.cpp en el proyecto cliente de tu mod y añade el siguiente código al final:

//----------------------------------------------------------------------------- // NightVision //----------------------------------------------------------------------------- static void NightVision_f ( void ) { C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); //obtener el reproductor local const Vector *vOrigin = &pPlayer->GetAbsOrigin(); //conseguir el origen de los jugadores locales static bool bDisplayed; //static bool if ( bDisplayed ) { view->SetScreenOverlayMaterial( null ); //establecer screenoverlay a nada CLocalPlayerFilter filter; pPlayer->EmitSound(filter, 0, "TestMod.NightVisionOff", vOrigin); //and play sound } else { IMaterial *pMaterial = materials->FindMaterial( "NightVision", TEXTURE_GROUP_OTHER, true); //establecer pMaterial a nuestra textura view->SetScreenOverlayMaterial( pMaterial ); //y superponerlo en la pantalla CLocalPlayerFilter filter; pPlayer->EmitSound(filter, 0, "TestMod.NightVisionOn", vOrigin); //y reproducir un sonido } bDisplayed = !bDisplayed; // cambiar el bool } //night vision console command static ConCommand r_nightvision( "r_nightvision", NightVision_f ); // comando de la consola para activar la función, bíndela escribiendo bind n r_nightvision.

Compílelo y debería tener una visión nocturna con shader que funcione completamente, personalícelo a su gusto. También puedes precargar los sonidos y el material como se ha explicado anteriormente.