Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

412 lines
16 KiB

//===== Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
// This is what all vs/ps (dx8+) shaders inherit from.
//===========================================================================//
#ifndef BASEVSSHADER_H
#define BASEVSSHADER_H
#ifdef _WIN32
#pragma once
#endif
#include "cpp_shader_constant_register_map.h"
#include "shaderlib/cshader.h"
#include "shaderlib/BaseShader.h"
#include "shaderapifast.h"
#include "convar.h"
#include <renderparm.h>
// Texture combining modes for combining base and detail/basetexture2
// Matches what's in common_ps_fxc.h
#define DETAIL_BLEND_MODE_RGB_EQUALS_BASE_x_DETAILx2 0 // Original mode (Mod2x)
#define DETAIL_BLEND_MODE_RGB_ADDITIVE 1 // Base.rgb+detail.rgb*fblend
#define DETAIL_BLEND_MODE_DETAIL_OVER_BASE 2
#define DETAIL_BLEND_MODE_FADE 3 // Straight fade between base and detail.
#define DETAIL_BLEND_MODE_BASE_OVER_DETAIL 4 // Use base alpha for blend over detail
#define DETAIL_BLEND_MODE_RGB_ADDITIVE_SELFILLUM 5 // Add detail color post lighting
#define DETAIL_BLEND_MODE_RGB_ADDITIVE_SELFILLUM_THRESHOLD_FADE 6
#define DETAIL_BLEND_MODE_MOD2X_SELECT_TWO_PATTERNS 7 // Use alpha channel of base to select between mod2x channels in r+a of detail
#define DETAIL_BLEND_MODE_MULTIPLY 8
#define DETAIL_BLEND_MODE_MASK_BASE_BY_DETAIL_ALPHA 9 // Use alpha channel of detail to mask base
#define DETAIL_BLEND_MODE_SSBUMP_BUMP 10 // Use detail to modulate lighting as an ssbump
#define DETAIL_BLEND_MODE_SSBUMP_NOBUMP 11 // Detail is an ssbump but use it as an albedo. shader does the magic here - no user needs to specify mode 11
#define DETAIL_BLEND_MODE_NONE 12 // There is no detail texture
// Texture combining modes for combining base and decal texture
#define DECAL_BLEND_MODE_DECAL_ALPHA 0 // Original mode ( = decalRGB*decalA + baseRGB*(1-decalA))
#define DECAL_BLEND_MODE_RGB_MOD1X 1 // baseRGB * decalRGB
#define DECAL_BLEND_MODE_NONE 2 // There is no decal texture
// We force aniso on certain textures for the consoles only
#if defined( _GAMECONSOLE )
#define ANISOTROPIC_OVERRIDE TEXTUREFLAGS_ANISOTROPIC
#else
#define ANISOTROPIC_OVERRIDE 0
#endif
//-----------------------------------------------------------------------------
// Helper macro for vertex shaders
//-----------------------------------------------------------------------------
#define BEGIN_VS_SHADER_FLAGS(_name, _help, _flags) __BEGIN_SHADER_INTERNAL( CBaseVSShader, _name, _help, _flags )
#define BEGIN_VS_SHADER(_name,_help) __BEGIN_SHADER_INTERNAL( CBaseVSShader, _name, _help, 0 )
// useful parameter initialization macro
#define INIT_FLOAT_PARM( parm, value ) \
if ( !params[(parm)]->IsDefined() ) \
{ \
params[(parm)]->SetFloatValue( (value) ); \
}
// useful pixel shader declaration macro for ps20/20b c++ code
#define SET_STATIC_PS2X_PIXEL_SHADER_NO_COMBOS( basename ) \
if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) \
{ \
DECLARE_STATIC_PIXEL_SHADER( basename##_ps20b ); \
SET_STATIC_PIXEL_SHADER( basename##_ps20b ); \
} \
else \
{ \
DECLARE_STATIC_PIXEL_SHADER( basename##_ps20 ); \
SET_STATIC_PIXEL_SHADER( basename##_ps20 ); \
}
#define SET_DYNAMIC_PS2X_PIXEL_SHADER_NO_COMBOS( basename ) \
if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) \
{ \
DECLARE_DYNAMIC_PIXEL_SHADER( basename##_ps20b ); \
SET_DYNAMIC_PIXEL_SHADER( basename##_ps20b ); \
} \
else \
{ \
DECLARE_DYNAMIC_PIXEL_SHADER( basename##_ps20 ); \
SET_DYNAMIC_PIXEL_SHADER( basename##_ps20 ); \
}
//-----------------------------------------------------------------------------
// Base class for shaders, contains helper methods.
//-----------------------------------------------------------------------------
class CBaseVSShader : public CBaseShader
{
public:
// Loads bump lightmap coordinates into the pixel shader
void LoadBumpLightmapCoordinateAxes_PixelShader( int pixelReg );
// Loads bump lightmap coordinates into the vertex shader
void LoadBumpLightmapCoordinateAxes_VertexShader( int vertexReg );
// Pixel and vertex shader constants....
void SetPixelShaderConstant( int pixelReg, int constantVar );
// Pixel and vertex shader constants....
void SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar );
// This version will put constantVar into x,y,z, and constantVar2 into the w
void SetPixelShaderConstant( int pixelReg, int constantVar, int constantVar2 );
void SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar, int constantVar2 );
// Helpers for setting constants that need to be converted to linear space (from gamma space).
void SetVertexShaderConstantGammaToLinear( int var, float const* pVec, int numConst = 1, bool bForce = false );
void SetPixelShaderConstantGammaToLinear( int var, float const* pVec, int numConst = 1, bool bForce = false );
void SetVertexShaderConstant( int vertexReg, int constantVar );
// set rgb components of constant from a color parm and give an explicit w value
void SetPixelShaderConstant_W( int pixelReg, int constantVar, float fWValue );
// GR - fix for const/lerp issues
void SetPixelShaderConstantFudge( int pixelReg, int constantVar );
// Sets vertex shader texture transforms
void SetVertexShaderTextureTranslation( int vertexReg, int translationVar );
void SetVertexShaderTextureScale( int vertexReg, int scaleVar );
void SetVertexShaderTextureTransform( int vertexReg, int transformVar );
void SetVertexShaderTextureScaledTransform( int vertexReg,
int transformVar, int scaleVar );
// Set pixel shader texture transforms
void SetPixelShaderTextureTranslation( int pixelReg, int translationVar );
void SetPixelShaderTextureScale( int pixelReg, int scaleVar );
void SetPixelShaderTextureTransform( int pixelReg, int transformVar );
void SetPixelShaderTextureScaledTransform( int pixelReg,
int transformVar, int scaleVar );
// Moves a matrix into vertex shader constants
void SetVertexShaderMatrix3x4( int vertexReg, int matrixVar );
void SetVertexShaderMatrix4x4( int vertexReg, int matrixVar );
// Loads the view matrix into vertex shader constants
void LoadViewMatrixIntoVertexShaderConstant( int vertexReg );
// Loads the projection matrix into vertex shader constants
void LoadProjectionMatrixIntoVertexShaderConstant( int vertexReg );
// Loads the model->view matrix into vertex shader constants
void LoadModelViewMatrixIntoVertexShaderConstant( int vertexReg );
// Helpers for dealing with envmaptint
void SetEnvMapTintPixelShaderDynamicState( int pixelReg, int tintVar, int alphaVar, bool bConvertFromGammaToLinear = false );
// Helper methods for pixel shader overbrighting
void EnablePixelShaderOverbright( int reg, bool bEnable, bool bDivideByTwo );
// Sets up hw morphing state for the vertex shader
void SetHWMorphVertexShaderState( int nDimConst, int nSubrectConst, VertexTextureSampler_t morphSampler );
BlendType_t EvaluateBlendRequirements( int textureVar, bool isBaseTexture, int detailTextureVar = -1 );
// Helper for setting up flashlight constants
void SetFlashlightVertexShaderConstants( bool bBump, int bumpTransformVar, bool bDetail, int detailScaleVar, bool bSetTextureTransforms );
struct DrawFlashlight_dx90_Vars_t
{
DrawFlashlight_dx90_Vars_t()
{
// set all ints to -1
memset( this, 0xFF, sizeof(DrawFlashlight_dx90_Vars_t) );
// set all bools to a default value.
m_bBump = false;
m_bLightmappedGeneric = false;
m_bWorldVertexTransition = false;
m_bTeeth = false;
m_bSSBump = false;
m_fSeamlessScale = 0.0;
}
bool m_bBump;
bool m_bLightmappedGeneric;
bool m_bWorldVertexTransition;
bool m_bTeeth;
int m_nBumpmapVar;
int m_nBumpmapFrame;
int m_nBumpTransform;
int m_nFlashlightTextureVar;
int m_nFlashlightTextureFrameVar;
int m_nBaseTexture2Var;
int m_nBaseTexture2FrameVar;
int m_nBumpmapVar2;
int m_nBumpmapFrame2;
int m_nBumpTransform2;
int m_nDetailVar;
int m_nDetailScale;
int m_nDetailTextureCombineMode;
int m_nDetailTextureBlendFactor;
int m_nDetailTint;
int m_nDetailVar2;
int m_nDetailScale2;
int m_nDetailTextureBlendFactor2;
int m_nDetailTint2;
int m_nTeethForwardVar;
int m_nTeethIllumFactorVar;
int m_nAlphaTestReference;
bool m_bSSBump;
float m_fSeamlessScale; // 0.0 = not seamless
int m_nLayerTint1;
int m_nLayerTint2;
};
void DrawFlashlight_dx90( IMaterialVar** params,
IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, DrawFlashlight_dx90_Vars_t &vars );
void HashShadow2DJitter( const float fJitterSeed, float *fU, float* fV );
//Alpha tested materials can end up leaving garbage in the dest alpha buffer if they write depth.
//This pass fills in the areas that passed the alpha test with depth in dest alpha
//by writing only equal depth pixels and only if we should be writing depth to dest alpha
void DrawEqualDepthToDestAlpha( void );
private:
// Converts a color + alpha into a vector4
void ColorVarsToVector( int colorVar, int alphaVar, Vector4D &color );
};
FORCEINLINE bool IsSRGBDetailTexture( int nMode )
{
return ( nMode == DETAIL_BLEND_MODE_DETAIL_OVER_BASE ) ||
( nMode == DETAIL_BLEND_MODE_FADE ) ||
( nMode == DETAIL_BLEND_MODE_BASE_OVER_DETAIL );
}
FORCEINLINE bool IsSRGBDecalTexture( int nMode )
{
return (nMode == DECAL_BLEND_MODE_DECAL_ALPHA);
}
FORCEINLINE char * GetFlashlightTextureFilename()
{
//if ( !IsX360() && ( g_pHardwareConfig->SupportsBorderColor() ) )
//{
// return "effects/flashlight001_border";
//}
//else
{
return "effects/flashlight001";
}
}
extern ConVar r_flashlightbrightness;
FORCEINLINE void SetFlashLightColorFromState( FlashlightState_t const &state, IShaderDynamicAPI *pShaderAPI, bool bSinglePassFlashlight, int nPSRegister=28, bool bFlashlightNoLambert=false )
{
// Old code
//float flToneMapScale = ( ShaderApiFast( pShaderAPI )->GetToneMappingScaleLinear() ).x;
//float flFlashlightScale = 1.0f / flToneMapScale;
// Fix to old code to keep flashlight from ever getting brighter than 1.0
//float flToneMapScale = ( ShaderApiFast( pShaderAPI )->GetToneMappingScaleLinear() ).x;
//if ( flToneMapScale < 1.0f )
// flToneMapScale = 1.0f;
//float flFlashlightScale = 1.0f / flToneMapScale;
float flFlashlightScale = r_flashlightbrightness.GetFloat();
if ( !g_pHardwareConfig->GetHDREnabled() )
{
// Non-HDR path requires 2.0 flashlight
flFlashlightScale = 2.0f;
}
// DX10 hardware and single pass flashlight require a hack scalar since the flashlight is added in linear space
if ( ( g_pHardwareConfig->UsesSRGBCorrectBlending() ) || ( bSinglePassFlashlight ) )
{
flFlashlightScale *= 2.5f; // Magic number that works well on the 360 and NVIDIA 8800
}
flFlashlightScale *= state.m_fBrightnessScale;
// Generate pixel shader constant
float const *pFlashlightColor = state.m_Color;
float vPsConst[4] = { flFlashlightScale * pFlashlightColor[0], flFlashlightScale * pFlashlightColor[1], flFlashlightScale * pFlashlightColor[2], pFlashlightColor[3] };
vPsConst[3] = bFlashlightNoLambert ? 2.0f : 0.0f; // This will be added to N.L before saturate to force a 1.0 N.L term
// Red flashlight for testing
//vPsConst[0] = 0.5f; vPsConst[1] = 0.0f; vPsConst[2] = 0.0f;
ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( nPSRegister, ( float * )vPsConst );
}
FORCEINLINE float ShadowAttenFromState( FlashlightState_t const &state )
{
// DX10 requires some hackery due to sRGB/blend ordering change from DX9, which makes the shadows too light
if ( g_pHardwareConfig->UsesSRGBCorrectBlending() )
return state.m_flShadowAtten * 0.1f; // magic number
return state.m_flShadowAtten;
}
FORCEINLINE float ShadowFilterFromState( FlashlightState_t const &state )
{
// We developed shadow maps at 1024, so we expect the penumbra size to have been tuned relative to that
return state.m_flShadowFilterSize / 1024.0f;
}
FORCEINLINE void SetupUberlightFromState( IShaderDynamicAPI *pShaderAPI, FlashlightState_t const &state )
{
// Bail if we can't do ps30 or we don't even want an uberlight
if ( !g_pHardwareConfig->HasFastVertexTextures() || !state.m_bUberlight || !pShaderAPI )
return;
UberlightState_t u = state.m_uberlightState;
// Set uberlight shader parameters as function of user controls from UberlightState_t
Vector4D vSmoothEdge0 = Vector4D( 0.0f, u.m_fCutOn - u.m_fNearEdge, u.m_fCutOff, 0.0f );
Vector4D vSmoothEdge1 = Vector4D( 0.0f, u.m_fCutOn, u.m_fCutOff + u.m_fFarEdge, 0.0f );
Vector4D vSmoothOneOverW = Vector4D( 0.0f, 1.0f / u.m_fNearEdge, 1.0f / u.m_fFarEdge, 0.0f );
Vector4D vShearRound = Vector4D( u.m_fShearx, u.m_fSheary, 2.0f / u.m_fRoundness, -u.m_fRoundness / 2.0f );
Vector4D vaAbB = Vector4D( u.m_fWidth, u.m_fWidth + u.m_fWedge, u.m_fHeight, u.m_fHeight + u.m_fHedge );
ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( PSREG_UBERLIGHT_SMOOTH_EDGE_0, vSmoothEdge0.Base(), 1 );
ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( PSREG_UBERLIGHT_SMOOTH_EDGE_1, vSmoothEdge1.Base(), 1 );
ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( PSREG_UBERLIGHT_SMOOTH_EDGE_OOW, vSmoothOneOverW.Base(), 1 );
ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( PSREG_UBERLIGHT_SHEAR_ROUND, vShearRound.Base(), 1 );
ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( PSREG_UBERLIGHT_AABB, vaAbB.Base(), 1 );
QAngle angles;
QuaternionAngles( state.m_quatOrientation, angles );
// World to Light's View matrix
matrix3x4_t viewMatrix, viewMatrixInverse;
AngleMatrix( angles, state.m_vecLightOrigin, viewMatrixInverse );
MatrixInvert( viewMatrixInverse, viewMatrix );
ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( PSREG_UBERLIGHT_WORLD_TO_LIGHT, viewMatrix.Base(), 4 );
}
// convenient material variable access functions for helpers to use.
FORCEINLINE bool IsTextureSet( int nVar, IMaterialVar **params )
{
return ( nVar != -1 ) && ( params[nVar]->IsTexture() );
}
FORCEINLINE bool IsBoolSet( int nVar, IMaterialVar **params )
{
return ( nVar != -1 ) && ( params[nVar]->GetIntValue() );
}
FORCEINLINE int GetIntParam( int nVar, IMaterialVar **params, int nDefaultValue = 0 )
{
return ( nVar != -1 ) ? ( params[nVar]->GetIntValue() ) : nDefaultValue;
}
FORCEINLINE float GetFloatParam( int nVar, IMaterialVar **params, float flDefaultValue = 0.0 )
{
return ( nVar != -1 ) ? ( params[nVar]->GetFloatValue() ) : flDefaultValue;
}
FORCEINLINE void InitFloatParam( int nIndex, IMaterialVar **params, float flValue )
{
if ( (nIndex != -1) && !params[nIndex]->IsDefined() )
{
params[nIndex]->SetFloatValue( flValue );
}
}
FORCEINLINE void InitIntParam( int nIndex, IMaterialVar **params, int nValue )
{
if ( (nIndex != -1) && !params[nIndex]->IsDefined() )
{
params[nIndex]->SetIntValue( nValue );
}
}
FORCEINLINE void InitVecParam( int nIndex, IMaterialVar **params, float x, float y )
{
if ( (nIndex != -1) && !params[nIndex]->IsDefined() )
{
params[nIndex]->SetVecValue( x, y );
}
}
FORCEINLINE void InitVecParam( int nIndex, IMaterialVar **params, float x, float y, float z )
{
if ( (nIndex != -1) && !params[nIndex]->IsDefined() )
{
params[nIndex]->SetVecValue( x, y, z );
}
}
FORCEINLINE void InitVecParam( int nIndex, IMaterialVar **params, float x, float y, float z, float w )
{
if ( (nIndex != -1) && !params[nIndex]->IsDefined() )
{
params[nIndex]->SetVecValue( x, y, z, w );
}
}
// Did we launch with -tools
bool ToolsEnabled();
class ConVar;
#ifdef _DEBUG
extern ConVar mat_envmaptintoverride;
extern ConVar mat_envmaptintscale;
#endif
#endif // BASEVSSHADER_H