Hi, I’m working on a small MOD, and there’s one thing I was wondering, how hard would it be to add a blur, so that when you’re under water everything is blurred? Would it be possible? I don’t mind having to code it in, but I don’t understand much C++, so I’d need someone to tell me what I’d need to do/change/add, if it’s even possible. Thanks ahead.
It should be possible, and I’m a bit miffed that Valve not only hasn’t put that in, but also took out the underwater ambient sound in the HL2 '09 update.
I dunno what you’d need, but I expect it would be as simple as coding it to overlay a blur & refract shader on the screen when the player goes underwater. (refract because your vision is also distorted underwater) How to make the shader, I dunno, but the Valve wiki probably has a tutorial somewhere.
Well, I’ve looked around on the wiki and havn’t found anything. I’ll keep looking into it though. Thanks for the help.
you have to check the water level of the player and add a screenoverlay if the waterlevel is 3
GetWaterLevel();
he doesn’t need a new shader.
add this to void C_BasePlayer::CreateWaterEffects( void )
if ( GetWaterLevel() < 3 )
{
view->SetScreenOverlayMaterial( NULL );
m_bResampleWaterSurface = true;
return;
}
IMaterial *pOverlay = materials->FindMaterial("effects/wateroverlay", TEXTURE_GROUP_CLIENT_EFFECTS, false);
if(!IsErrorMaterial(pOverlay))
{
view->SetScreenOverlayMaterial(pOverlay);
}
wateroverlay is your material which blurs the image
something like this:
"Refract"
{
"$normalmap" "dev/water_normal"
"$dudvmap" "dev/water_dudv"
"$refractamount" 0.05
"$bluramount" 1.6
"Proxies"
{
"AnimatedTexture"
{
"animatedtexturevar" "$normalmap"
"animatedtextureframenumvar" "$bumpframe"
"animatedtextureframerate" 30.00
}
}
}
And where do I check the “water level”, and where do I change/add all this code? It looks like the last one is in the .vmt, but I have no idea for the others. Thanks for the help.
at line 1127 in c_baseplayer.cpp(clientside) in the function
void C_BasePlayer::CreateWaterEffects( void )
find
if ( GetWaterLevel() < 3 )
{
m_bResampleWaterSurface = true;
return;
}
and replace it with
if ( GetWaterLevel() < 3 )
{
view->SetScreenOverlayMaterial( NULL );
m_bResampleWaterSurface = true;
return;
}
IMaterial *pOverlay = materials->FindMaterial("effects/wateroverlay", TEXTURE_GROUP_CLIENT_EFFECTS, false);
if(!IsErrorMaterial(pOverlay))
{
view->SetScreenOverlayMaterial(pOverlay);
}
Note: the function you change is already responsible for water effects, in that function you can add any effect, which should be only active when in water
but that’s just a simple unoptimized solution, you better move the
IMaterial *pOverlay
into the declaration of C_BasePlayer as public and initialize it in the spawn() function
class C_BasePlayer : public C_BaseCombatCharacter
{
public:
...
IMaterial *pOverlay;
...
};
void C_BasePlayer::Spawn( void )
{
...
pOverlay = materials->FindMaterial("effects/wateroverlay", TEXTURE_GROUP_CLIENT_EFFECTS, false);
...
}