Joe Ludwig 7309a5f13f 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.
2013-12-23 15:00:03 -08:00

978 lines
38 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//===========================================================================//
#include "BaseVSShader.h"
#include "skin_dx9_helper.h"
#include "convar.h"
#include "cpp_shader_constant_register_map.h"
#include "skin_vs20.inc"
#include "skin_ps20b.inc"
#include "commandbuilder.h"
#ifndef _X360
#include "skin_vs30.inc"
#include "skin_ps30.inc"
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
static ConVar mat_fullbright( "mat_fullbright", "0", FCVAR_CHEAT );
static ConVar r_lightwarpidentity( "r_lightwarpidentity", "0", FCVAR_CHEAT );
static ConVar r_rimlight( "r_rimlight", "1", FCVAR_CHEAT );
// Textures may be bound to the following samplers:
// SHADER_SAMPLER0 Base (Albedo) / Gloss in alpha
// SHADER_SAMPLER1 Specular warp (including iridescence)
// SHADER_SAMPLER2 Diffuse Lighting warp texture
// SHADER_SAMPLER3 Normal Map
// SHADER_SAMPLER4 Flashlight Shadow Depth Map
// SHADER_SAMPLER5 Normalization cube map
// SHADER_SAMPLER6 Flashlight Cookie
// SHADER_SAMPLER7 Specular exponent
// SHADER_SAMPLER8 Cubic environment map
// SHADER_SAMPLER9 Compressed wrinklemap
// SHADER_SAMPLER10 Stretched wrinklemap
// SHADER_SAMPLER11 Compressed wrinkle normal map
// SHADER_SAMPLER12 Stretched wrinkle normal map
// SHADER_SAMPLER13 Detail texture
//-----------------------------------------------------------------------------
// Initialize shader parameters
//-----------------------------------------------------------------------------
void InitParamsSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, VertexLitGeneric_DX9_Vars_t &info )
{
// FLASHLIGHTFIXME: Do ShaderAPI::BindFlashlightTexture
Assert( info.m_nFlashlightTexture >= 0 );
if ( g_pHardwareConfig->SupportsBorderColor() )
{
params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" );
}
else
{
params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" );
}
// Write over $basetexture with $info.m_nBumpmap if we are going to be using diffuse normal mapping.
if( info.m_nAlbedo != -1 && g_pConfig->UseBumpmapping() && info.m_nBumpmap != -1 && params[info.m_nBumpmap]->IsDefined() && params[info.m_nAlbedo]->IsDefined() &&
params[info.m_nBaseTexture]->IsDefined() )
{
params[info.m_nBaseTexture]->SetStringValue( params[info.m_nAlbedo]->GetStringValue() );
}
// This shader can be used with hw skinning
SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING );
SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT );
// No texture means no env mask in base alpha
if ( !params[info.m_nBaseTexture]->IsDefined() )
{
CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK );
}
// If in decal mode, no debug override...
if (IS_FLAG_SET(MATERIAL_VAR_DECAL))
{
SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE );
}
// Lots of reasons to want tangent space, since we bind a flat normal map in many cases where we don't have a bump map
bool bBump = (info.m_nBumpmap != -1) && g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined();
bool bEnvMap = (info.m_nEnvmap != -1) && params[info.m_nEnvmap]->IsDefined();
bool bDiffuseWarp = (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined();
bool bPhong = (info.m_nPhong != -1) && params[info.m_nPhong]->IsDefined();
if( bBump || bEnvMap || bDiffuseWarp || bPhong )
{
SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES );
}
else
{
CLEAR_FLAGS( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK );
}
if ( ( info.m_nSelfIllumFresnel != -1 ) && ( !params[info.m_nSelfIllumFresnel]->IsDefined() ) )
{
params[info.m_nSelfIllumFresnel]->SetIntValue( 0 );
}
if ( ( info.m_nSelfIllumFresnelMinMaxExp != -1 ) && ( !params[info.m_nSelfIllumFresnelMinMaxExp]->IsDefined() ) )
{
params[info.m_nSelfIllumFresnelMinMaxExp]->SetVecValue( 0.0f, 1.0f, 1.0f );
}
if ( ( info.m_nBaseMapAlphaPhongMask != -1 ) && ( !params[info.m_nBaseMapAlphaPhongMask]->IsDefined() ) )
{
params[info.m_nBaseMapAlphaPhongMask]->SetIntValue( 0 );
}
if ( ( info.m_nEnvmapFresnel != -1 ) && ( !params[info.m_nEnvmapFresnel]->IsDefined() ) )
{
params[info.m_nEnvmapFresnel]->SetFloatValue( 0 );
}
}
//-----------------------------------------------------------------------------
// Initialize shader
//-----------------------------------------------------------------------------
void InitSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, VertexLitGeneric_DX9_Vars_t &info )
{
Assert( info.m_nFlashlightTexture >= 0 );
pShader->LoadTexture( info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB );
bool bIsBaseTextureTranslucent = false;
if ( params[info.m_nBaseTexture]->IsDefined() )
{
pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB );
if ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() )
{
bIsBaseTextureTranslucent = true;
}
if ( ( info.m_nWrinkle != -1 ) && ( info.m_nStretch != -1 ) &&
params[info.m_nWrinkle]->IsDefined() && params[info.m_nStretch]->IsDefined() )
{
pShader->LoadTexture( info.m_nWrinkle, TEXTUREFLAGS_SRGB );
pShader->LoadTexture( info.m_nStretch, TEXTUREFLAGS_SRGB );
}
}
bool bHasSelfIllumMask = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && (info.m_nSelfIllumMask != -1) && params[info.m_nSelfIllumMask]->IsDefined();
// No alpha channel in any of the textures? No self illum or envmapmask
if ( !bIsBaseTextureTranslucent )
{
bool bHasSelfIllumFresnel = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 );
// Can still be self illum with no base alpha if using one of these alternate modes
if ( !bHasSelfIllumFresnel && !bHasSelfIllumMask )
{
CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM );
}
CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK );
}
if ( (info.m_nPhongExponentTexture != -1) && params[info.m_nPhongExponentTexture]->IsDefined() &&
(info.m_nPhong != -1) && params[info.m_nPhong]->IsDefined() )
{
pShader->LoadTexture( info.m_nPhongExponentTexture );
}
if ( (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined() &&
(info.m_nPhong != -1) && params[info.m_nPhong]->IsDefined() )
{
pShader->LoadTexture( info.m_nDiffuseWarpTexture );
}
if ( (info.m_nPhongWarpTexture != -1) && params[info.m_nPhongWarpTexture]->IsDefined() &&
(info.m_nPhong != -1) && params[info.m_nPhong]->IsDefined() )
{
pShader->LoadTexture( info.m_nPhongWarpTexture );
}
if ( info.m_nDetail != -1 && params[info.m_nDetail]->IsDefined() )
{
int nDetailBlendMode = ( info.m_nDetailTextureCombineMode == -1 ) ? 0 : params[info.m_nDetailTextureCombineMode]->GetIntValue();
if ( nDetailBlendMode == 0 ) // Mod2X
pShader->LoadTexture( info.m_nDetail );
else
pShader->LoadTexture( info.m_nDetail, TEXTUREFLAGS_SRGB );
}
if ( g_pConfig->UseBumpmapping() )
{
if ( (info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsDefined() )
{
pShader->LoadBumpMap( info.m_nBumpmap );
SET_FLAGS2( MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL );
if ( ( info.m_nNormalWrinkle != -1 ) && ( info.m_nNormalStretch != -1 ) &&
params[info.m_nNormalWrinkle]->IsDefined() && params[info.m_nNormalStretch]->IsDefined() )
{
pShader->LoadTexture( info.m_nNormalWrinkle );
pShader->LoadTexture( info.m_nNormalStretch );
}
}
}
if ( params[info.m_nEnvmap]->IsDefined() )
{
pShader->LoadCubeMap( info.m_nEnvmap, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0 );
}
if ( bHasSelfIllumMask )
{
pShader->LoadTexture( info.m_nSelfIllumMask );
}
}
class CSkin_DX9_Context : public CBasePerMaterialContextData
{
public:
CCommandBufferBuilder< CFixedCommandStorageBuffer< 800 > > m_SemiStaticCmdsOut;
bool m_bFastPath;
};
//-----------------------------------------------------------------------------
// Draws the shader
//-----------------------------------------------------------------------------
void DrawSkin_DX9_Internal( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow,
bool bHasFlashlight, VertexLitGeneric_DX9_Vars_t &info, VertexCompressionType_t vertexCompression,
CBasePerMaterialContextData **pContextDataPtr )
{
bool bHasBaseTexture = (info.m_nBaseTexture != -1) && params[info.m_nBaseTexture]->IsTexture();
bool bHasBump = (info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsTexture();
bool bHasBaseTextureWrinkle = bHasBaseTexture &&
(info.m_nWrinkle != -1) && params[info.m_nWrinkle]->IsTexture() &&
(info.m_nStretch != -1) && params[info.m_nStretch]->IsTexture();
bool bHasBumpWrinkle = bHasBump &&
(info.m_nNormalWrinkle != -1) && params[info.m_nNormalWrinkle]->IsTexture() &&
(info.m_nNormalStretch != -1) && params[info.m_nNormalStretch]->IsTexture();
bool bHasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR );
bool bHasVertexAlpha = IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA );
bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0;
bool bHasSelfIllum = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) != 0;
bool bHasSelfIllumFresnel = ( bHasSelfIllum ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 );
bool bHasSelfIllumMask = ( bHasSelfIllum ) && (info.m_nSelfIllumMask != -1) && params[info.m_nSelfIllumMask]->IsTexture();
// Tie these to specular
bool bHasPhong = (info.m_nPhong != -1) && ( params[info.m_nPhong]->GetIntValue() != 0 );
bool bHasSpecularExponentTexture = (info.m_nPhongExponentTexture != -1) && params[info.m_nPhongExponentTexture]->IsTexture();
bool bHasPhongTintMap = bHasSpecularExponentTexture && (info.m_nPhongAlbedoTint != -1) && ( params[info.m_nPhongAlbedoTint]->GetIntValue() != 0 );
bool bHasDiffuseWarp = (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsTexture();
bool bHasPhongWarp = (info.m_nPhongWarpTexture != -1) && params[info.m_nPhongWarpTexture]->IsTexture();
bool bHasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK );
#if !defined( _X360 )
bool bIsDecal = IS_FLAG_SET( MATERIAL_VAR_DECAL );
#endif
// Rimlight must be set to non-zero to trigger rim light combo (also requires Phong)
bool bHasRimLight = r_rimlight.GetBool() && bHasPhong && (info.m_nRimLight != -1) && ( params[info.m_nRimLight]->GetIntValue() != 0 );
bool bHasRimMaskMap = bHasSpecularExponentTexture && bHasRimLight && (info.m_nRimMask != -1) && ( params[info.m_nRimMask]->GetIntValue() != 0 );
float fBlendFactor=( info.m_nDetailTextureBlendFactor == -1 )? 1 : params[info.m_nDetailTextureBlendFactor]->GetFloatValue();
bool hasDetailTexture = ( info.m_nDetail != -1 ) && params[info.m_nDetail]->IsTexture();
int nDetailBlendMode = ( hasDetailTexture && info.m_nDetailTextureCombineMode != -1 ) ? params[info.m_nDetailTextureCombineMode]->GetIntValue() : 0;
bool bBlendTintByBaseAlpha = IsBoolSet( info.m_nBlendTintByBaseAlpha, params ) && !bHasSelfIllum; // Pixel shader can't do both BLENDTINTBYBASEALPHA and SELFILLUM, so let selfillum win
float flTintReplacementAmount = GetFloatParam( info.m_nTintReplacesBaseColor, params );
BlendType_t nBlendType= pShader->EvaluateBlendRequirements( bBlendTintByBaseAlpha ? -1 : info.m_nBaseTexture, true );
bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !bIsAlphaTested && !bHasFlashlight; //dest alpha is free for special use
CSkin_DX9_Context *pContextData = reinterpret_cast< CSkin_DX9_Context *> ( *pContextDataPtr );
if ( ! pContextData )
{
pContextData = new CSkin_DX9_Context;
*pContextDataPtr = pContextData;
}
if( pShader->IsSnapshotting() )
{
// look at color and alphamod stuff.
// Unlit generic never uses the flashlight
bool bHasEnvmap = !bHasFlashlight && params[info.m_nEnvmap]->IsTexture();
bool bHasNormal = params[info.m_nBumpmap]->IsTexture();
bool bCanUseBaseAlphaPhongMaskFastPath = (info.m_nBaseMapAlphaPhongMask != -1) && ( params[info.m_nBaseMapAlphaPhongMask]->GetIntValue() != 0 );
if ( ! ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) )
bCanUseBaseAlphaPhongMaskFastPath = true;
pContextData->m_bFastPath =
(! bHasBump ) &&
(! bHasSpecularExponentTexture ) &&
(! bHasPhongTintMap ) &&
(! bHasPhongWarp ) &&
(! bHasRimLight ) &&
(! hasDetailTexture ) &&
bCanUseBaseAlphaPhongMaskFastPath &&
(! bHasSelfIllum ) &&
(! bBlendTintByBaseAlpha );
// Alpha test: FIXME: shouldn't this be handled in CBaseVSShader::SetInitialShadowState
pShaderShadow->EnableAlphaTest( bIsAlphaTested );
if( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f )
{
pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() );
}
int nShadowFilterMode = 0;
if( bHasFlashlight )
{
if (params[info.m_nBaseTexture]->IsTexture())
{
pShader->SetAdditiveBlendingShadowState( info.m_nBaseTexture, true );
}
if( bIsAlphaTested )
{
// disable alpha test and use the zfunc zequals since alpha isn't guaranteed to
// be the same on both the regular pass and the flashlight pass.
pShaderShadow->EnableAlphaTest( false );
pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL );
}
pShaderShadow->EnableBlending( true );
pShaderShadow->EnableDepthWrites( false );
// Be sure not to write to dest alpha
pShaderShadow->EnableAlphaWrites( false );
nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats
}
else // not flashlight pass
{
if (params[info.m_nBaseTexture]->IsTexture())
{
pShader->SetDefaultBlendingShadowState( info.m_nBaseTexture, true );
}
if ( bHasEnvmap )
{
pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // Cubic environment map
if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE )
{
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER8, true );
}
}
}
unsigned int flags = VERTEX_POSITION;
if( bHasNormal )
{
flags |= VERTEX_NORMAL;
}
int userDataSize = 0;
// Always enable...will bind white if nothing specified...
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base (albedo) map
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true );
if ( bHasBaseTextureWrinkle || bHasBumpWrinkle )
{
pShaderShadow->EnableTexture( SHADER_SAMPLER9, true ); // Base (albedo) compression map
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER9, true );
pShaderShadow->EnableTexture( SHADER_SAMPLER10, true ); // Base (albedo) expansion map
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER10, true );
}
if( bHasDiffuseWarp )
{
pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // Diffuse warp texture
}
if( bHasPhongWarp )
{
pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Specular warp texture
}
// Specular exponent map or dummy
pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Specular exponent map
if( bHasFlashlight )
{
pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); // Shadow depth map
pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER4 );
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, false );
pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Noise map
pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Flashlight cookie
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, true );
userDataSize = 4; // tangent S
}
// Always enable, since flat normal will be bound
pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Normal map
userDataSize = 4; // tangent S
pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Normalizing cube map
if ( bHasBaseTextureWrinkle || bHasBumpWrinkle )
{
pShaderShadow->EnableTexture( SHADER_SAMPLER11, true ); // Normal compression map
pShaderShadow->EnableTexture( SHADER_SAMPLER12, true ); // Normal expansion map
}
if ( hasDetailTexture )
{
pShaderShadow->EnableTexture( SHADER_SAMPLER13, true );
if ( nDetailBlendMode != 0 ) //Not Mod2X
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER13, true );
}
if ( bHasSelfIllum )
{
pShaderShadow->EnableTexture( SHADER_SAMPLER14, true );
}
if( bHasVertexColor || bHasVertexAlpha )
{
flags |= VERTEX_COLOR;
}
pShaderShadow->EnableSRGBWrite( true );
// texcoord0 : base texcoord, texcoord2 : decal hw morph delta
int pTexCoordDim[3] = { 2, 0, 3 };
int nTexCoordCount = 1;
#ifndef _X360
// Special morphed decal information
if ( bIsDecal && g_pHardwareConfig->HasFastVertexTextures() )
{
nTexCoordCount = 3;
}
#endif
// This shader supports compressed vertices, so OR in that flag:
flags |= VERTEX_FORMAT_COMPRESSED;
pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, pTexCoordDim, userDataSize );
#ifndef _X360
if ( !g_pHardwareConfig->HasFastVertexTextures() )
#endif
{
bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow();
DECLARE_STATIC_VERTEX_SHADER( skin_vs20 );
SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow );
SET_STATIC_VERTEX_SHADER( skin_vs20 );
// Assume we're only going to get in here if we support 2b
DECLARE_STATIC_PIXEL_SHADER( skin_ps20b );
SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight );
SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum && !bHasFlashlight );
SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel && !bHasFlashlight );
SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && bHasPhong );
SET_STATIC_PIXEL_SHADER_COMBO( PHONGWARPTEXTURE, bHasPhongWarp && bHasPhong );
SET_STATIC_PIXEL_SHADER_COMBO( WRINKLEMAP, bHasBaseTextureWrinkle || bHasBumpWrinkle );
SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture );
SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode );
SET_STATIC_PIXEL_SHADER_COMBO( RIMLIGHT, bHasRimLight );
SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap );
SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode );
SET_STATIC_PIXEL_SHADER_COMBO( CONVERT_TO_SRGB, 0 );
SET_STATIC_PIXEL_SHADER_COMBO( FASTPATH_NOBUMP, pContextData->m_bFastPath );
SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha );
SET_STATIC_PIXEL_SHADER( skin_ps20b );
}
#ifndef _X360
else
{
// The vertex shader uses the vertex id stream
SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID );
DECLARE_STATIC_VERTEX_SHADER( skin_vs30 );
SET_STATIC_VERTEX_SHADER_COMBO( DECAL, bIsDecal );
SET_STATIC_VERTEX_SHADER( skin_vs30 );
DECLARE_STATIC_PIXEL_SHADER( skin_ps30 );
SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight );
SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum && !bHasFlashlight );
SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel && !bHasFlashlight );
SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && bHasPhong );
SET_STATIC_PIXEL_SHADER_COMBO( PHONGWARPTEXTURE, bHasPhongWarp && bHasPhong );
SET_STATIC_PIXEL_SHADER_COMBO( WRINKLEMAP, bHasBaseTextureWrinkle || bHasBumpWrinkle );
SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture );
SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode );
SET_STATIC_PIXEL_SHADER_COMBO( RIMLIGHT, bHasRimLight );
SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap );
SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode );
SET_STATIC_PIXEL_SHADER_COMBO( CONVERT_TO_SRGB, 0 );
SET_STATIC_PIXEL_SHADER_COMBO( FASTPATH_NOBUMP, pContextData->m_bFastPath );
SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha );
SET_STATIC_PIXEL_SHADER( skin_ps30 );
}
#endif
if( bHasFlashlight )
{
pShader->FogToBlack();
}
else
{
pShader->DefaultFog();
}
// HACK HACK HACK - enable alpha writes all the time so that we have them for underwater stuff
pShaderShadow->EnableAlphaWrites( bFullyOpaque );
}
else // not snapshotting -- begin dynamic state
{
bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE );
bool bHasEnvmap = !bHasFlashlight && params[info.m_nEnvmap]->IsTexture();
if( bHasBaseTexture )
{
pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame );
}
else
{
pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE );
}
if ( bHasBaseTextureWrinkle )
{
pShader->BindTexture( SHADER_SAMPLER9, info.m_nWrinkle, info.m_nBaseTextureFrame );
pShader->BindTexture( SHADER_SAMPLER10, info.m_nStretch, info.m_nBaseTextureFrame );
}
else if ( bHasBumpWrinkle )
{
pShader->BindTexture( SHADER_SAMPLER9, info.m_nBaseTexture, info.m_nBaseTextureFrame );
pShader->BindTexture( SHADER_SAMPLER10, info.m_nBaseTexture, info.m_nBaseTextureFrame );
}
if( bHasDiffuseWarp && bHasPhong )
{
if ( r_lightwarpidentity.GetBool() )
{
pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_IDENTITY_LIGHTWARP );
}
else
{
pShader->BindTexture( SHADER_SAMPLER2, info.m_nDiffuseWarpTexture );
}
}
if( bHasPhongWarp )
{
pShader->BindTexture( SHADER_SAMPLER1, info.m_nPhongWarpTexture );
}
if( bHasSpecularExponentTexture && bHasPhong )
{
pShader->BindTexture( SHADER_SAMPLER7, info.m_nPhongExponentTexture );
}
else
{
pShaderAPI->BindStandardTexture( SHADER_SAMPLER7, TEXTURE_WHITE );
}
if( !g_pConfig->m_bFastNoBump )
{
if( bHasBump )
pShader->BindTexture( SHADER_SAMPLER3, info.m_nBumpmap, info.m_nBumpFrame );
else
pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT );
if ( bHasBumpWrinkle )
{
pShader->BindTexture( SHADER_SAMPLER11, info.m_nNormalWrinkle, info.m_nBumpFrame );
pShader->BindTexture( SHADER_SAMPLER12, info.m_nNormalStretch, info.m_nBumpFrame );
}
else if ( bHasBaseTextureWrinkle )
{
pShader->BindTexture( SHADER_SAMPLER11, info.m_nBumpmap, info.m_nBumpFrame );
pShader->BindTexture( SHADER_SAMPLER12, info.m_nBumpmap, info.m_nBumpFrame );
}
}
else
{
if( bHasBump )
{
pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT );
}
if ( bHasBaseTextureWrinkle || bHasBumpWrinkle )
{
pShaderAPI->BindStandardTexture( SHADER_SAMPLER11, TEXTURE_NORMALMAP_FLAT );
pShaderAPI->BindStandardTexture( SHADER_SAMPLER12, TEXTURE_NORMALMAP_FLAT );
}
}
if ( hasDetailTexture )
{
pShader->BindTexture( SHADER_SAMPLER13, info.m_nDetail, info.m_nDetailFrame );
}
if ( bHasSelfIllum )
{
if ( bHasSelfIllumMask ) // Separate texture for self illum?
{
pShader->BindTexture( SHADER_SAMPLER14, info.m_nSelfIllumMask ); // Bind it
}
else // else
{
pShaderAPI->BindStandardTexture( SHADER_SAMPLER14, TEXTURE_BLACK ); // Bind dummy
}
}
LightState_t lightState = { 0, false, false };
bool bFlashlightShadows = false;
if( bHasFlashlight )
{
Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 );
pShader->BindTexture( SHADER_SAMPLER6, info.m_nFlashlightTexture, info.m_nFlashlightTextureFrame );
VMatrix worldToTexture;
ITexture *pFlashlightDepthTexture;
FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture );
bFlashlightShadows = state.m_bEnableShadows && ( pFlashlightDepthTexture != NULL );
SetFlashLightColorFromState( state, pShaderAPI, PSREG_FLASHLIGHT_COLOR );
if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows )
{
pShader->BindTexture( SHADER_SAMPLER4, pFlashlightDepthTexture, 0 );
pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D );
}
}
else // no flashlight
{
if ( bHasEnvmap )
{
pShader->BindTexture( SHADER_SAMPLER8, info.m_nEnvmap, info.m_nEnvmapFrame );
}
pShaderAPI->GetDX9LightState( &lightState );
}
MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode();
int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0;
int numBones = pShaderAPI->GetCurrentNumBones();
// don't have an easy way to get this through to GLM, so just print it old school
//printf("\n-D- DrawSkin_DX9_Internal numBones is %d", numBones );
bool bWriteDepthToAlpha = false;
bool bWriteWaterFogToAlpha = false;
if( bFullyOpaque )
{
bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha();
bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z);
AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." );
}
#ifndef _X360
if ( !g_pHardwareConfig->HasFastVertexTextures() )
#endif
{
bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow();
DECLARE_DYNAMIC_VERTEX_SHADER( skin_vs20 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex );
SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0);
SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights );
SET_DYNAMIC_VERTEX_SHADER( skin_vs20 );
DECLARE_DYNAMIC_PIXEL_SHADER( skin_ps20b );
SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights );
SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha );
SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha );
SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows );
SET_DYNAMIC_PIXEL_SHADER( skin_ps20b );
}
#ifndef _X360
else
{
pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 );
DECLARE_DYNAMIC_VERTEX_SHADER( skin_vs30 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex );
SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0);
SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() );
SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
SET_DYNAMIC_VERTEX_SHADER( skin_vs30 );
DECLARE_DYNAMIC_PIXEL_SHADER( skin_ps30 );
SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights );
SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha );
SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha );
SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows );
SET_DYNAMIC_PIXEL_SHADER( skin_ps30 );
bool bUnusedTexCoords[3] = { false, false, !pShaderAPI->IsHWMorphingEnabled() || !bIsDecal };
pShaderAPI->MarkUnusedVertexFields( 0, 3, bUnusedTexCoords );
}
#endif
pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform );
if( bHasBump )
{
pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBumpTransform );
}
if ( hasDetailTexture )
{
if ( IS_PARAM_DEFINED( info.m_nDetailTextureTransform ) )
pShader->SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4,
info.m_nDetailTextureTransform,
info.m_nDetailScale );
else
pShader->SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4,
info.m_nBaseTextureTransform,
info.m_nDetailScale );
}
pShader->SetModulationPixelShaderDynamicState_LinearColorSpace( 1 );
pShader->SetPixelShaderConstant_W( PSREG_SELFILLUMTINT, info.m_nSelfIllumTint, fBlendFactor );
bool bInvertPhongMask = ( info.m_nInvertPhongMask != -1 ) && ( params[info.m_nInvertPhongMask]->GetIntValue() != 0 );
float fInvertPhongMask = bInvertPhongMask ? 1 : 0;
bool bHasBaseAlphaPhongMask = (info.m_nBaseMapAlphaPhongMask != -1) && ( params[info.m_nBaseMapAlphaPhongMask]->GetIntValue() != 0 );
float fHasBaseAlphaPhongMask = bHasBaseAlphaPhongMask ? 1 : 0;
// Controls for lerp-style paths through shader code
float vShaderControls[4] = { fHasBaseAlphaPhongMask, 0.0f/*unused*/, flTintReplacementAmount, fInvertPhongMask };
pShaderAPI->SetPixelShaderConstant( PSREG_CONSTANT_27, vShaderControls, 1 );
if ( hasDetailTexture )
{
#if 0 // needs constant change
if ( info.m_nDetailTint != -1 )
pShader->SetPixelShaderConstantGammaToLinear( 10, info.m_nDetailTint );
else
{
float boring_tint[4]={1,1,1,1};
pShaderAPI->SetPixelShaderConstant( 10, boring_tint, 1 );
}
#endif
}
if ( bHasSelfIllumFresnel && !bHasFlashlight )
{
float vConstScaleBiasExp[4] = { 1.0f, 0.0f, 1.0f, 0.0f };
float flMin = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[0] : 0.0f;
float flMax = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[1] : 1.0f;
float flExp = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[2] : 1.0f;
vConstScaleBiasExp[1] = ( flMax != 0.0f ) ? ( flMin / flMax ) : 0.0f; // Bias
vConstScaleBiasExp[0] = 1.0f - vConstScaleBiasExp[1]; // Scale
vConstScaleBiasExp[2] = flExp; // Exp
vConstScaleBiasExp[3] = flMax; // Brightness
pShaderAPI->SetPixelShaderConstant( PSREG_SELFILLUM_SCALE_BIAS_EXP, vConstScaleBiasExp, 1 );
}
pShader->SetAmbientCubeDynamicStateVertexShader();
if( !bHasFlashlight )
{
pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED );
// Setting .x to 1 means to apply Fresnel to env map. Setting w to 1 means use separate selfillummask
float vEnvMapFresnel_SelfIllumMask[4] = {0.0f, 0.0f, 0.0f, 0.0f};
vEnvMapFresnel_SelfIllumMask[3] = bHasSelfIllumMask ? 1.0f : 0.0f;
if( bHasEnvmap )
{
float vEnvMapTint_MaskControl[4] = {1.0f, 1.0f, 1.0f, 0.0f};
// If we have a tint, grab it
if ( (info.m_nEnvmapTint != -1) && params[info.m_nEnvmapTint]->IsDefined() )
params[info.m_nEnvmapTint]->GetVecValue(vEnvMapTint_MaskControl, 3);
// Set control for source of env map mask (normal alpha or base alpha)
vEnvMapTint_MaskControl[3] = bHasNormalMapAlphaEnvmapMask ? 1.0f : 0.0f;
if ( (info.m_nEnvmapFresnel != -1) && params[info.m_nEnvmapFresnel]->IsDefined() )
vEnvMapFresnel_SelfIllumMask[0] = params[info.m_nEnvmapFresnel]->GetFloatValue();
// Handle mat_fullbright 2 (diffuse lighting only with 50% gamma space basetexture)
if( bLightingOnly )
{
vEnvMapTint_MaskControl[0] = vEnvMapTint_MaskControl[1] = vEnvMapTint_MaskControl[2] = 0.0f;
}
pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, vEnvMapTint_MaskControl, 1 );
}
pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_FRESNEL__SELFILLUMMASK, vEnvMapFresnel_SelfIllumMask, 1 );
}
pShaderAPI->SetPixelShaderStateAmbientLightCube( PSREG_AMBIENT_CUBE, !lightState.m_bAmbientLight ); // Force to black if not bAmbientLight
pShaderAPI->CommitPixelShaderLighting( PSREG_LIGHT_INFO_ARRAY );
// Pack Phong exponent in with the eye position
float vEyePos_SpecExponent[4], vFresnelRanges_SpecBoost[4] = {1, 0.5, 1, 1}, vRimBoost[4] = {1, 1, 1, 1};
float vSpecularTint[4] = {1, 1, 1, 4};
pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent );
// Use the alpha channel of the normal map for the exponent by default
vEyePos_SpecExponent[3] = -1.f;
if ( (info.m_nPhongExponent != -1) && params[info.m_nPhongExponent]->IsDefined() )
{
float fValue = params[info.m_nPhongExponent]->GetFloatValue();
if ( fValue > 0.f )
{
// Nonzero value in material overrides map channel
vEyePos_SpecExponent[3] = fValue;
}
}
// Get the tint parameter
if ( (info.m_nPhongTint != -1) && params[info.m_nPhongTint]->IsDefined() )
{
params[info.m_nPhongTint]->GetVecValue(vSpecularTint, 3);
}
// Get the rim light power (goes in w of Phong tint)
if ( bHasRimLight && (info.m_nRimLightPower != -1) && params[info.m_nRimLightPower]->IsDefined() )
{
vSpecularTint[3] = params[info.m_nRimLightPower]->GetFloatValue();
vSpecularTint[3] = max(vSpecularTint[3], 1.0f); // Make sure this is at least 1
}
// Get the rim boost (goes in w of flashlight position)
if ( bHasRimLight && (info.m_nRimLightBoost != -1) && params[info.m_nRimLightBoost]->IsDefined() )
{
vRimBoost[3] = params[info.m_nRimLightBoost]->GetFloatValue();
}
if ( !bHasFlashlight )
{
float vRimMaskControl[4] = {0, 0, 0, 0}; // Only x is relevant in shader code
vRimMaskControl[0] = bHasRimMaskMap ? params[info.m_nRimMask]->GetFloatValue() : 0.0f;
// Rim mask...if this is true, use alpha channel of spec exponent texture to mask the rim term
pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, vRimMaskControl, 1 );
}
// If it's all zeros, there was no constant tint in the vmt
if ( (vSpecularTint[0] == 0.0f) && (vSpecularTint[1] == 0.0f) && (vSpecularTint[2] == 0.0f) )
{
if ( bHasPhongTintMap ) // If we have a map to use, tell the shader
{
vSpecularTint[0] = -1;
}
else // Otherwise, just tint with white
{
vSpecularTint[0] = 1.0f;
vSpecularTint[1] = 1.0f;
vSpecularTint[2] = 1.0f;
}
}
// handle mat_fullbright 2 (diffuse lighting only)
if( bLightingOnly )
{
// BASETEXTURE
if( bHasSelfIllum && !bHasFlashlight )
{
pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY_ALPHA_ZERO );
}
else
{
pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY );
}
// DETAILTEXTURE
if ( hasDetailTexture )
{
pShaderAPI->BindStandardTexture( SHADER_SAMPLER13, TEXTURE_GREY );
}
// turn off specularity
vSpecularTint[0] = vSpecularTint[1] = vSpecularTint[2] = 0.0f;
}
if ( (info.m_nPhongFresnelRanges != -1) && params[info.m_nPhongFresnelRanges]->IsDefined() )
{
params[info.m_nPhongFresnelRanges]->GetVecValue( vFresnelRanges_SpecBoost, 3 ); // Grab optional Fresnel range parameters
// Change fresnel range encoding from (min, mid, max) to ((mid-min)*2, mid, (max-mid)*2)
vFresnelRanges_SpecBoost[0] = (vFresnelRanges_SpecBoost[1] - vFresnelRanges_SpecBoost[0]) * 2;
vFresnelRanges_SpecBoost[2] = (vFresnelRanges_SpecBoost[2] - vFresnelRanges_SpecBoost[1]) * 2;
}
if ( (info.m_nPhongBoost != -1 ) && params[info.m_nPhongBoost]->IsDefined()) // Grab optional Phong boost param
vFresnelRanges_SpecBoost[3] = params[info.m_nPhongBoost]->GetFloatValue();
else
vFresnelRanges_SpecBoost[3] = 1.0f;
pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 );
pShaderAPI->SetPixelShaderConstant( PSREG_FRESNEL_SPEC_PARAMS, vFresnelRanges_SpecBoost, 1 );
pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, vRimBoost, 1 ); // Rim boost in w on non-flashlight pass
pShaderAPI->SetPixelShaderConstant( PSREG_SPEC_RIM_PARAMS, vSpecularTint, 1 );
pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS );
// flashlightfixme: put this in common code.
if( bHasFlashlight )
{
VMatrix worldToTexture;
float atten[4], pos[4], tweaks[4];
const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture );
SetFlashLightColorFromState( flashlightState, pShaderAPI, PSREG_FLASHLIGHT_COLOR );
pShader->BindTexture( SHADER_SAMPLER6, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame );
atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors
atten[1] = flashlightState.m_fLinearAtten;
atten[2] = flashlightState.m_fQuadraticAtten;
atten[3] = flashlightState.m_FarZ;
pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 );
pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin
pos[1] = flashlightState.m_vecLightOrigin[1];
pos[2] = flashlightState.m_vecLightOrigin[2];
pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1 ); // steps on rim boost
pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE, worldToTexture.Base(), 4 );
// Tweaks associated with a given flashlight
tweaks[0] = ShadowFilterFromState( flashlightState );
tweaks[1] = ShadowAttenFromState( flashlightState );
pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] );
pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 );
// Dimensions of screen, used for screen-space noise map sampling
float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0};
int nWidth, nHeight;
pShaderAPI->GetBackBufferDimensions( nWidth, nHeight );
vScreenScale[0] = (float) nWidth / 32.0f;
vScreenScale[1] = (float) nHeight / 32.0f;
pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 );
if ( IsX360() )
{
pShaderAPI->SetBooleanPixelShaderConstant( 0, &flashlightState.m_nShadowQuality, 1 );
}
}
}
pShader->Draw();
}
//-----------------------------------------------------------------------------
// Draws the shader
//-----------------------------------------------------------------------------
extern ConVar r_flashlight_version2;
void DrawSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow,
VertexLitGeneric_DX9_Vars_t &info, VertexCompressionType_t vertexCompression,
CBasePerMaterialContextData **pContextDataPtr )
{
bool bHasFlashlight = pShader->UsingFlashlight( params );
if ( bHasFlashlight && ( IsX360() || r_flashlight_version2.GetInt() ) )
{
DrawSkin_DX9_Internal( pShader, params, pShaderAPI,
pShaderShadow, false, info, vertexCompression, pContextDataPtr++ );
if ( pShaderShadow )
{
pShader->SetInitialShadowState( );
}
}
DrawSkin_DX9_Internal( pShader, params, pShaderAPI,
pShaderShadow, bHasFlashlight, info, vertexCompression, pContextDataPtr );
}