diff options
| author | Joe Ludwig <[email protected]> | 2013-12-23 14:58:45 -0800 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-12-23 15:00:03 -0800 |
| commit | 7309a5f13f63fdcc7b1e090f6c176113a9d95061 (patch) | |
| tree | ad65c7fbe46a3c70bdc0a1426e88247ce1b0d7f5 /sp/src/materialsystem/stdshaders/water.cpp | |
| parent | Merge pull request #182 from ardneran/master (diff) | |
| download | source-sdk-2013-7309a5f13f63fdcc7b1e090f6c176113a9d95061.tar.xz source-sdk-2013-7309a5f13f63fdcc7b1e090f6c176113a9d95061.zip | |
Added many shader source files
This should include the latest version of every shader that was in the
2007 SDK. It also includes a smattering of debug shaders, both VR
distortion shaders, and other assorted shaders that will hopefully be
useful.
None of these new files are included in the game shader DLL project. If
you need to modify one of these shaders for use in your mod you will
need to rename it so that you don't collide with the version of that
shader that lives in stdshader_dx9.dll.
Diffstat (limited to 'sp/src/materialsystem/stdshaders/water.cpp')
| -rw-r--r-- | sp/src/materialsystem/stdshaders/water.cpp | 614 |
1 files changed, 614 insertions, 0 deletions
diff --git a/sp/src/materialsystem/stdshaders/water.cpp b/sp/src/materialsystem/stdshaders/water.cpp new file mode 100644 index 00000000..92a26375 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/water.cpp @@ -0,0 +1,614 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" +#include "mathlib/vmatrix.h" +#include "common_hlsl_cpp_consts.h" // hack hack hack! +#include "convar.h" + +#include "WaterCheap_vs20.inc" +#include "WaterCheap_ps20.inc" +#include "WaterCheap_ps20b.inc" +#include "Water_vs20.inc" +#include "Water_ps20.inc" +#include "water_ps20b.inc" + +#ifndef _X360 +static ConVar r_waterforceexpensive( "r_waterforceexpensive", "0", FCVAR_ARCHIVE ); +#endif + +DEFINE_FALLBACK_SHADER( Water, Water_DX9_HDR ) + +BEGIN_VS_SHADER( Water_DX90, + "Help for Water" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( REFRACTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_WaterRefraction", "" ) + SHADER_PARAM( REFLECTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_WaterReflection", "" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" ) + SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" ) + SHADER_PARAM( REFLECTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0.8", "" ) + SHADER_PARAM( REFLECTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "reflection tint" ) + SHADER_PARAM( NORMALMAP, SHADER_PARAM_TYPE_TEXTURE, "dev/water_normal", "normal map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( SCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "" ) + SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "", "" ) + SHADER_PARAM( WATERDEPTH, SHADER_PARAM_TYPE_FLOAT, "", "" ) + SHADER_PARAM( CHEAPWATERSTARTDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "This is the distance from the eye in inches that the shader should start transitioning to a cheaper water shader." ) + SHADER_PARAM( CHEAPWATERENDDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "This is the distance from the eye in inches that the shader should finish transitioning to a cheaper water shader." ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "env_cubemap", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( FOGCOLOR, SHADER_PARAM_TYPE_COLOR, "", "" ) + SHADER_PARAM( FORCECHEAP, SHADER_PARAM_TYPE_BOOL, "", "" ) + SHADER_PARAM( FORCEEXPENSIVE, SHADER_PARAM_TYPE_BOOL, "", "" ) + SHADER_PARAM( REFLECTENTITIES, SHADER_PARAM_TYPE_BOOL, "", "" ) + SHADER_PARAM( FOGSTART, SHADER_PARAM_TYPE_FLOAT, "", "" ) + SHADER_PARAM( FOGEND, SHADER_PARAM_TYPE_FLOAT, "", "" ) + SHADER_PARAM( ABOVEWATER, SHADER_PARAM_TYPE_BOOL, "", "" ) + SHADER_PARAM( REFLECTBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1.0", "" ) + SHADER_PARAM( NOFRESNEL, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( NOLOWENDLIGHTMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( SCROLL1, SHADER_PARAM_TYPE_COLOR, "", "" ) + SHADER_PARAM( SCROLL2, SHADER_PARAM_TYPE_COLOR, "", "" ) + SHADER_PARAM( BLURREFRACT, SHADER_PARAM_TYPE_BOOL, "0", "Cause the refraction to be blurry on ps2b hardware" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + if( !params[ABOVEWATER]->IsDefined() ) + { + Warning( "***need to set $abovewater for material %s\n", pMaterialName ); + params[ABOVEWATER]->SetIntValue( 1 ); + } + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + if( !params[CHEAPWATERSTARTDISTANCE]->IsDefined() ) + { + params[CHEAPWATERSTARTDISTANCE]->SetFloatValue( 500.0f ); + } + if( !params[CHEAPWATERENDDISTANCE]->IsDefined() ) + { + params[CHEAPWATERENDDISTANCE]->SetFloatValue( 1000.0f ); + } + if( !params[SCALE]->IsDefined() ) + { + params[SCALE]->SetVecValue( 1.0f, 1.0f ); + } + if( !params[SCROLL1]->IsDefined() ) + { + params[SCROLL1]->SetVecValue( 0.0f, 0.0f, 0.0f ); + } + if( !params[SCROLL2]->IsDefined() ) + { + params[SCROLL2]->SetVecValue( 0.0f, 0.0f, 0.0f ); + } + if( !params[FOGCOLOR]->IsDefined() ) + { + params[FOGCOLOR]->SetVecValue( 1.0f, 0.0f, 0.0f ); + Warning( "material %s needs to have a $fogcolor.\n", pMaterialName ); + } + if( !params[REFLECTENTITIES]->IsDefined() ) + { + params[REFLECTENTITIES]->SetIntValue( 0 ); + } + if( !params[REFLECTBLENDFACTOR]->IsDefined() ) + { + params[REFLECTBLENDFACTOR]->SetFloatValue( 1.0f ); + } + + // By default, we're force expensive on dx9. NO WE DON'T!!!! + if( !params[FORCEEXPENSIVE]->IsDefined() ) + { +#ifdef _X360 + params[FORCEEXPENSIVE]->SetIntValue( 0 ); +#else + params[FORCEEXPENSIVE]->SetIntValue( 1 ); +#endif + } + if( params[FORCEEXPENSIVE]->GetIntValue() && params[FORCECHEAP]->GetIntValue() ) + { + params[FORCEEXPENSIVE]->SetIntValue( 0 ); + } + + // Fallbacks for water need lightmaps usually + if ( !params[NOLOWENDLIGHTMAP]->GetIntValue() ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + if( g_pConfig->UseBumpmapping() && params[NORMALMAP]->IsDefined() ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ); + } + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "Water_DX81"; + } + return 0; + } + + SHADER_INIT + { + Assert( params[WATERDEPTH]->IsDefined() ); + + if( params[REFRACTTEXTURE]->IsDefined() ) + { + LoadTexture( REFRACTTEXTURE, TEXTUREFLAGS_SRGB ); + } + if( params[REFLECTTEXTURE]->IsDefined() ) + { + LoadTexture( REFLECTTEXTURE, TEXTUREFLAGS_SRGB ); + } + if ( params[ENVMAP]->IsDefined() ) + { + LoadCubeMap( ENVMAP, TEXTUREFLAGS_SRGB ); + } + if ( params[NORMALMAP]->IsDefined() ) + { + LoadBumpMap( NORMALMAP ); + } + if( params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); + } + } + + inline void GetVecParam( int constantVar, float *val ) + { + if( constantVar == -1 ) + return; + + IMaterialVar* pVar = s_ppParams[constantVar]; + Assert( pVar ); + + if (pVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pVar->GetVecValue( val, 4 ); + else + val[0] = val[1] = val[2] = val[3] = pVar->GetFloatValue(); + } + + inline void DrawReflectionRefraction( IMaterialVar **params, IShaderShadow* pShaderShadow, + IShaderDynamicAPI* pShaderAPI, bool bReflection, bool bRefraction ) + { + SHADOW_STATE + { + SetInitialShadowState( ); + if( bRefraction ) + { + // refract sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + } + if( bReflection ) + { + // reflect sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); + if( params[BASETEXTURE]->IsTexture() ) + { + // BASETEXTURE + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + // LIGHTMAP + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, true ); + } + } + // normal map + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + // Normalizing cube map + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + + int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T; + + // texcoord0 : base texcoord + // texcoord1 : lightmap texcoord + // texcoord2 : lightmap texcoord offset + int numTexCoords = 1; + if( params[BASETEXTURE]->IsTexture() ) + { + numTexCoords = 3; + } + pShaderShadow->VertexShaderVertexFormat( fmt, numTexCoords, 0, 0 ); + + Vector4D Scroll1; + params[SCROLL1]->GetVecValue( Scroll1.Base(), 4 ); + + NormalDecodeMode_t nNormalDecodeMode = NORMAL_DECODE_NONE; + if ( params[NORMALMAP]->IsTexture() && g_pHardwareConfig->SupportsNormalMapCompression() ) + { + ITexture *pNormalMap = params[NORMALMAP]->GetTextureValue(); + if ( pNormalMap ) + { + // Clamp this to 0 or 1 since that's how we've authored the water shader (i.e. no separate alpha map/channel) + nNormalDecodeMode = pNormalMap->GetNormalDecodeMode() == NORMAL_DECODE_NONE ? NORMAL_DECODE_NONE : NORMAL_DECODE_ATI2N; + } + } + + DECLARE_STATIC_VERTEX_SHADER( water_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); + SET_STATIC_VERTEX_SHADER_COMBO( BASETEXTURE, params[BASETEXTURE]->IsTexture() ); + SET_STATIC_VERTEX_SHADER( water_vs20 ); + + // "REFLECT" "0..1" + // "REFRACT" "0..1" + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( water_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( REFLECT, bReflection ); + SET_STATIC_PIXEL_SHADER_COMBO( REFRACT, bRefraction ); + SET_STATIC_PIXEL_SHADER_COMBO( ABOVEWATER, params[ABOVEWATER]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE, params[BASETEXTURE]->IsTexture() ); + SET_STATIC_PIXEL_SHADER_COMBO( BLURRY_REFRACT, params[BLURREFRACT]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); + SET_STATIC_PIXEL_SHADER( water_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( water_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( REFLECT, bReflection ); + SET_STATIC_PIXEL_SHADER_COMBO( REFRACT, bRefraction ); + SET_STATIC_PIXEL_SHADER_COMBO( ABOVEWATER, params[ABOVEWATER]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE, params[BASETEXTURE]->IsTexture() ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); + SET_STATIC_PIXEL_SHADER( water_ps20 ); + } + + FogToFogColor(); + + // we are writing linear values from this shader. + pShaderShadow->EnableSRGBWrite( true ); + + pShaderShadow->EnableAlphaWrites( true ); + } + DYNAMIC_STATE + { + pShaderAPI->SetDefaultState(); + if( bRefraction ) + { + // HDRFIXME: add comment about binding.. Specify the number of MRTs in the enable + BindTexture( SHADER_SAMPLER0, REFRACTTEXTURE, -1 ); + } + if( bReflection ) + { + BindTexture( SHADER_SAMPLER2, REFLECTTEXTURE, -1 ); + } + BindTexture( SHADER_SAMPLER4, NORMALMAP, BUMPFRAME ); + if( params[BASETEXTURE]->IsTexture() ) + { + BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_LIGHTMAP ); + } + + pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); + + // Refraction tint + if( bRefraction ) + { + SetPixelShaderConstantGammaToLinear( 1, REFRACTTINT ); + } + // Reflection tint + if( bReflection ) + { + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER ) + { + // Need to multiply by 4 in linear space since we premultiplied into + // the render target by .25 to get overbright data in the reflection render target. + float gammaReflectTint[3]; + params[REFLECTTINT]->GetVecValue( gammaReflectTint, 3 ); + float linearReflectTint[4]; + linearReflectTint[0] = GammaToLinear( gammaReflectTint[0] ) * 4.0f; + linearReflectTint[1] = GammaToLinear( gammaReflectTint[1] ) * 4.0f; + linearReflectTint[2] = GammaToLinear( gammaReflectTint[2] ) * 4.0f; + linearReflectTint[3] = 1.0f; + pShaderAPI->SetPixelShaderConstant( 4, linearReflectTint, 1 ); + } + else + { + SetPixelShaderConstantGammaToLinear( 4, REFLECTTINT ); + } + } + + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); + + float curtime=pShaderAPI->CurrentTime(); + float vc0[4]; + float v0[4]; + params[SCROLL1]->GetVecValue(v0,4); + vc0[0]=curtime*v0[0]; + vc0[1]=curtime*v0[1]; + params[SCROLL2]->GetVecValue(v0,4); + vc0[2]=curtime*v0[0]; + vc0[3]=curtime*v0[1]; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vc0, 1 ); + + float c0[4] = { 1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f, 0.0f }; + pShaderAPI->SetPixelShaderConstant( 0, c0, 1 ); + + float c2[4] = { 0.5f, 0.5f, 0.5f, 0.5f }; + pShaderAPI->SetPixelShaderConstant( 2, c2, 1 ); + + // fresnel constants + float c3[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; + pShaderAPI->SetPixelShaderConstant( 3, c3, 1 ); + + float c5[4] = { params[REFLECTAMOUNT]->GetFloatValue(), params[REFLECTAMOUNT]->GetFloatValue(), + params[REFRACTAMOUNT]->GetFloatValue(), params[REFRACTAMOUNT]->GetFloatValue() }; + pShaderAPI->SetPixelShaderConstant( 5, c5, 1 ); + + SetPixelShaderConstantGammaToLinear( 6, FOGCOLOR ); + + float c7[4] = + { + params[FOGSTART]->GetFloatValue(), + params[FOGEND]->GetFloatValue() - params[FOGSTART]->GetFloatValue(), + 1.0f, + 0.0f + }; + if (g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER ) + { + // water overbright factor + c7[2] = 4.0; + } + pShaderAPI->SetPixelShaderConstant( 7, c7, 1 ); + + pShaderAPI->SetPixelShaderFogParams( 8 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( water_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( water_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( water_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( water_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( water_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( water_ps20 ); + } + } + Draw(); + } + + inline void DrawCheapWater( IMaterialVar **params, IShaderShadow* pShaderShadow, + IShaderDynamicAPI* pShaderAPI, bool bBlend, bool bRefraction ) + { + SHADOW_STATE + { + SetInitialShadowState( ); + + // In edit mode, use nocull + if ( UsingEditor( params ) ) + { + s_pShaderShadow->EnableCulling( false ); + } + + if( bBlend ) + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + // envmap + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + // normal map + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + if( bRefraction && bBlend ) + { + // refraction map (used for alpha) + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + } + // Normalizing cube map + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); + int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + NormalDecodeMode_t nNormalDecodeMode = NORMAL_DECODE_NONE; + if ( params[NORMALMAP]->IsTexture() && g_pHardwareConfig->SupportsNormalMapCompression() ) + { + ITexture *pNormalMap = params[NORMALMAP]->GetTextureValue(); + if ( pNormalMap ) + { + // Clamp this to 0 or 1 since that's how we've authored the water shader (i.e. no separate alpha map/channel) + nNormalDecodeMode = pNormalMap->GetNormalDecodeMode() == NORMAL_DECODE_NONE ? NORMAL_DECODE_NONE : NORMAL_DECODE_ATI2N; + } + } + + DECLARE_STATIC_VERTEX_SHADER( watercheap_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( BLEND, bBlend && bRefraction ); + SET_STATIC_VERTEX_SHADER( watercheap_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( watercheap_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( FRESNEL, params[NOFRESNEL]->GetIntValue() == 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( BLEND, bBlend ); + SET_STATIC_PIXEL_SHADER_COMBO( REFRACTALPHA, bRefraction ); + SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() ); + Vector4D Scroll1; + params[SCROLL1]->GetVecValue( Scroll1.Base(), 4 ); + SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); + SET_STATIC_PIXEL_SHADER( watercheap_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( watercheap_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( FRESNEL, params[NOFRESNEL]->GetIntValue() == 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( BLEND, bBlend ); + SET_STATIC_PIXEL_SHADER_COMBO( REFRACTALPHA, bRefraction ); + SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() ); + Vector4D Scroll1; + params[SCROLL1]->GetVecValue( Scroll1.Base(), 4 ); + SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); + SET_STATIC_PIXEL_SHADER( watercheap_ps20 ); + } + + // HDRFIXME: test cheap water! + if( g_pHardwareConfig->GetHDRType() != HDR_TYPE_NONE ) + { + // we are writing linear values from this shader. + pShaderShadow->EnableSRGBWrite( true ); + } + + FogToFogColor(); + } + DYNAMIC_STATE + { + pShaderAPI->SetDefaultState(); + + BindTexture( SHADER_SAMPLER0, ENVMAP, ENVMAPFRAME ); + BindTexture( SHADER_SAMPLER1, NORMALMAP, BUMPFRAME ); + if( bRefraction && bBlend ) + { + BindTexture( SHADER_SAMPLER2, REFRACTTEXTURE, -1 ); + } + pShaderAPI->BindStandardTexture( SHADER_SAMPLER6, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); + + SetPixelShaderConstant( 0, FOGCOLOR ); + + float cheapWaterStartDistance = params[CHEAPWATERSTARTDISTANCE]->GetFloatValue(); + float cheapWaterEndDistance = params[CHEAPWATERENDDISTANCE]->GetFloatValue(); + float cheapWaterParams[4] = + { + cheapWaterStartDistance * VSHADER_VECT_SCALE, + cheapWaterEndDistance * VSHADER_VECT_SCALE, + PSHADER_VECT_SCALE / ( cheapWaterEndDistance - cheapWaterStartDistance ), + cheapWaterStartDistance / ( cheapWaterEndDistance - cheapWaterStartDistance ), + }; + pShaderAPI->SetPixelShaderConstant( 1, cheapWaterParams ); + + if( g_pConfig->bShowSpecular ) + { + SetPixelShaderConstant( 2, REFLECTTINT, REFLECTBLENDFACTOR ); + } + else + { + float zero[4] = { 0.0f, 0.0f, 0.0f, params[REFLECTBLENDFACTOR]->GetFloatValue() }; + pShaderAPI->SetPixelShaderConstant( 2, zero ); + } + + pShaderAPI->SetPixelShaderFogParams( 3 ); + + if( params[SCROLL1]->IsDefined()) + { + float curtime=pShaderAPI->CurrentTime(); + float vc0[4]; + float v0[4]; + params[SCROLL1]->GetVecValue(v0,4); + vc0[0]=curtime*v0[0]; + vc0[1]=curtime*v0[1]; + params[SCROLL2]->GetVecValue(v0,4); + vc0[2]=curtime*v0[0]; + vc0[3]=curtime*v0[1]; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vc0, 1 ); + } + + DECLARE_DYNAMIC_VERTEX_SHADER( watercheap_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( watercheap_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( watercheap_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( watercheap_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( watercheap_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( watercheap_ps20 ); + } + } + Draw(); + } + + SHADER_DRAW + { + // TODO: fit the cheap water stuff into the water shader so that we don't have to do + // 2 passes. +#ifdef _X360 + bool bForceExpensive = false; +#else + bool bForceExpensive = r_waterforceexpensive.GetBool(); +#endif + bool bForceCheap = (params[FORCECHEAP]->GetIntValue() != 0) || UsingEditor( params ); + if ( bForceCheap ) + { + bForceExpensive = false; + } + else + { + bForceExpensive = bForceExpensive || (params[FORCEEXPENSIVE]->GetIntValue() != 0); + } + Assert( !( bForceCheap && bForceExpensive ) ); + + bool bRefraction = params[REFRACTTEXTURE]->IsTexture(); +#ifdef _X360 + bool bReflection = params[REFLECTTEXTURE]->IsTexture(); +#else + bool bReflection = bForceExpensive && params[REFLECTTEXTURE]->IsTexture(); +#endif + bool bDrewSomething = false; + if ( !bForceCheap && ( bReflection || bRefraction ) ) + { + bDrewSomething = true; + DrawReflectionRefraction( params, pShaderShadow, pShaderAPI, bReflection, bRefraction ); + } + + // Use $decal to see if we are a decal or not. . if we are, then don't bother + // drawing the cheap version for now since we don't have access to env_cubemap +#ifdef _X360 + if( params[ENVMAP]->IsTexture() && !IS_FLAG_SET( MATERIAL_VAR_DECAL ) && !bForceExpensive ) +#else + if( !bReflection && params[ENVMAP]->IsTexture() && !IS_FLAG_SET( MATERIAL_VAR_DECAL ) ) +#endif + { + bDrewSomething = true; + DrawCheapWater( params, pShaderShadow, pShaderAPI, !bForceCheap, bRefraction ); + } + + if( !bDrewSomething ) + { + // We are likely here because of the tools. . . draw something so that + // we won't go into wireframe-land. + Draw(); + } + } +END_SHADER + +//----------------------------------------------------------------------------- +// This allows us to use a block labelled 'Water_DX9_HDR' in the water materials +//----------------------------------------------------------------------------- +BEGIN_INHERITED_SHADER( Water_DX9_HDR, Water_DX90, + "Help for Water_DX9_HDR" ) + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + return "WATER_DX90"; + } + return 0; + } +END_INHERITED_SHADER + |