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.
 
 
 
 
 
 

501 lines
20 KiB

//========= Copyright (c) 1996-2007, Valve LLC, All rights reserved. ============
//
// Purpose: Lightmapped paint shader
//
// $Header: $
// $NoKeywords: $
//=============================================================================
#include "lightmappedpaint_dx9_helper.h"
#include "BaseVSShader.h"
#include "shaderlib/commandbuilder.h"
#include "convar.h"
#include "lightmappedgeneric_vs20.inc"
#include "lightmappedpaint_ps20.inc"
#include "lightmappedpaint_ps20b.inc"
#include "tier0/vprof.h"
#include "shaderapifast.h"
#include "tier0/memdbgon.h"
extern ConVar mat_ambient_light_r;
extern ConVar mat_ambient_light_g;
extern ConVar mat_ambient_light_b;
void DrawLightmappedPaint_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow,
LightmappedGeneric_DX9_Vars_t &info, CBasePerMaterialContextData **pContextDataPtr )
{
SHADOW_STATE
{
pShader->SetInitialShadowState();
}
CLightmappedGeneric_DX9_Context *pContextData = reinterpret_cast< CLightmappedGeneric_DX9_Context *>( *pContextDataPtr );
bool bHDR = g_pHardwareConfig->GetHDRType() != HDR_TYPE_NONE;
if ( pShaderShadow || ( ! pContextData ) || pContextData->m_bMaterialVarsChanged )
{
static ConVarRef gpu_level( "gpu_level" );
int nGPULevel = gpu_level.GetInt();
bool bFullyOpaqueWithoutAlphaTest = false;
bool bFullyOpaque = false;
bool bNeedRegenStaticCmds = (! pContextData ) || pShaderShadow;
bool bThickPaint = ( nGPULevel > 1 );
#ifdef _GAMECONSOLE
bThickPaint = TRUE;
#endif
if ( ! pContextData ) // make sure allocated
{
pContextData = new CLightmappedGeneric_DX9_Context;
*pContextDataPtr = pContextData;
}
bool hasBump = true; //g_pConfig->UseBumpmapping();
bool hasSSBump = hasBump && (info.m_nSelfShadowedBumpFlag != -1) && ( params[info.m_nSelfShadowedBumpFlag]->GetIntValue() );
bool hasSelfIllum = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM );
bool bHasBlendModulateTexture =
(info.m_nBlendModulateTexture != -1) &&
(params[info.m_nBlendModulateTexture]->IsTexture() );
pContextData->m_bFullyOpaque = bFullyOpaque;
pContextData->m_bFullyOpaqueWithoutAlphaTest = bFullyOpaqueWithoutAlphaTest;
bool hasEnvmapMask = params[info.m_nEnvmapMask]->IsTexture();
if ( pShaderShadow || bNeedRegenStaticCmds )
{
bool hasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR );
bool hasEnvmap = params[info.m_nPaintEnvmap]->IsTexture();
int envmap_variant; //0 = no envmap, 1 = regular, 2 = darken in shadow mode
if( hasEnvmap )
{
//only enabled darkened cubemap mode when the scale calls for it. And not supported in ps20 when also using a 2nd bumpmap
envmap_variant = ((GetFloatParam( info.m_nEnvMapLightScale, params ) > 0.0f) && g_pHardwareConfig->SupportsPixelShaders_2_b()) ? 2 : 1;
}
else
{
envmap_variant = 1;
}
bool bSeamlessMapping = ( ( info.m_nSeamlessMappingScale != -1 ) &&
( params[info.m_nSeamlessMappingScale]->GetFloatValue() != 0.0 ) );
if ( bNeedRegenStaticCmds )
{
pContextData->ResetStaticCmds();
CCommandBufferBuilder< CFixedCommandStorageBuffer< 5000 > > staticCmdsBuf;
#if 0
int nLightingPreviewMode = IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER0 ) + 2 * IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER1 );
if ( ( nLightingPreviewMode == ENABLE_FIXED_LIGHTING_OUTPUTNORMAL_AND_DEPTH ) && IsPC() )
{
staticCmdsBuf.SetVertexShaderNearAndFarZ( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6 ); // Needed for SSAO
}
#endif
staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER1, bHDR ? TEXTURE_BINDFLAGS_NONE : TEXTURE_BINDFLAGS_SRGBREAD, TEXTURE_LIGHTMAP );
//noise
staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER6, TEXTURE_BINDFLAGS_NONE, TEXTURE_SHADOW_NOISE_2D );
//paint map
staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER9, TEXTURE_BINDFLAGS_NONE, TEXTURE_PAINT );
if ( bSeamlessMapping )
{
staticCmdsBuf.SetVertexShaderConstant4(
VERTEX_SHADER_SHADER_SPECIFIC_CONST_0,
params[info.m_nSeamlessMappingScale]->GetFloatValue(),0,0,0 );
}
staticCmdsBuf.StoreEyePosInPixelShaderConstant( 10 );
#ifndef _PS3
staticCmdsBuf.SetPixelShaderFogParams( 11 );
#endif
staticCmdsBuf.End();
// now, copy buf
pContextData->m_pStaticCmds = new uint8[staticCmdsBuf.Size()];
memcpy( pContextData->m_pStaticCmds, staticCmdsBuf.Base(), staticCmdsBuf.Size() );
}
if ( pShaderShadow )
{
pShader->EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA );
// Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState
//pShaderShadow->EnableAlphaTest( true );
//pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.0f );
unsigned int flags = VERTEX_POSITION;
flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T | VERTEX_NORMAL;
if( hasEnvmapMask )
{
pShaderShadow->EnableTexture( SHADER_SAMPLER5, true );
}
if( hasVertexColor )
{
flags |= VERTEX_COLOR;
}
// texcoord0 : base texcoord
// texcoord1 : lightmap texcoord
// texcoord2 : lightmap texcoord offset
int numTexCoords;
// if ( ShaderApiFast( pShaderAPI )->InEditorMode() )
// if ( pShader->CanUseEditorMaterials() )
// {
// numTexCoords = 1;
// }
// else
{
numTexCoords = 2;
if( hasBump )
{
numTexCoords = 3;
}
}
int nLightingPreviewMode = 0;
#if 0
int nLightingPreviewMode = IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER0 ) + 2 * IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER1 );
#endif
pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 );
// Pre-cache pixel shaders
int bumpmap_variant=(hasSSBump) ? 2 : hasBump;
DECLARE_STATIC_VERTEX_SHADER( lightmappedgeneric_vs20 );
SET_STATIC_VERTEX_SHADER_COMBO( ENVMAP_MASK, hasEnvmapMask );
SET_STATIC_VERTEX_SHADER_COMBO( TANGENTSPACE, 1 ); //need tangent transpose matrix for lighting
SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, hasBump );
SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) );
SET_STATIC_VERTEX_SHADER_COMBO( VERTEXALPHATEXBLENDFACTOR, 0 );
SET_STATIC_VERTEX_SHADER_COMBO( BUMPMASK, 0 );
SET_STATIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, nLightingPreviewMode );
SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, bSeamlessMapping );
SET_STATIC_VERTEX_SHADER_COMBO( DETAILTEXTURE, 0 );
SET_STATIC_VERTEX_SHADER_COMBO( FANCY_BLENDING, bHasBlendModulateTexture );
SET_STATIC_VERTEX_SHADER_COMBO( SELFILLUM, hasSelfIllum );
SET_STATIC_VERTEX_SHADER_COMBO( PAINT, 1 );
SET_STATIC_VERTEX_SHADER_COMBO( ADDBUMPMAPS, 0 );
#if defined( _X360 ) || defined( _PS3 )
SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, 0);
#endif
SET_STATIC_VERTEX_SHADER( lightmappedgeneric_vs20 );
#define TCOMBINE_NONE 12 // there is no detail texture
if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( lightmappedpaint_ps20b );
SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bumpmap_variant );
SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, envmap_variant );
SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping );
SET_STATIC_PIXEL_SHADER_COMBO( THICKPAINT, bThickPaint );
SET_STATIC_PIXEL_SHADER( lightmappedpaint_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( lightmappedpaint_ps20 );
SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bumpmap_variant );
SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, envmap_variant );
SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping );
SET_STATIC_PIXEL_SHADER_COMBO( THICKPAINT, bThickPaint );
SET_STATIC_PIXEL_SHADER( lightmappedpaint_ps20 );
}
// HACK HACK HACK - enable alpha writes all the time so that we have them for
// underwater stuff and writing depth to dest alpha
// But only do it if we're not using the alpha already for translucency
pShaderShadow->EnableAlphaWrites( bFullyOpaque );
pShaderShadow->EnableSRGBWrite( true );
pShader->DefaultFog();
float flLScale = pShaderShadow->GetLightMapScaleFactor();
pShader->PI_BeginCommandBuffer();
pShader->PI_SetModulationPixelShaderDynamicState( 21 );
pShader->PI_SetModulationPixelShaderDynamicState_LinearScale_ScaleInW( 12, flLScale );
pShader->PI_SetModulationVertexShaderDynamicState_LinearScale( flLScale );
pShader->PI_EndCommandBuffer();
} // end shadow state
} // end shadow || regen display list
if ( pShaderAPI && ( pContextData->m_bMaterialVarsChanged ) )
{
// need to regenerate the semistatic cmds
pContextData->m_SemiStaticCmdsOut.Reset();
pContextData->m_bMaterialVarsChanged = false;
// If we don't have a texture transform, we don't have
// to set vertex shader constants or run vertex shader instructions
// for the texture transform.
bool bHasTextureTransform =
!( params[info.m_nBaseTextureTransform]->MatrixIsIdentity() &&
params[info.m_nBumpTransform]->MatrixIsIdentity() &&
params[info.m_nBumpTransform2]->MatrixIsIdentity() &&
params[info.m_nEnvmapMaskTransform]->MatrixIsIdentity() );
pContextData->m_bVertexShaderFastPath = !bHasTextureTransform;
if( params[info.m_nDetail]->IsTexture() )
{
pContextData->m_bVertexShaderFastPath = false;
}
int nTransformToLoad = -1;
if ( ( hasBump || hasSSBump ) && !hasSelfIllum && !bHasBlendModulateTexture )
{
nTransformToLoad = info.m_nBumpTransform;
}
pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform(
VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, nTransformToLoad );
if ( ! pContextData->m_bVertexShaderFastPath )
{
bool bSeamlessMapping = ( ( info.m_nSeamlessMappingScale != -1 ) &&
( params[info.m_nSeamlessMappingScale]->GetFloatValue() != 0.0 ) );
bool hasEnvmapMask = params[info.m_nEnvmapMask]->IsTexture();
if (!bSeamlessMapping )
pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform );
// If we have a detail texture, then the bump texcoords are the same as the base texcoords.
if( hasBump )
{
pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBumpTransform );
}
if( hasEnvmapMask )
{
pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nEnvmapMaskTransform );
}
}
pContextData->m_SemiStaticCmdsOut.SetEnvMapTintPixelShaderDynamicState( 0, info.m_nEnvmapTint );
float envmapTintVal[4];
float selfIllumTintVal[4];
params[info.m_nEnvmapTint]->GetVecValue( envmapTintVal, 3 );
params[info.m_nSelfIllumTint]->GetVecValue( selfIllumTintVal, 3 );
float envmapContrast = params[info.m_nEnvmapContrast]->GetFloatValue();
float envmapSaturation = params[info.m_nEnvmapSaturation]->GetFloatValue();
float fresnelReflection = params[info.m_nFresnelReflection]->GetFloatValue();
bool hasEnvmap = params[info.m_nPaintEnvmap]->IsTexture();
int envmap_variant; //0 = no envmap, 1 = regular, 2 = darken in shadow mode
if( hasEnvmap )
{
//only enabled darkened cubemap mode when the scale calls for it. And not supported in ps20 when also using a 2nd bumpmap
envmap_variant = ((GetFloatParam( info.m_nEnvMapLightScale, params ) > 0.0f) && g_pHardwareConfig->SupportsPixelShaders_2_b()) ? 2 : 1;
}
else
{
envmap_variant = 0;
}
pContextData->m_bPixelShaderFastPath = true;
bool bUsingContrastOrSaturation = hasEnvmap && ( ( (envmapContrast != 0.0f) && (envmapContrast != 1.0f) ) || (envmapSaturation != 1.0f) );
bool bUsingFresnel = hasEnvmap && (fresnelReflection != 1.0f);
bool bUsingSelfIllumTint = IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) && (selfIllumTintVal[0] != 1.0f || selfIllumTintVal[1] != 1.0f || selfIllumTintVal[2] != 1.0f);
if ( bUsingContrastOrSaturation || bUsingFresnel || bUsingSelfIllumTint || !g_pConfig->bShowSpecular )
{
pContextData->m_bPixelShaderFastPath = false;
}
if( !pContextData->m_bPixelShaderFastPath )
{
pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstants( 2, 3 );
pContextData->m_SemiStaticCmdsOut.OutputConstantData( params[info.m_nEnvmapContrast]->GetVecValue() );
pContextData->m_SemiStaticCmdsOut.OutputConstantData( params[info.m_nEnvmapSaturation]->GetVecValue() );
float flFresnel = params[info.m_nFresnelReflection]->GetFloatValue();
// [ 0, 0, 1-R(0), R(0) ]
pContextData->m_SemiStaticCmdsOut.OutputConstantData4( 0., 0., 1.0 - flFresnel, flFresnel );
pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 7, params[info.m_nSelfIllumTint]->GetVecValue() );
}
// parallax and cubemap light scale mapping parms (c20)
if ( envmap_variant == 2 )
{
pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant4( 20, 0, GetFloatParam( info.m_nEnvMapLightScale, params), 0, 0 );
}
// texture binds
// handle mat_fullbright 2
bool bLightingOnly = g_pConfig->nFullbright == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE );
if( bLightingOnly )
{
// disable color modulation
float color[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color );
// turn off environment mapping
envmapTintVal[0] = 0.0f;
envmapTintVal[1] = 0.0f;
envmapTintVal[2] = 0.0f;
}
if( params[info.m_nPaintSplatNormal]->IsTexture() )
{
pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER7, TEXTURE_BINDFLAGS_NONE, info.m_nPaintSplatNormal );
}
else
{
pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER7, TEXTURE_BINDFLAGS_NONE, TEXTURE_NORMALMAP_FLAT );
}
if( params[info.m_nPaintSplatBubbleLayout]->IsTexture() )
{
pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER4, TEXTURE_BINDFLAGS_NONE, info.m_nPaintSplatBubbleLayout );
}
else
{
pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER4, TEXTURE_BINDFLAGS_NONE, TEXTURE_BLACK );
}
if( params[info.m_nPaintSplatBubble]->IsTexture() )
{
pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER5, TEXTURE_BINDFLAGS_NONE, info.m_nPaintSplatBubble );
}
else
{
pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER5, TEXTURE_BINDFLAGS_NONE, TEXTURE_NORMALMAP_FLAT );
}
if ( bHasBlendModulateTexture )
{
pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER3, TEXTURE_BINDFLAGS_NONE, info.m_nBlendModulateTexture, -1 );
}
pContextData->m_SemiStaticCmdsOut.End();
}
}
DYNAMIC_STATE
{
ShaderApiFast( pShaderAPI )->SetDefaultState();
#ifdef _PS3
CCommandBufferBuilder< CDynamicCommandStorageBuffer > DynamicCmdsOut;
ShaderApiFast( pShaderAPI )->ExecuteCommandBuffer( pContextData->m_pStaticCmds );
ShaderApiFast( pShaderAPI )->ExecuteCommandBuffer( pContextData->m_SemiStaticCmdsOut.Base() );
#else
CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut;
DynamicCmdsOut.Call( pContextData->m_pStaticCmds );
DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() );
#endif
bool hasEnvmap = params[info.m_nPaintEnvmap]->IsTexture();
if ( hasEnvmap )
{
DynamicCmdsOut.BindEnvCubemapTexture( pShader, SHADER_SAMPLER2, bHDR ? TEXTURE_BINDFLAGS_NONE : TEXTURE_BINDFLAGS_SRGBREAD, info.m_nPaintEnvmap, info.m_nEnvmapFrame );
}
bool bVertexShaderFastPath = pContextData->m_bVertexShaderFastPath;
int nFixedLightingMode = ShaderApiFast( pShaderAPI )->GetIntRenderingParameter( INT_RENDERPARM_ENABLE_FIXED_LIGHTING );
if( nFixedLightingMode != ENABLE_FIXED_LIGHTING_NONE )
{
bVertexShaderFastPath = false;
}
float vEyePos[4];
ShaderApiFast( pShaderAPI )->GetWorldSpaceCameraPosition( vEyePos );
DynamicCmdsOut.SetVertexShaderConstant4( 12, vEyePos[0], vEyePos[1], vEyePos[2], 0.0f );
// These constants are used to rotate the world space water normals around the up axis to align the
// normal with the camera and then give us a 2D offset vector to use for reflection and refraction uv's
VMatrix mView;
ShaderApiFast( pShaderAPI )->GetMatrix( MATERIAL_VIEW, mView.m[0] );
mView = mView.Transpose3x3();
Vector4D vCameraRight( mView.m[0][0], mView.m[0][1], mView.m[0][2], 0.0f );
vCameraRight.z = 0.0f; // Project onto the plane of water
vCameraRight.AsVector3D().NormalizeInPlace();
Vector4D vCameraForward;
CrossProduct( Vector( 0.0f, 0.0f, 1.0f ), vCameraRight.AsVector3D(), vCameraForward.AsVector3D() ); // I assume the water surface normal is pointing along z!
ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( 22, vCameraRight.Base() );
ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( 23, vCameraForward.Base() );
MaterialFogMode_t fogType = ShaderApiFast( pShaderAPI )->GetSceneFogMode();
DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_vs20 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( FASTPATH, bVertexShaderFastPath );
SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, lightmappedgeneric_vs20 );
// This block of logic is up here and is so verbose because the compiler on the Mac was previously
// optimizing much of this away and allowing out of range values into the logic which ultimately
// computes the dynamic index. Please leave this here and don't try to weave it into the dynamic
// combo setting macros below.
bool bPixelShaderFastPath = false;
if ( pContextData->m_bPixelShaderFastPath )
bPixelShaderFastPath = true;
bool bFastPath = false;
if ( bPixelShaderFastPath )
bFastPath = true;
if ( nFixedLightingMode != ENABLE_FIXED_LIGHTING_NONE )
{
bPixelShaderFastPath = false;
}
bool bWriteDepthToAlpha;
bool bWriteWaterFogToAlpha;
if( pContextData->m_bFullyOpaque )
{
bWriteDepthToAlpha = ShaderApiFast( pShaderAPI )->ShouldWriteDepthToDestAlpha();
bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z);
AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." );
}
else
{
//can't write a special value to dest alpha if we're actually using as-intended alpha
bWriteDepthToAlpha = false;
bWriteWaterFogToAlpha = false;
}
// only do ambient light when not using flashlight
float vAmbientColor[4] = { mat_ambient_light_r.GetFloat(), mat_ambient_light_g.GetFloat(), mat_ambient_light_b.GetFloat(), 0.0f };
if ( g_pConfig->nFullbright == 1 )
{
vAmbientColor[0] = vAmbientColor[1] = vAmbientColor[2] = 0.0f;
}
DynamicCmdsOut.SetPixelShaderConstant( 31, vAmbientColor, 1 );
float envmapContrast = params[info.m_nEnvmapContrast]->GetFloatValue();
if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( lightmappedpaint_ps20b );
SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATH, bFastPath );
SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATHENVMAPCONTRAST, bPixelShaderFastPath && envmapContrast == 1.0f );
// Don't write fog to alpha if we're using translucency
SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, lightmappedpaint_ps20b );
}
else
{
DECLARE_DYNAMIC_PIXEL_SHADER( lightmappedpaint_ps20 );
SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATH, bPixelShaderFastPath );
SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATHENVMAPCONTRAST, bPixelShaderFastPath && envmapContrast == 1.0f );
// Don't write fog to alpha if we're using translucency
SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, lightmappedpaint_ps20 );
}
DynamicCmdsOut.End();
#ifdef _PS3
ShaderApiFast( pShaderAPI )->SetPixelShaderFogParams( 11 );
#endif
ShaderApiFast( pShaderAPI )->ExecuteCommandBuffer( DynamicCmdsOut.Base() );
}
pShader->Draw();
}