1801 lines
61 KiB
C++
1801 lines
61 KiB
C++
//
|
|
// filename: ShaderLib.cpp
|
|
// description: Class controlling loading of shaders
|
|
// written by: Adam Fowler
|
|
//
|
|
|
|
#include "shaders/ShaderLib.h"
|
|
|
|
// Rage headers
|
|
#include "bank/bank.h"
|
|
#include "bank/bkmgr.h"
|
|
#include "grmodel/shader.h"
|
|
#include "grmodel/shaderfx.h"
|
|
#include "grcore/device.h"
|
|
#include "grcore/effect.h"
|
|
#include "grcore/im.h"
|
|
#include "streaming/streaming.h"
|
|
#include "system/xtl.h"
|
|
|
|
// Framework headers
|
|
#include "fwsys/gameskeleton.h"
|
|
#include "fwdrawlist/drawlistmgr.h"
|
|
|
|
// Game headers
|
|
#include "debug/debug.h"
|
|
#include "debug/Rendering/DebugDeferred.h"
|
|
#include "game/weather.h"
|
|
#include "peds/ped.h"
|
|
#include "Renderer/Renderer.h"
|
|
#include "renderer/DrawLists/drawListMgr.h"
|
|
#include "renderer/Deferred/DeferredLighting.h"
|
|
#include "renderer/PostProcessFX.h"
|
|
#include "renderer/RenderPhases/RenderPhaseCascadeShadows.h" // for IsEnabled
|
|
#include "renderer/RenderPhases/RenderPhaseEntitySelect.h" // for ENTITYSELECT_ENABLED_BUILD
|
|
#include "shader_source/vehicles/vehicle_common_values.h" // For GPU_DAMAGE_WRITE_ENABLED
|
|
#include "renderer/Deferred/GBuffer.h"
|
|
#include "renderer/rendertargets.h"
|
|
#include "renderer/SpuPm/SpuPmMgr.h"
|
|
#include "scene/world/GameWorld.h"
|
|
#include "timecycle/TimeCycle.h"
|
|
#include "vfx/misc/LinearPiecewiseFog.h"
|
|
|
|
#if RSG_ORBIS
|
|
#include "gnmx/helpers.h"
|
|
#endif
|
|
|
|
//OPTIMISATIONS_OFF()
|
|
|
|
// PSN: when enabled, AlphaRefs constants must be enabled as variables in common.fxh
|
|
#define USE_ALPHAREF (__XENON || __PPU || __D3D11 || RSG_ORBIS)
|
|
|
|
// See also USE_SSTAA define for Durango in shader code, common.fxh, l. 331
|
|
#define USE_TRANSPARENCYAA (1)
|
|
|
|
// Generated via: for (int i=0; i<256; i++) printf("%d.0f/255,%s",i,(i&7)!=7?"":"\n\t");
|
|
float CShaderLib::ms_divideBy255[256] = {
|
|
0.0f/255,1.0f/255,2.0f/255,3.0f/255,4.0f/255,5.0f/255,6.0f/255,7.0f/255,
|
|
8.0f/255,9.0f/255,10.0f/255,11.0f/255,12.0f/255,13.0f/255,14.0f/255,15.0f/255,
|
|
16.0f/255,17.0f/255,18.0f/255,19.0f/255,20.0f/255,21.0f/255,22.0f/255,23.0f/255,
|
|
24.0f/255,25.0f/255,26.0f/255,27.0f/255,28.0f/255,29.0f/255,30.0f/255,31.0f/255,
|
|
32.0f/255,33.0f/255,34.0f/255,35.0f/255,36.0f/255,37.0f/255,38.0f/255,39.0f/255,
|
|
40.0f/255,41.0f/255,42.0f/255,43.0f/255,44.0f/255,45.0f/255,46.0f/255,47.0f/255,
|
|
48.0f/255,49.0f/255,50.0f/255,51.0f/255,52.0f/255,53.0f/255,54.0f/255,55.0f/255,
|
|
56.0f/255,57.0f/255,58.0f/255,59.0f/255,60.0f/255,61.0f/255,62.0f/255,63.0f/255,
|
|
64.0f/255,65.0f/255,66.0f/255,67.0f/255,68.0f/255,69.0f/255,70.0f/255,71.0f/255,
|
|
72.0f/255,73.0f/255,74.0f/255,75.0f/255,76.0f/255,77.0f/255,78.0f/255,79.0f/255,
|
|
80.0f/255,81.0f/255,82.0f/255,83.0f/255,84.0f/255,85.0f/255,86.0f/255,87.0f/255,
|
|
88.0f/255,89.0f/255,90.0f/255,91.0f/255,92.0f/255,93.0f/255,94.0f/255,95.0f/255,
|
|
96.0f/255,97.0f/255,98.0f/255,99.0f/255,100.0f/255,101.0f/255,102.0f/255,103.0f/255,
|
|
104.0f/255,105.0f/255,106.0f/255,107.0f/255,108.0f/255,109.0f/255,110.0f/255,111.0f/255,
|
|
112.0f/255,113.0f/255,114.0f/255,115.0f/255,116.0f/255,117.0f/255,118.0f/255,119.0f/255,
|
|
120.0f/255,121.0f/255,122.0f/255,123.0f/255,124.0f/255,125.0f/255,126.0f/255,127.0f/255,
|
|
128.0f/255,129.0f/255,130.0f/255,131.0f/255,132.0f/255,133.0f/255,134.0f/255,135.0f/255,
|
|
136.0f/255,137.0f/255,138.0f/255,139.0f/255,140.0f/255,141.0f/255,142.0f/255,143.0f/255,
|
|
144.0f/255,145.0f/255,146.0f/255,147.0f/255,148.0f/255,149.0f/255,150.0f/255,151.0f/255,
|
|
152.0f/255,153.0f/255,154.0f/255,155.0f/255,156.0f/255,157.0f/255,158.0f/255,159.0f/255,
|
|
160.0f/255,161.0f/255,162.0f/255,163.0f/255,164.0f/255,165.0f/255,166.0f/255,167.0f/255,
|
|
168.0f/255,169.0f/255,170.0f/255,171.0f/255,172.0f/255,173.0f/255,174.0f/255,175.0f/255,
|
|
176.0f/255,177.0f/255,178.0f/255,179.0f/255,180.0f/255,181.0f/255,182.0f/255,183.0f/255,
|
|
184.0f/255,185.0f/255,186.0f/255,187.0f/255,188.0f/255,189.0f/255,190.0f/255,191.0f/255,
|
|
192.0f/255,193.0f/255,194.0f/255,195.0f/255,196.0f/255,197.0f/255,198.0f/255,199.0f/255,
|
|
200.0f/255,201.0f/255,202.0f/255,203.0f/255,204.0f/255,205.0f/255,206.0f/255,207.0f/255,
|
|
208.0f/255,209.0f/255,210.0f/255,211.0f/255,212.0f/255,213.0f/255,214.0f/255,215.0f/255,
|
|
216.0f/255,217.0f/255,218.0f/255,219.0f/255,220.0f/255,221.0f/255,222.0f/255,223.0f/255,
|
|
224.0f/255,225.0f/255,226.0f/255,227.0f/255,228.0f/255,229.0f/255,230.0f/255,231.0f/255,
|
|
232.0f/255,233.0f/255,234.0f/255,235.0f/255,236.0f/255,237.0f/255,238.0f/255,239.0f/255,
|
|
240.0f/255,241.0f/255,242.0f/255,243.0f/255,244.0f/255,245.0f/255,246.0f/255,247.0f/255,
|
|
248.0f/255,249.0f/255,250.0f/255,251.0f/255,252.0f/255,253.0f/255,254.0f/255,255.0f/255 };
|
|
|
|
|
|
//
|
|
//
|
|
//
|
|
//
|
|
grcEffectGlobalVar CShaderLib::ms_globalScalarsID; //x=globalAlpha y=HDRMultiplier z=AmbientScale
|
|
grcEffectGlobalVar CShaderLib::ms_globalScalars2ID;
|
|
grcEffectGlobalVar CShaderLib::ms_globalScalars3ID; // scale, invscale, normalScaler, naturalAmbientPush
|
|
#if !RSG_ORBIS && !RSG_DURANGO
|
|
grcEffectGlobalVar CShaderLib::ms_globalFadeID;
|
|
u16 CShaderLib::ms_FadeMask16;
|
|
#endif // !RSG_ORBIS && !RSG_DURANGO
|
|
|
|
grcDepthStencilStateHandle CShaderLib::ms_gDefaultState_DS = grcStateBlock::DSS_Invalid;
|
|
grcDepthStencilStateHandle CShaderLib::ms_gNoDepthWrite_DS = grcStateBlock::DSS_Invalid;
|
|
grcDepthStencilStateHandle CShaderLib::ms_gNoDepthRead_DS = grcStateBlock::DSS_Invalid;
|
|
grcRasterizerStateHandle CShaderLib::ms_frontFaceCulling_RS = grcStateBlock::RS_Invalid;
|
|
grcRasterizerStateHandle CShaderLib::ms_disableFaceCulling_RS = grcStateBlock::RS_Invalid;
|
|
grcDepthStencilStateHandle CShaderLib::DSS_Default_Invert;
|
|
grcDepthStencilStateHandle CShaderLib::DSS_LessEqual_Invert;
|
|
grcDepthStencilStateHandle CShaderLib::DSS_TestOnly_Invert;
|
|
grcDepthStencilStateHandle CShaderLib::DSS_TestOnly_LessEqual_Invert;
|
|
grcBlendStateHandle CShaderLib::BS_NoColorWrite;
|
|
static grcBlendStateHandle previousBS[NUMBER_OF_RENDER_THREADS];
|
|
|
|
#if __DEV
|
|
bool CShaderLib::ms_gReflectTweakEnabled = false;
|
|
float CShaderLib::ms_gReflectTweak = 0.1f;
|
|
bool CShaderLib::ms_gDisableShaderVarCaching = false;
|
|
#endif // __DEV
|
|
|
|
strLocalIndex CShaderLib::ms_txdId = strLocalIndex(-1);
|
|
|
|
#if SHADERLIB_USE_MSAA_PARAMS
|
|
static grcEffectGlobalVar globalTargetAAParamsID;
|
|
#endif // SHADERLIB_USE_MSAA_PARAMS
|
|
|
|
static grcEffectGlobalVar globalAOEffectScaleID;
|
|
static grcEffectGlobalVar globalScreenSizeID; //screensize
|
|
static grcEffectGlobalVar gFogParamsID;
|
|
static grcEffectGlobalVar gFogColorID;
|
|
static grcEffectGlobalVar gFogColorEID;
|
|
static grcEffectGlobalVar gFogColorNID;
|
|
#if LINEAR_PIECEWISE_FOG
|
|
static grcEffectGlobalVar gLinearPiecewiseFogParamsID;
|
|
#endif // LINEAR_PIECEWISE_FOG
|
|
|
|
static grcEffectGlobalVar gReflectionTweaksID;
|
|
static grcEffectGlobalVar gDynamicBakesAndWetnessID;
|
|
|
|
static grcEffectGlobalVar globalPlayerLFootPosID;
|
|
static grcEffectGlobalVar globalPlayerRFootPosID;
|
|
|
|
#if RSG_PC
|
|
static grcEffectGlobalVar gReticuleDistID;
|
|
static grcEffectGlobalVar globalTreesUseDiscardId;
|
|
static grcEffectGlobalVar globalShaderQualityID;
|
|
static grcEffectGlobalVar gStereoParamsID;
|
|
static grcEffectGlobalVar gStereoParams1ID;
|
|
#endif
|
|
|
|
static grcEffectGlobalVar globalUseFogRayId;
|
|
|
|
static grcEffectGlobalVar gFogRayTextureID;
|
|
static grcEffectGlobalVar gFogRayIntensityID;
|
|
|
|
#if DEVICE_MSAA
|
|
static grcEffectGlobalVar globalTransparencyAASamples;
|
|
#endif // DEVICE_MSAA
|
|
|
|
static grcEffectGlobalVar globalAlphaTestRef;
|
|
|
|
#if USE_ALPHAREF
|
|
static grcEffectGlobalVar alphaRefVec0ID = (grcEffectGlobalVar)0;
|
|
static grcEffectGlobalVar alphaRefVec1ID = (grcEffectGlobalVar)0;
|
|
|
|
static s32 global_alphaRef = 90;
|
|
#if HACK_RDR3
|
|
static s32 ped_alphaRef = 0;
|
|
#else
|
|
static s32 ped_alphaRef = 128;
|
|
#endif
|
|
static s32 ped_longhair_alphaRef = 128;
|
|
static s32 foliage_alphaRef = 90; // valve distance-map alpha will use middle value of 0.35 to compensate
|
|
static s32 foliageImposter_alphaRef = 88;
|
|
static s32 billboard_alphaRef = 148;
|
|
static s32 shadowBillboard_alphaRef = 88;
|
|
static s32 grass_alphaRef = 32;
|
|
#endif // USE_ALPHAREF...
|
|
static bool useTransparencyAA = USE_TRANSPARENCYAA;
|
|
static u32 maxStipplingAA = 2;
|
|
|
|
|
|
ThreadVector4 CShaderLib::ms_gCurrentScalarGlobals[NUMBER_OF_RENDER_THREADS] = {{1.0f, 1.0f, 1.0f, 1.0f}};
|
|
u32 CShaderLib::ms_giCurrentScalarGlobals[NUMBER_OF_RENDER_THREADS][4] = {{255, 255, 255, 255}}; //setting to same values as ms_gCurrentScalarGlobals
|
|
ThreadVector4 CShaderLib::ms_gCurrentScalarGlobals2[NUMBER_OF_RENDER_THREADS] = {{1.0f, 1.0f, 1.0f, 1.0f}};
|
|
ThreadVector4 CShaderLib::ms_gCurrentScalarGlobals3[NUMBER_OF_RENDER_THREADS] = {{16.0f,1.0f/16.0f,0.0f,0.0f}};
|
|
ThreadVector4 CShaderLib::ms_gCurrentDirectionalAmbient[NUMBER_OF_RENDER_THREADS] = {{ 0.0f, 0.0f, 0.0f, 0.0f }};
|
|
|
|
|
|
bool CShaderLib::ms_facingBackwards[NUMBER_OF_RENDER_THREADS] = {false};
|
|
bool CShaderLib::ms_fogDepthFxEnabled[NUMBER_OF_RENDER_THREADS] = {true};
|
|
|
|
float CShaderLib::ms_overridesEmissiveScale = 0.0f;
|
|
float CShaderLib::ms_overridesEmissiveMult = 0.0f;
|
|
float CShaderLib::ms_overridesArtIntAmbDown = 0.0f;
|
|
float CShaderLib::ms_overridesArtIntAmbBase = 0.0f;
|
|
float CShaderLib::ms_overridesArtExtAmbDown = 0.0f;
|
|
float CShaderLib::ms_overridesArtExtAmbBase = 0.0f;
|
|
float CShaderLib::ms_overridesArtAmbScale = 0.0f;
|
|
|
|
// Other things are packed into the "unused" W component of these vectors
|
|
CShaderLib::CFogParams CShaderLib::ms_globalFogParams[NUMBER_OF_RENDER_THREADS];
|
|
#if LINEAR_PIECEWISE_FOG
|
|
ThreadVector4 CShaderLib::ms_linearPiecewiseFog[NUMBER_OF_RENDER_THREADS][LINEAR_PIECEWISE_FOG_NUM_SHADER_VARIABLES];
|
|
#endif // LINEAR_PIECEWISE_FOG
|
|
|
|
u32 CShaderLib::ms_gDeferredMaterial[NUMBER_OF_RENDER_THREADS] = { DEFERRED_MATERIAL_DEFAULT };
|
|
u32 CShaderLib::ms_gDeferredMaterialORMask[NUMBER_OF_RENDER_THREADS] = { 0x0 };
|
|
|
|
ThreadVector4 CShaderLib::ms_gCurrentScreenSize[NUMBER_OF_RENDER_THREADS] = { {1.0f, 1.0f, 1.0f, 1.0f} };
|
|
ThreadVector4 CShaderLib::ms_gCurrentAOEffectScale[NUMBER_OF_RENDER_THREADS] = {{1.0f, 1.0f, 1.0f, 1.0f}};
|
|
|
|
bool CShaderLib::ms_gDeferredWetBlend[NUMBER_OF_RENDER_THREADS] = { false };
|
|
|
|
ThreadVector4 CShaderLib::ms_gReflectionTweaks = {1.0f, 1.0f, 1.0f, 0.0f};
|
|
bool CShaderLib::ms_gMotionBlurMask = true;
|
|
|
|
float CShaderLib::ms_alphaTestRef[NUMBER_OF_RENDER_THREADS] = {NUMBER_OF_RENDER_THREADS_INITIALIZER_LIST(0.f)};
|
|
|
|
Vector4 CShaderLib::ms_PlayerLFootPos[2];
|
|
Vector4 CShaderLib::ms_PlayerRFootPos[2];
|
|
ThreadVector4 CShaderLib::ms_gCurrentPlayerLFootPos[NUMBER_OF_RENDER_THREADS] = { {0,0,0,0} };
|
|
ThreadVector4 CShaderLib::ms_gCurrentPlayerRFootPos[NUMBER_OF_RENDER_THREADS] = { {0,0,0,0} };;
|
|
#if RSG_PC
|
|
float CShaderLib::ms_ShaderQuality[2] = {2.0f,2.0f};
|
|
#endif
|
|
|
|
static grcMaterialLibrary *s_MtlLib;
|
|
|
|
#if __PS3
|
|
namespace rage
|
|
{
|
|
extern u32 TotalUcode, TotalUcodeWithoutCache, TotalUcodeInDebugHeap;
|
|
}
|
|
#endif
|
|
namespace rage
|
|
{
|
|
extern u32 TotalReferenceInstanceData;
|
|
}
|
|
|
|
// We do this to minimize the amount of time spent between starting the
|
|
// game and the first draw call. loading the remaining shaders is left
|
|
// until the intro movie is active
|
|
void CShaderLib::LoadInitialShaders()
|
|
{
|
|
grcEffect *effect = NULL;
|
|
ASSET.PushFolder("update2:/common/shaders");
|
|
|
|
effect = grcEffect::Create("im");
|
|
Assert(effect);
|
|
effect = grcEffect::Create("rage_bink");
|
|
Assert(effect);
|
|
effect = grcEffect::Create("scaleform_shaders");
|
|
Assert(effect);
|
|
effect = grcEffect::Create("rage_fastmipmap");
|
|
Assert(effect);
|
|
if( GRCDEVICE.GetMSAA()>1 )
|
|
{
|
|
effect = grcEffect::Create("imMS");
|
|
Assert(effect);
|
|
}
|
|
ASSET.PopFolder();
|
|
}
|
|
|
|
void CShaderLib::LoadAllShaders()
|
|
{
|
|
grmShaderFactory::GetInstance().PreloadShaders("common:/shaders");
|
|
if( GRCDEVICE.GetMSAA()>1 )
|
|
{
|
|
grmShaderFactory::GetInstance().PreloadShaders("common:/shaders","preloadMS");
|
|
}
|
|
#if __ASSERT
|
|
grcEffect::SetAllowShaderLoading(false);
|
|
#endif
|
|
}
|
|
|
|
|
|
void CShaderLib::PreInit()
|
|
{
|
|
ms_globalScalarsID = grcEffect::LookupGlobalVar("globalScalars");
|
|
grcEffect::SetGlobalVar(ms_globalScalarsID, (Vec4V&)ms_gCurrentScalarGlobals[g_RenderThreadIndex]);
|
|
|
|
sysMemUseMemoryBucket b(MEMBUCKET_RENDER);
|
|
|
|
size_t used = sysMemGetMemoryUsed(MEMBUCKET_RENDER);
|
|
|
|
// We need to register all techniques before any shaders get loaded:
|
|
|
|
#if __XENON || __D3D11 || RSG_ORBIS // special-case "ld" being used for local light shadows on 360 ..
|
|
{
|
|
grmShaderFx::RegisterTechniqueGroup("ld");
|
|
grmShaderFx::RegisterTechniqueGroup("shadtexture_ld");
|
|
}
|
|
#endif // __XENON || __D3D11 || RSG_ORBIS
|
|
|
|
// CRenderPhaseCascadeShadows
|
|
grmShaderFx::RegisterTechniqueGroup("wdcascade");
|
|
#if __PPU && USE_EDGE
|
|
grmShaderFx::RegisterTechniqueGroup("wdcascadeedge");
|
|
grmShaderFx::RegisterTechniqueGroup("shadtexture_wdcascadeedge");
|
|
#else // __PPU && USE_EDGE
|
|
grmShaderFx::RegisterTechniqueGroup("shadtexture_wdcascade");
|
|
#endif
|
|
|
|
// CParaboloidShadow
|
|
#if __PPU
|
|
grmShaderFx::RegisterTechniqueGroup("ldpoint"); // xenon uses "ld"
|
|
grmShaderFx::RegisterTechniqueGroup("shadtexture_ldpoint");
|
|
|
|
#if USE_EDGE
|
|
grmShaderFx::RegisterTechniqueGroup("ldedgepoint");
|
|
grmShaderFx::RegisterTechniqueGroup("shadtexture_ldedgepoint");
|
|
#endif // USE_EDGE
|
|
|
|
#endif // __PPU
|
|
|
|
// CRenderPhaseWaterReflection
|
|
grmShaderFx::RegisterTechniqueGroup("waterreflection");
|
|
grmShaderFx::RegisterTechniqueGroup("waterreflectionalphaclip");
|
|
grmShaderFx::RegisterTechniqueGroup("waterreflectionalphacliptint");
|
|
|
|
// CRenderPhaseReflection
|
|
grmShaderFx::RegisterTechniqueGroup("cube");
|
|
#if GS_INSTANCED_CUBEMAP
|
|
grmShaderFx::RegisterTechniqueGroup("cubeinst");
|
|
#endif
|
|
|
|
//Generic
|
|
grmShaderFx::RegisterTechniqueGroup("alt0"); //UnderwaterLowTechniqueGroup
|
|
grmShaderFx::RegisterTechniqueGroup("alt1"); //UnderwaterHighTechniqueGroup
|
|
grmShaderFx::RegisterTechniqueGroup("alt2"); //UnderwaterEnvLowTechniqueGroup
|
|
grmShaderFx::RegisterTechniqueGroup("alt3"); //UnderwaterEnvHighTechniqueGroup
|
|
grmShaderFx::RegisterTechniqueGroup("alt4"); //EnvTechniqueGroup
|
|
grmShaderFx::RegisterTechniqueGroup("alt5"); //SinglePassTechniqueGroup
|
|
grmShaderFx::RegisterTechniqueGroup("alt6"); //SinglePassEnvTechniqueGroup
|
|
grmShaderFx::RegisterTechniqueGroup("alt7"); //FoamTechniqueGrou
|
|
grmShaderFx::RegisterTechniqueGroup("alt8"); //WaterHeightTechniqueGroup
|
|
|
|
// CLights
|
|
grmShaderFx::RegisterTechniqueGroup("lightweight0");
|
|
grmShaderFx::RegisterTechniqueGroup("lightweight4");
|
|
grmShaderFx::RegisterTechniqueGroup("lightweight8");
|
|
grmShaderFx::RegisterTechniqueGroup("lightweight0CutOut");
|
|
grmShaderFx::RegisterTechniqueGroup("lightweight4CutOut");
|
|
grmShaderFx::RegisterTechniqueGroup("lightweight8CutOut");
|
|
|
|
grmShaderFx::RegisterTechniqueGroup("lightweight0CutOutTint");
|
|
grmShaderFx::RegisterTechniqueGroup("lightweight4CutOutTint");
|
|
grmShaderFx::RegisterTechniqueGroup("lightweight8CutOutTint");
|
|
|
|
grmShaderFx::RegisterTechniqueGroup("lightweightNoCapsule4");
|
|
grmShaderFx::RegisterTechniqueGroup("lightweightNoCapsule8");
|
|
|
|
grmShaderFx::RegisterTechniqueGroup("lightweightHighQuality0");
|
|
grmShaderFx::RegisterTechniqueGroup("lightweightHighQuality4");
|
|
grmShaderFx::RegisterTechniqueGroup("lightweightHighQuality8");
|
|
grmShaderFx::RegisterTechniqueGroup("lightweightHighQuality0CutOut");
|
|
grmShaderFx::RegisterTechniqueGroup("lightweightHighQuality4CutOut");
|
|
grmShaderFx::RegisterTechniqueGroup("lightweightHighQuality8CutOut");
|
|
|
|
// CTreeImposters
|
|
grmShaderFx::RegisterTechniqueGroup("imposter");
|
|
grmShaderFx::RegisterTechniqueGroup("imposterdeferred");
|
|
|
|
// CMarkers
|
|
#if __PPU
|
|
grmShaderFx::RegisterTechniqueGroup("manualdepth");
|
|
#endif
|
|
|
|
// CPedVariationMgr
|
|
grmShaderFx::RegisterTechniqueGroup("deferredbs");
|
|
|
|
// DeferredLighting
|
|
grmShaderFx::RegisterTechniqueGroup("deferred");
|
|
grmShaderFx::RegisterTechniqueGroup("deferredalphaclip");
|
|
grmShaderFx::RegisterTechniqueGroup("deferredsubsamplealphaclip");
|
|
grmShaderFx::RegisterTechniqueGroup("deferredalphacliptint");
|
|
grmShaderFx::RegisterTechniqueGroup("deferredsubsamplealpha");
|
|
grmShaderFx::RegisterTechniqueGroup("deferredsubsamplewritealpha");
|
|
grmShaderFx::RegisterTechniqueGroup("deferredcutscene");
|
|
grmShaderFx::RegisterTechniqueGroup("deferredsubsamplealphatint");
|
|
|
|
//Vehicle Fade Override Techniques
|
|
grmShaderFx::RegisterTechniqueGroup("lightweight0WaterRefractionAlpha");
|
|
grmShaderFx::RegisterTechniqueGroup("lightweight4WaterRefractionAlpha");
|
|
grmShaderFx::RegisterTechniqueGroup("lightweight8WaterRefractionAlpha");
|
|
grmShaderFx::RegisterTechniqueGroup("lightweightHighQuality0WaterRefractionAlpha");
|
|
grmShaderFx::RegisterTechniqueGroup("lightweightHighQuality4WaterRefractionAlpha");
|
|
grmShaderFx::RegisterTechniqueGroup("lightweightHighQuality8WaterRefractionAlpha");
|
|
|
|
// RenderPhaseSeeThrough
|
|
grmShaderFx::RegisterTechniqueGroup("seethrough");
|
|
|
|
// UI
|
|
grmShaderFx::RegisterTechniqueGroup("ui");
|
|
|
|
#if ENTITYSELECT_ENABLED_BUILD
|
|
// Entity Select debug technique
|
|
grmShaderFx::RegisterTechniqueGroup("entityselect");
|
|
#endif // ENTITYSELECT_ENABLED_BUILD
|
|
|
|
#if GPU_DAMAGE_WRITE_ENABLED
|
|
// Adding new damage circles to the vehicles' damage texture when collisions occur
|
|
grmShaderFx::RegisterTechniqueGroup("applydamage");
|
|
#endif
|
|
|
|
// for adding clouds to the light rays
|
|
grmShaderFx::RegisterTechniqueGroup("clouddepth");
|
|
|
|
#if __BANK
|
|
// CRenderPhaseDebugOverlay
|
|
grmShaderFx::RegisterTechniqueGroup("debugoverlay");
|
|
#endif // __BANK
|
|
#if __XENON
|
|
MEMORYSTATUS before, after;
|
|
GlobalMemoryStatus(&before);
|
|
#endif
|
|
|
|
#if __ASSERT
|
|
// Assert on late loaded shaders.
|
|
grcEffect::SetAllowShaderLoading(true);
|
|
#endif // __ASSERT
|
|
|
|
LoadInitialShaders();
|
|
|
|
used = sysMemGetMemoryUsed(MEMBUCKET_RENDER) - used;
|
|
|
|
Displayf("CShaderLib::PreInit - %" SIZETFMT "u bytes consumed by inital shader load",used);
|
|
}
|
|
|
|
//
|
|
// name: FullInit
|
|
// description: Initialise shader library.
|
|
void CShaderLib::Init()
|
|
{
|
|
size_t used = sysMemGetMemoryUsed(MEMBUCKET_RENDER);
|
|
|
|
CShaderLib::LoadAllShaders();
|
|
|
|
#if __ASSERT
|
|
// Assert on late loaded shaders.
|
|
grcEffect::SetAllowShaderLoading(false);
|
|
#endif // __ASSERT
|
|
|
|
used = sysMemGetMemoryUsed(MEMBUCKET_RENDER) - used;
|
|
|
|
Displayf("CShaderLib::Init - %" SIZETFMT "u bytes consumed by full shader load",used);
|
|
#if __PS3
|
|
Displayf("CShaderLib::Init - %u bytes in cached shaders, %u if uncached, %u saved (%u in debug heap)",TotalUcode,TotalUcodeWithoutCache,TotalUcodeWithoutCache - TotalUcode,TotalUcodeInDebugHeap);
|
|
#endif
|
|
#if __XENON
|
|
GlobalMemoryStatus(&after);
|
|
Displayf("CShaderLib::Init - %u bytes of physical memory consumed by shaders",before.dwAvailPhys - after.dwAvailPhys);
|
|
#endif
|
|
Displayf("CShaderLib::Init - %u bytes consumed by reference instance data",TotalReferenceInstanceData);
|
|
|
|
s_MtlLib = grcMaterialLibrary::Preload("common:/shaders/db/");
|
|
if (Verifyf(s_MtlLib,"Material library didn't load, you're probably in a world of suck."))
|
|
grcMaterialLibrary::SetCurrent(s_MtlLib);
|
|
|
|
#if NUMBER_OF_RENDER_THREADS > 1
|
|
Assert(g_RenderThreadIndex==0); // make sure we're running on mainRT
|
|
Assert(g_IsSubRenderThread==false);
|
|
|
|
// initialise global vars for render subthreads:
|
|
for(int i=1; i<NUMBER_OF_RENDER_THREADS; i++)
|
|
{
|
|
ms_gCurrentScalarGlobals[i] = ms_gCurrentScalarGlobals[0];
|
|
ms_giCurrentScalarGlobals[i][0] = ms_giCurrentScalarGlobals[0][0];
|
|
ms_giCurrentScalarGlobals[i][1] = ms_giCurrentScalarGlobals[0][1];
|
|
ms_giCurrentScalarGlobals[i][2] = ms_giCurrentScalarGlobals[0][2];
|
|
ms_giCurrentScalarGlobals[i][3] = ms_giCurrentScalarGlobals[0][3];
|
|
|
|
ms_gCurrentScalarGlobals2[i] = ms_gCurrentScalarGlobals2[0];
|
|
ms_gCurrentScalarGlobals3[i] = ms_gCurrentScalarGlobals3[0];
|
|
|
|
ms_gCurrentDirectionalAmbient[i]= ms_gCurrentDirectionalAmbient[0];
|
|
ms_globalFogParams[i] = ms_globalFogParams[0];
|
|
ms_facingBackwards[i] = ms_facingBackwards[0];
|
|
ms_fogDepthFxEnabled[i] = ms_fogDepthFxEnabled[0];
|
|
|
|
ms_gCurrentScreenSize[i] = ms_gCurrentScreenSize[0];
|
|
ms_gCurrentAOEffectScale[i] = ms_gCurrentAOEffectScale[0];
|
|
ms_gDeferredWetBlend[i] = ms_gDeferredWetBlend[0];
|
|
|
|
ms_gDeferredMaterial[i] = ms_gDeferredMaterial[0];
|
|
ms_gDeferredMaterialORMask[i] = ms_gDeferredMaterialORMask[0];
|
|
|
|
ms_gCurrentPlayerLFootPos[i] = ms_gCurrentPlayerLFootPos[0];
|
|
ms_gCurrentPlayerRFootPos[i] = ms_gCurrentPlayerRFootPos[0];
|
|
}
|
|
#endif
|
|
ms_globalScalarsID = grcEffect::LookupGlobalVar("globalScalars");
|
|
grcEffect::SetGlobalVar(ms_globalScalarsID, (Vec4V&)(ms_gCurrentScalarGlobals[g_RenderThreadIndex]));
|
|
|
|
ms_globalScalars2ID= grcEffect::LookupGlobalVar("globalScalars2");
|
|
grcEffect::SetGlobalVar(ms_globalScalars2ID, (Vec4V&)(ms_gCurrentScalarGlobals2[g_RenderThreadIndex]));
|
|
|
|
ms_globalScalars3ID = grcEffect::LookupGlobalVar("globalScalars3");
|
|
grcEffect::SetGlobalVar(ms_globalScalars3ID, (Vec4V&)(ms_gCurrentScalarGlobals3[g_RenderThreadIndex]));
|
|
|
|
globalAOEffectScaleID= grcEffect::LookupGlobalVar("globalAOEffectScale");
|
|
grcEffect::SetGlobalVar(globalAOEffectScaleID, (Vec4V&)(ms_gCurrentAOEffectScale[g_RenderThreadIndex]));
|
|
|
|
globalScreenSizeID= grcEffect::LookupGlobalVar("globalScreenSize");
|
|
grcEffect::SetGlobalVar(globalScreenSizeID, (Vec4V&)(ms_gCurrentScreenSize[g_RenderThreadIndex]));
|
|
|
|
#if SHADERLIB_USE_MSAA_PARAMS
|
|
globalTargetAAParamsID = grcEffect::LookupGlobalVar("gTargetAAParams");
|
|
const IntVector AAParams = {0};
|
|
grcEffect::SetGlobalVar(globalTargetAAParamsID, AAParams);
|
|
#endif // SHADERLIB_USE_MSAA_PARAMS
|
|
|
|
#if DEVICE_MSAA
|
|
#if RSG_PC
|
|
globalTreesUseDiscardId = grcEffect::LookupGlobalVar("gTreesUseDiscard");
|
|
grcEffect::SetGlobalVar(globalTreesUseDiscardId, UsesStippleFades());
|
|
#endif // RSG_PC
|
|
#if USE_TRANSPARENCYAA
|
|
CSettings::eSettingsLevel shaderQuality = CSettingsManager::GetInstance().GetSettings().m_graphics.m_ShaderQuality;
|
|
useTransparencyAA = (shaderQuality >= CSettings::High);
|
|
|
|
globalTransparencyAASamples = grcEffect::LookupGlobalVar("gTransparencyAASamples", shaderQuality != CSettings::Low);
|
|
grcEffect::SetGlobalVar(globalTransparencyAASamples, useTransparencyAA ? (float)GRCDEVICE.GetMSAA() : 0.0f);
|
|
#endif // USE_TRANSPARENCYAA
|
|
#endif // DEVICE_MSAA
|
|
|
|
globalUseFogRayId = grcEffect::LookupGlobalVar("gUseFogRay", RSG_PC ? false : true);
|
|
|
|
gFogParamsID = grcEffect::LookupGlobalVar("globalFogParams");
|
|
grcEffect::SetGlobalVar(gFogParamsID, (Vec4V*)&ms_globalFogParams[g_RenderThreadIndex], sizeof(CFogParams)/sizeof(Vec4V));
|
|
|
|
gFogColorID = grcEffect::LookupGlobalVar("globalFogColor");
|
|
grcEffect::SetGlobalVar(gFogColorID, Vec4V(V_ONE));
|
|
|
|
gFogColorEID = grcEffect::LookupGlobalVar("globalFogColorE");
|
|
grcEffect::SetGlobalVar(gFogColorEID, Vec4V(V_ONE));
|
|
|
|
gFogColorNID = grcEffect::LookupGlobalVar("globalFogColorN");
|
|
grcEffect::SetGlobalVar(gFogColorNID, Vec4V(V_ONE));
|
|
|
|
#if LINEAR_PIECEWISE_FOG
|
|
gLinearPiecewiseFogParamsID = grcEffect::LookupGlobalVar("linearPiecewiseFogParams");
|
|
LinearPiecewiseFog_ShaderParams linearParams; // Default to off.
|
|
SetLinearPiecewiseFogParams(linearParams);
|
|
grcEffect::SetGlobalVar(gLinearPiecewiseFogParamsID, (Vec4V*)ms_linearPiecewiseFog[g_RenderThreadIndex], LINEAR_PIECEWISE_FOG_NUM_SHADER_VARIABLES);
|
|
#endif // LINEAR_PIECEWISE_FOG
|
|
|
|
gReflectionTweaksID = grcEffect::LookupGlobalVar("gReflectionTweaks");
|
|
grcEffect::SetGlobalVar(gReflectionTweaksID, (Vec4V&)(ms_gReflectionTweaks));
|
|
|
|
gDynamicBakesAndWetnessID = grcEffect::LookupGlobalVar("gDynamicBakesAndWetness");
|
|
grcEffect::SetGlobalVar(gDynamicBakesAndWetnessID, Vec4V(V_ONE));
|
|
|
|
#if __XENON
|
|
GRCDEVICE.SetColorExpBiasNow(0);
|
|
#endif
|
|
|
|
#if RSG_PC
|
|
gReticuleDistID = grcEffect::LookupGlobalVar("StereoReticuleDistTexture", (GRCDEVICE.CanUseStereo() && GRCDEVICE.IsStereoEnabled()) ? true : false);
|
|
|
|
globalShaderQualityID = grcEffect::LookupGlobalVar("GlobalShaderQuality", true);
|
|
grcEffect::SetGlobalVar(globalShaderQualityID, ms_ShaderQuality[0]);
|
|
|
|
gStereoParamsID = grcEffect::LookupGlobalVar("gStereoParams", false);
|
|
gStereoParams1ID = grcEffect::LookupGlobalVar("gStereoParams1", false);
|
|
#endif
|
|
|
|
gFogRayTextureID = grcEffect::LookupGlobalVar("FogRayTex", RSG_PC ? false : true);
|
|
gFogRayIntensityID = grcEffect::LookupGlobalVar("gGlobalFogIntensity");
|
|
|
|
globalAlphaTestRef = grcEffect::LookupGlobalVar("alphaTestRef");
|
|
|
|
#if USE_ALPHAREF
|
|
alphaRefVec0ID = grcEffect::LookupGlobalVar("alphaRefVec0");
|
|
alphaRefVec1ID = grcEffect::LookupGlobalVar("alphaRefVec1",false); // This one only exists when certain grass code path are enabled.
|
|
CShaderLib::SetAlphaRefConsts();
|
|
#endif // USE_ALPHAREF...
|
|
|
|
#if !RSG_ORBIS && !RSG_DURANGO
|
|
ms_globalFadeID = grcEffect::LookupGlobalVar("globalFade");
|
|
#endif // !RSG_ORBIS
|
|
|
|
globalPlayerLFootPosID = grcEffect::LookupGlobalVar("gPlayerLFootPos");
|
|
grcEffect::SetGlobalVar(globalPlayerLFootPosID, (Vec4V&)(ms_gCurrentPlayerLFootPos[g_RenderThreadIndex]));
|
|
|
|
globalPlayerRFootPosID = grcEffect::LookupGlobalVar("gPlayerRFootPos");
|
|
grcEffect::SetGlobalVar(globalPlayerRFootPosID, (Vec4V&)(ms_gCurrentPlayerRFootPos[g_RenderThreadIndex]));
|
|
|
|
// initialise state blocks
|
|
|
|
// default depth/stencil block
|
|
grcDepthStencilStateDesc defaultStateDS;
|
|
defaultStateDS.DepthFunc = rage::FixupDepthDirection(grcRSV::CMP_LESSEQUAL);
|
|
defaultStateDS.StencilEnable = 1;
|
|
defaultStateDS.FrontFace.StencilFailOp = grcRSV::STENCILOP_KEEP;
|
|
defaultStateDS.FrontFace.StencilDepthFailOp = grcRSV::STENCILOP_KEEP;
|
|
defaultStateDS.FrontFace.StencilPassOp = grcRSV::STENCILOP_REPLACE;
|
|
defaultStateDS.FrontFace.StencilFunc = grcRSV::CMP_ALWAYS;
|
|
defaultStateDS.BackFace.StencilFailOp = grcRSV::STENCILOP_KEEP;
|
|
defaultStateDS.BackFace.StencilDepthFailOp = grcRSV::STENCILOP_KEEP;
|
|
defaultStateDS.BackFace.StencilPassOp = grcRSV::STENCILOP_REPLACE;
|
|
defaultStateDS.BackFace.StencilFunc = grcRSV::CMP_ALWAYS;
|
|
|
|
ms_gDefaultState_DS = grcStateBlock::CreateDepthStencilState(defaultStateDS);
|
|
|
|
// write depth disabled block
|
|
grcDepthStencilStateDesc noDepthWriteStateDS;
|
|
noDepthWriteStateDS.DepthFunc = rage::FixupDepthDirection(grcRSV::CMP_LESSEQUAL);
|
|
noDepthWriteStateDS.DepthWriteMask = 0;
|
|
noDepthWriteStateDS.StencilEnable = 1;
|
|
noDepthWriteStateDS.FrontFace.StencilFailOp = grcRSV::STENCILOP_KEEP;
|
|
noDepthWriteStateDS.FrontFace.StencilDepthFailOp = grcRSV::STENCILOP_KEEP;
|
|
noDepthWriteStateDS.FrontFace.StencilPassOp = grcRSV::STENCILOP_REPLACE;
|
|
noDepthWriteStateDS.FrontFace.StencilFunc = grcRSV::CMP_ALWAYS;
|
|
noDepthWriteStateDS.BackFace.StencilFailOp = grcRSV::STENCILOP_KEEP;
|
|
noDepthWriteStateDS.BackFace.StencilDepthFailOp = grcRSV::STENCILOP_KEEP;
|
|
noDepthWriteStateDS.BackFace.StencilPassOp = grcRSV::STENCILOP_REPLACE;
|
|
noDepthWriteStateDS.BackFace.StencilFunc = grcRSV::CMP_ALWAYS;
|
|
|
|
ms_gNoDepthWrite_DS = grcStateBlock::CreateDepthStencilState(noDepthWriteStateDS);
|
|
|
|
// write read disabled block
|
|
grcDepthStencilStateDesc noDepthReadStateDS;
|
|
noDepthReadStateDS.DepthFunc = rage::FixupDepthDirection(grcRSV::CMP_ALWAYS);
|
|
noDepthReadStateDS.StencilEnable = 1;
|
|
noDepthReadStateDS.FrontFace.StencilFailOp = grcRSV::STENCILOP_KEEP;
|
|
noDepthReadStateDS.FrontFace.StencilDepthFailOp = grcRSV::STENCILOP_KEEP;
|
|
noDepthReadStateDS.FrontFace.StencilPassOp = grcRSV::STENCILOP_REPLACE;
|
|
noDepthReadStateDS.FrontFace.StencilFunc = grcRSV::CMP_ALWAYS;
|
|
noDepthReadStateDS.BackFace.StencilFailOp = grcRSV::STENCILOP_KEEP;
|
|
noDepthReadStateDS.BackFace.StencilDepthFailOp = grcRSV::STENCILOP_KEEP;
|
|
noDepthReadStateDS.BackFace.StencilPassOp = grcRSV::STENCILOP_REPLACE;
|
|
noDepthReadStateDS.BackFace.StencilFunc = grcRSV::CMP_ALWAYS;
|
|
|
|
ms_gNoDepthRead_DS = grcStateBlock::CreateDepthStencilState(noDepthReadStateDS);
|
|
|
|
grcRasterizerStateDesc faceCullingRS;
|
|
faceCullingRS.CullMode=grcRSV::CULL_FRONT;
|
|
ms_frontFaceCulling_RS = grcStateBlock::CreateRasterizerState(faceCullingRS);
|
|
faceCullingRS.CullMode=grcRSV::CULL_NONE;
|
|
ms_disableFaceCulling_RS = grcStateBlock::CreateRasterizerState(faceCullingRS);
|
|
|
|
grcDepthStencilStateDesc DefaultDepthStencilInvertStateBlockDesc;
|
|
DefaultDepthStencilInvertStateBlockDesc.DepthFunc = rage::FixupDepthDirection(grcRSV::CMP_LESS);
|
|
DSS_Default_Invert = grcStateBlock::CreateDepthStencilState(DefaultDepthStencilInvertStateBlockDesc);
|
|
DefaultDepthStencilInvertStateBlockDesc.DepthFunc = rage::FixupDepthDirection(grcRSV::CMP_LESSEQUAL);
|
|
DSS_LessEqual_Invert = grcStateBlock::CreateDepthStencilState(DefaultDepthStencilInvertStateBlockDesc);
|
|
DefaultDepthStencilInvertStateBlockDesc.DepthWriteMask = false;
|
|
DSS_TestOnly_LessEqual_Invert = grcStateBlock::CreateDepthStencilState(DefaultDepthStencilInvertStateBlockDesc);
|
|
DefaultDepthStencilInvertStateBlockDesc.DepthFunc = rage::FixupDepthDirection(grcRSV::CMP_LESS);
|
|
DSS_TestOnly_Invert = grcStateBlock::CreateDepthStencilState(DefaultDepthStencilInvertStateBlockDesc);
|
|
|
|
grcBlendStateDesc noColorWrite;
|
|
noColorWrite.IndependentBlendEnable = true;
|
|
noColorWrite.BlendRTDesc[0].RenderTargetWriteMask = grcRSV::COLORWRITEENABLE_NONE;
|
|
noColorWrite.BlendRTDesc[1].RenderTargetWriteMask = grcRSV::COLORWRITEENABLE_NONE;
|
|
noColorWrite.BlendRTDesc[2].RenderTargetWriteMask = grcRSV::COLORWRITEENABLE_NONE;
|
|
noColorWrite.BlendRTDesc[3].RenderTargetWriteMask = grcRSV::COLORWRITEENABLE_NONE;
|
|
BS_NoColorWrite = grcStateBlock::CreateBlendState(noColorWrite);
|
|
}// end of CShaderLib::Init()...
|
|
|
|
|
|
//
|
|
// name: Shutdown
|
|
// description: Shutdown shader library.
|
|
void CShaderLib::Shutdown()
|
|
{
|
|
if (s_MtlLib)
|
|
{
|
|
grcMaterialLibrary::SetCurrent(NULL);
|
|
s_MtlLib->Release();
|
|
s_MtlLib = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
void CShaderLib::InitTxd(unsigned initmode)
|
|
{
|
|
if(initmode == INIT_CORE)
|
|
{
|
|
ms_txdId = g_TxdStore.FindSlot(strStreamingObjectName("platform:/textures/graphics",0xA306598));
|
|
Assert(ms_txdId != -1);
|
|
CStreaming::LoadObject(ms_txdId, g_TxdStore.GetStreamingModuleId());
|
|
g_TxdStore.AddRef(ms_txdId, REF_OTHER);
|
|
}
|
|
}
|
|
|
|
void CShaderLib::ShutdownTxd(unsigned shutdownmode)
|
|
{
|
|
if(shutdownmode == SHUTDOWN_CORE)
|
|
{
|
|
g_TxdStore.RemoveRef(ms_txdId, REF_OTHER);
|
|
ms_txdId = -1;
|
|
}
|
|
}
|
|
|
|
//
|
|
// name: InitWidgets
|
|
// description: Creates widgets for shader library
|
|
#if __BANK
|
|
|
|
static bkBank* ms_pShadersBank=NULL;
|
|
static bkButton* ms_pAddShadersWidgetsBtn=NULL;
|
|
|
|
static void AddShaderDbWidgetsOnDemandCB()
|
|
{
|
|
if(ms_pShadersBank)
|
|
{
|
|
// remove old button:
|
|
if(ms_pAddShadersWidgetsBtn)
|
|
{
|
|
ms_pShadersBank->Remove( *((bkWidget*)ms_pAddShadersWidgetsBtn) );
|
|
ms_pAddShadersWidgetsBtn = NULL;
|
|
}
|
|
|
|
// add shaders db buttons:
|
|
if (s_MtlLib)
|
|
s_MtlLib->AddWidgets(*ms_pShadersBank);
|
|
}
|
|
}
|
|
|
|
void CShaderLib::InitWidgets(Static0 BANK_ONLY(shaderReloadCB))
|
|
{
|
|
// add debug widgets
|
|
bkBank& bank = BANKMGR.CreateBank("Shader database");
|
|
ms_pShadersBank = &bank;
|
|
|
|
#if __DEV
|
|
bank.AddToggle("Disable Shader Var Caching", &ms_gDisableShaderVarCaching);
|
|
#endif // __DEV
|
|
bank.PushGroup("Shader Reload", false);
|
|
bank.AddButton("Reload All Shaders", (CFA(shaderReloadCB)));
|
|
bank.PopGroup();
|
|
|
|
#if USE_ALPHAREF
|
|
bank.PushGroup("Alpha Refs", true);
|
|
bank.AddSlider("global_alphaRef", &global_alphaRef, 0, 255, 1);
|
|
bank.AddSlider("ped_alphaRef", &ped_alphaRef, 0, 255, 1);
|
|
bank.AddSlider("ped_longhair_alphaRef", &ped_longhair_alphaRef, 0, 255, 1);
|
|
bank.AddSlider("foliage/trees_alphaRef", &foliage_alphaRef, 0, 255, 1);
|
|
bank.AddSlider("foliageImposter_alphaRef", &foliageImposter_alphaRef, 0, 255, 1);
|
|
bank.AddSlider("billboard_alphaRef", &billboard_alphaRef, 0, 255, 1);
|
|
bank.AddSlider("shadowBillboard_alphaRef", &shadowBillboard_alphaRef, 0, 255, 1);
|
|
bank.AddSlider("grass_alphaRef", &grass_alphaRef, 0, 255, 1);
|
|
bank.PopGroup();
|
|
#endif // USE_ALPHAREF....
|
|
|
|
bank.AddToggle("Use Supersample transparency anti-aliasing (best for true cutout)", &useTransparencyAA);
|
|
bank.AddSlider("Maximum MSAA level that still uses stippling", &maxStipplingAA, 1, 8, 1);
|
|
|
|
ms_pAddShadersWidgetsBtn = bank.AddButton("Activate Shader DB bank(s).", (CFA(AddShaderDbWidgetsOnDemandCB)));
|
|
}
|
|
#endif //__BANK...
|
|
|
|
void CShaderLib::ResetBlendState()
|
|
{
|
|
grcStateBlock::SetBlendState(previousBS[g_RenderThreadIndex], grcStateBlock::ActiveBlendFactors, grcStateBlock::ActiveSampleMask);
|
|
}
|
|
|
|
void CShaderLib::SetGlobals(u8 natAmb, u8 artAmb, bool setAlpha, u32 alpha, bool setStipple,
|
|
bool bInvertStipple, u32 stippleAlpha,
|
|
bool bDontWriteDepth, bool bDontReadDepth, bool bDontWriteColor)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
|
|
if (bDontReadDepth)
|
|
{
|
|
Assertf(!bDontWriteDepth, "No Z read and no Z write not supported");
|
|
grcStateBlock::SetDepthStencilState(ms_gNoDepthRead_DS, ms_gDeferredMaterial[g_RenderThreadIndex]); // need to preserve the stencil ref
|
|
}
|
|
else if (bDontWriteDepth)
|
|
{
|
|
grcStateBlock::SetDepthStencilState(ms_gNoDepthWrite_DS, ms_gDeferredMaterial[g_RenderThreadIndex]); // need to preserve the stencil ref
|
|
}
|
|
|
|
if( bDontWriteColor )
|
|
{
|
|
previousBS[g_RenderThreadIndex] = grcStateBlock::BS_Active;
|
|
grcStateBlock::SetBlendState(BS_NoColorWrite, grcStateBlock::ActiveBlendFactors, grcStateBlock::ActiveSampleMask);
|
|
}
|
|
|
|
bool updateGlobals = false;
|
|
|
|
if (setAlpha && !gDrawListMgr->IsExecutingDrawList(DL_RENDERPHASE_REFLECTION_MAP))
|
|
{
|
|
// Set alpha
|
|
if (ms_giCurrentScalarGlobals[g_RenderThreadIndex][0] != alpha DEV_ONLY(||ms_gDisableShaderVarCaching))
|
|
{
|
|
SetScalarGlobalConstant(0, alpha, CShaderLib::DivideBy255(alpha));
|
|
updateGlobals = true;
|
|
}
|
|
}
|
|
|
|
if( setStipple )
|
|
{
|
|
Assert(!DRAWLISTMGR->IsExecutingWaterReflectionDrawList());
|
|
|
|
SetStippleAlpha(stippleAlpha, bInvertStipple);
|
|
}
|
|
|
|
if (ms_giCurrentScalarGlobals[g_RenderThreadIndex][1] != artAmb || ms_giCurrentScalarGlobals[g_RenderThreadIndex][2] != natAmb DEV_ONLY(||ms_gDisableShaderVarCaching))
|
|
{
|
|
SetScalarGlobalConstant(1, artAmb, CShaderLib::DivideBy255(artAmb));
|
|
SetScalarGlobalConstant(2, natAmb, CShaderLib::DivideBy255(natAmb));
|
|
updateGlobals = true;
|
|
}
|
|
|
|
if (updateGlobals) { grcEffect::SetGlobalVar(ms_globalScalarsID, (Vec4V&)(ms_gCurrentScalarGlobals[g_RenderThreadIndex])); }
|
|
}
|
|
|
|
u16 CShaderLib::GetStippleMask(u32 stippleAlpha, bool
|
|
#if !__D3D11
|
|
bInvertStipple
|
|
#endif
|
|
)
|
|
{
|
|
u16 aaMaskLUT = 0xff;
|
|
stippleAlpha = stippleAlpha & 0xff; //Make sure we don't access out of bounds if alpha is invalid!
|
|
|
|
#if !__D3D11
|
|
if( bInvertStipple )
|
|
{
|
|
aaMaskLUT = ~(ms_aaMaskLut[stippleAlpha >> 3]);
|
|
}
|
|
else
|
|
{
|
|
aaMaskLUT = ms_aaMaskLut[stippleAlpha >> 3];
|
|
}
|
|
#else
|
|
if (!CShaderLib::UsesStippleFades())
|
|
{
|
|
aaMaskLUT = ms_aaMaskLut[stippleAlpha >> 3];
|
|
}
|
|
else
|
|
{
|
|
aaMaskLUT = ms_aaMaskFadeLut[stippleAlpha >> 3];
|
|
}
|
|
#endif // __D3D11
|
|
|
|
return aaMaskLUT;
|
|
}
|
|
|
|
void CShaderLib::SetStippleAlpha(u32 stippleAlpha, bool bInvertStipple)
|
|
{
|
|
// State block path, set the current BS block with a new reference.
|
|
#if RSG_ORBIS || RSG_DURANGO
|
|
u64 sampleMask = ComputeSampleMask(stippleAlpha);
|
|
if (bInvertStipple)
|
|
sampleMask = ~sampleMask;
|
|
|
|
grcStateBlock::SetBlendState(grcStateBlock::BS_Active, grcStateBlock::ActiveBlendFactors, sampleMask);
|
|
#else
|
|
if (!CShaderLib::UsesStippleFades())
|
|
{
|
|
u64 sampleMask = ComputeSampleMask(stippleAlpha);
|
|
if (bInvertStipple)
|
|
sampleMask = ~sampleMask;
|
|
|
|
grcStateBlock::SetBlendState(grcStateBlock::BS_Active, grcStateBlock::ActiveBlendFactors, sampleMask);
|
|
# if MSAA_EDGE_PROCESS_FADING
|
|
const u64 activeMask = (1<<GRCDEVICE.GetMSAA()) - 1;
|
|
if (GBuffer::IsRenderingTo() && (sampleMask & activeMask) != activeMask && DeferredLighting::IsEdgeFadeProcessingActive())
|
|
{
|
|
grcStateBlock::SetDepthStencilState(grcStateBlock::DSS_Active, grcStateBlock::ActiveStencilRef | EDGE_FLAG);
|
|
}
|
|
# endif //MSAA_EDGE_PROCESS_FADING
|
|
}
|
|
else
|
|
{
|
|
grcStateBlock::SetBlendState(grcStateBlock::BS_Active, grcStateBlock::ActiveBlendFactors, ~0ULL);
|
|
|
|
u16 fadeMask = ms_aaMaskFadeLut[stippleAlpha >> 3];
|
|
|
|
if (bInvertStipple)
|
|
fadeMask = ~fadeMask;
|
|
|
|
int u32FadeMask[4] =
|
|
{ (fadeMask >> 0) & 0xf,
|
|
(fadeMask >> 4) & 0xf,
|
|
(fadeMask >> 8) & 0xf,
|
|
(fadeMask >> 12) & 0xf
|
|
};
|
|
|
|
Vec4V vectorFadeMask( ((float)u32FadeMask[0])/15.0f, ((float)u32FadeMask[1])/15.0f, ((float)u32FadeMask[2])/15.0f, ((float)u32FadeMask[3])/15.0f );
|
|
|
|
ms_FadeMask16 = fadeMask;
|
|
grcEffect::SetGlobalVar(ms_globalFadeID,vectorFadeMask);
|
|
}
|
|
#endif // RSG_ORBIS || RSG_DURANGO
|
|
}
|
|
|
|
bool CShaderLib::UsesStippleFades()
|
|
{
|
|
return GRCDEVICE.GetMSAA() <= maxStipplingAA;
|
|
}
|
|
|
|
void CShaderLib::SetScreenDoorAlpha(bool setAlpha, u32 alpha, bool setStipple, bool bInvertStipple, u32 stippleAlpha, bool bDontWriteDepth)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
|
|
if (bDontWriteDepth)
|
|
{
|
|
grcStateBlock::SetDepthStencilState(ms_gNoDepthWrite_DS, ms_gDeferredMaterial[g_RenderThreadIndex]); // need to preserve the stencil ref
|
|
}
|
|
|
|
bool updateGlobals = false;
|
|
|
|
if (setAlpha)
|
|
{
|
|
// Set alpha
|
|
if (ms_giCurrentScalarGlobals[g_RenderThreadIndex][0] != alpha DEV_ONLY(||ms_gDisableShaderVarCaching))
|
|
{
|
|
SetScalarGlobalConstant(0, alpha, CShaderLib::DivideBy255(alpha));
|
|
updateGlobals = true;
|
|
}
|
|
}
|
|
|
|
if( setStipple )
|
|
{
|
|
Assert(!DRAWLISTMGR->IsExecutingWaterReflectionDrawList());
|
|
|
|
SetStippleAlpha(stippleAlpha, bInvertStipple);
|
|
}
|
|
|
|
if (updateGlobals) { grcEffect::SetGlobalVar(ms_globalScalarsID, (Vec4V&)(ms_gCurrentScalarGlobals[g_RenderThreadIndex])); }
|
|
}
|
|
|
|
|
|
void CShaderLib::ResetAlpha(bool resetAlpha, bool resetStipple)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
|
|
bool updateGlobals = false;
|
|
|
|
if( resetAlpha )
|
|
{
|
|
// Set alpha
|
|
updateGlobals = ms_giCurrentScalarGlobals[g_RenderThreadIndex][0] != 255;
|
|
SetScalarGlobalConstant(0, 255, 1.0f);
|
|
}
|
|
|
|
if( resetStipple )
|
|
{
|
|
// State block path, set the current BS block with a new reference.
|
|
grcStateBlock::SetBlendState(grcStateBlock::BS_Active, grcStateBlock::ActiveBlendFactors, ~0ULL);
|
|
|
|
#if RSG_PC
|
|
if (CShaderLib::UsesStippleFades())
|
|
{
|
|
u16 fadeMask = 0xFFFF;
|
|
int u32FadeMask[4] =
|
|
{ (fadeMask >> 0) & 0xf,
|
|
(fadeMask >> 4) & 0xf,
|
|
(fadeMask >> 8) & 0xf,
|
|
(fadeMask >> 12) & 0xf
|
|
};
|
|
|
|
Vec4V vectorFadeMask( ((float)u32FadeMask[0])/15.0f, ((float)u32FadeMask[1])/15.0f, ((float)u32FadeMask[2])/15.0f, ((float)u32FadeMask[3])/15.0f );
|
|
|
|
ms_FadeMask16 = fadeMask;
|
|
grcEffect::SetGlobalVar(ms_globalFadeID,vectorFadeMask);
|
|
}
|
|
# if MSAA_EDGE_PROCESS_FADING
|
|
else if (GBuffer::IsRenderingTo())
|
|
{
|
|
grcStateBlock::SetDepthStencilState(grcStateBlock::DSS_Active, grcStateBlock::ActiveStencilRef & ~EDGE_FLAG);
|
|
}
|
|
# endif // MSAA_EDGE_PROCESS_FADING
|
|
#endif // RSG_PC
|
|
}
|
|
|
|
if (updateGlobals) { grcEffect::SetGlobalVar(ms_globalScalarsID, (Vec4V&)(ms_gCurrentScalarGlobals[g_RenderThreadIndex])); }
|
|
}
|
|
|
|
u64 eqaa1NSampleMask[32] =
|
|
{
|
|
0x0000000000000000, // 0x0000,
|
|
0x0000000000000000, // 0x0000,
|
|
0x0000000000000001, // 0x000F,
|
|
0x0000000000000001, // 0x000F,
|
|
0x0000000000000003, // 0x000F,
|
|
0x0000000000000003, // 0x000F,
|
|
0x0000000000000005, // 0x000F,
|
|
0x0000000000000005, // 0x000F,
|
|
0x0000000000000007, // 0x000F,
|
|
0x0000000000000007, // 0x000F,
|
|
0x000000000000000F, // 0x000F,
|
|
0x000100000000000F, // 0xF00F,
|
|
0x000100000000000F, // 0xF00F,
|
|
0x000300000000000F, // 0xF00F,
|
|
0x000300000000000F, // 0xF00F,
|
|
0x000500000000000F, // 0xF00F,
|
|
0x000500000000000F, // 0xF00F,
|
|
0x000700000000000F, // 0xF00F,
|
|
0x000700000000000F, // 0xF00F,
|
|
0x000F00000000000F, // 0xF00F,
|
|
0x000F00000001000F, // 0xF0FF,
|
|
0x000F00000003000F, // 0xF0FF,
|
|
0x000F00000005000F, // 0xF0FF,
|
|
0x000F00000005000F, // 0xF0FF,
|
|
0x000F00000007000F, // 0xF0FF,
|
|
0x000F0000000F000F, // 0xF0FF,
|
|
0xFFFFFFFFFFFFFFFF, // 0xFFFF, // Pushing full on FFFFFF's so that the hardware gets a chance to not disable any early Z optimisations.
|
|
0xFFFFFFFFFFFFFFFF, // 0xFFFF,
|
|
0xFFFFFFFFFFFFFFFF, // 0xFFFF,
|
|
0xFFFFFFFFFFFFFFFF, // 0xFFFF,
|
|
0xFFFFFFFFFFFFFFFF, // 0xFFFF,
|
|
0xFFFFFFFFFFFFFFFF, // 0xFFFF,
|
|
};
|
|
|
|
// This is just used for MSAA fade. The other is used for FadeDiscard() in shader on PC.
|
|
u16 CShaderLib::ms_aaMaskLut[32] = {
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x01, 0x01, 0x01, 0x01 ,
|
|
0x01, 0x01, 0x01, 0x01 ,
|
|
0x05, 0x05, 0x05, 0x05 ,
|
|
0x05, 0x05, 0x05, 0x05 ,
|
|
0x0d, 0x0d, 0x0d, 0x0d ,
|
|
0x0d, 0x0d, 0x0d, 0x0d ,
|
|
0x0f, 0x0f, 0x0f, 0x0f
|
|
|
|
};
|
|
|
|
u16 CShaderLib::ms_aaMaskFadeLut[32] = {
|
|
0x0000, 0x0000,
|
|
0x000F, 0x000F, 0x000F,
|
|
0x000F, 0x000F, 0x000F,
|
|
0x000F, 0x000F, 0x000F,
|
|
0xF00F, 0xF00F, 0xF00F,
|
|
0xF00F, 0xF00F, 0xF00F,
|
|
0xF00F, 0xF00F, 0xF00F,
|
|
0xF0FF, 0xF0FF, 0xF0FF,
|
|
0xF0FF, 0xF0FF, 0xF0FF,
|
|
0xFFFF, 0xFFFF, 0xFFFF,
|
|
0xFFFF, 0xFFFF, 0xFFFF,
|
|
};
|
|
|
|
u64 CShaderLib::ComputeSampleMask(u32 stippleAlpha)
|
|
{
|
|
// numSamples is different form numFragments if EQAA is enabled
|
|
#if DEVICE_EQAA
|
|
const u32 numSamples = GRCDEVICE.GetMSAA().m_uSamples;
|
|
const u32 numFragments = GRCDEVICE.GetMSAA().m_uFragments;
|
|
#else
|
|
const u32 numSamples = GRCDEVICE.GetMSAA();
|
|
const u32 numFragments = numSamples;
|
|
#endif // DEVICE_EQAA
|
|
|
|
u64 sampleMask = ~0x0UL;
|
|
u32 baseMask = ~0x0U;
|
|
if( (numFragments == 1 && numSamples != numFragments)
|
|
#if RSG_ORBIS || RSG_DURANGO
|
|
|| numFragments == 0
|
|
#endif // RSG_ORBIS || RSG_DURANGO
|
|
)
|
|
{ // EQAA 1/N, we need to go special..
|
|
return eqaa1NSampleMask[stippleAlpha >> 3];
|
|
}
|
|
else
|
|
{
|
|
// the mask is designed for MSAA-4, hence we modify it
|
|
const u32 origMask = ms_aaMaskLut[stippleAlpha >> 3];
|
|
Assert( origMask < 0x10 );
|
|
switch (numSamples)
|
|
{
|
|
case 2: baseMask = origMask>>2; break;
|
|
case 4: baseMask = origMask; break;
|
|
case 8: baseMask = origMask * 0x11; break;
|
|
case 16:baseMask = origMask * 0x1111; break;
|
|
default: baseMask = ~0x0U; break;
|
|
}
|
|
|
|
sampleMask = (((u64)baseMask & 0xFFFF)<<48) | (((u64)baseMask & 0xFFFF)<<32) | (((u64)baseMask & 0xFFFF)<<16) | (((u64)baseMask & 0xFFFF));
|
|
}
|
|
|
|
return sampleMask;
|
|
}
|
|
|
|
|
|
void CShaderLib::SetGlobalAlpha(float alpha)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
|
|
if (ms_gCurrentScalarGlobals[g_RenderThreadIndex].x!=alpha DEV_ONLY(||ms_gDisableShaderVarCaching))
|
|
{
|
|
SetScalarGlobalConstant(0, (u32)(alpha * 255.0f), alpha);
|
|
grcEffect::SetGlobalVar(ms_globalScalarsID, (Vec4V&)(ms_gCurrentScalarGlobals[g_RenderThreadIndex]));
|
|
}
|
|
}
|
|
|
|
void CShaderLib::SetAlphaTestRef(float alphaTestRef)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
const unsigned rti = g_RenderThreadIndex;
|
|
if (ms_alphaTestRef[rti]!=alphaTestRef DEV_ONLY(||ms_gDisableShaderVarCaching))
|
|
{
|
|
ms_alphaTestRef[rti] = alphaTestRef;
|
|
grcEffect::SetGlobalVar(globalAlphaTestRef, alphaTestRef);
|
|
}
|
|
}
|
|
|
|
float CShaderLib::GetAlphaTestRef()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
return ms_alphaTestRef[g_RenderThreadIndex];
|
|
}
|
|
|
|
void CShaderLib::SetGlobalEmissiveScale(float emissiveScale, bool ignoreDisable)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
|
|
if( !ignoreDisable && CRenderer::GetDisableArtificialLights() )
|
|
{
|
|
emissiveScale = GetOverridesEmissiveScale();
|
|
}
|
|
|
|
if (ms_gCurrentScalarGlobals[g_RenderThreadIndex].w!=emissiveScale DEV_ONLY(||ms_gDisableShaderVarCaching))
|
|
{
|
|
SetScalarGlobalConstant(3, (u32)(emissiveScale * 255.0f), emissiveScale);
|
|
grcEffect::SetGlobalVar(ms_globalScalarsID, (Vec4V&)(ms_gCurrentScalarGlobals[g_RenderThreadIndex]));
|
|
}
|
|
}
|
|
|
|
float CShaderLib::GetGlobalEmissiveScale()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
return ms_gCurrentScalarGlobals[g_RenderThreadIndex].w;
|
|
}
|
|
|
|
void CShaderLib::SetGlobalNaturalAmbientScale(float ambScale)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
if (ms_gCurrentScalarGlobals[g_RenderThreadIndex].z!=ambScale DEV_ONLY(||ms_gDisableShaderVarCaching))
|
|
{
|
|
SetScalarGlobalConstant(2, (u32)(ambScale * 255.0f), ambScale);
|
|
grcEffect::SetGlobalVar(ms_globalScalarsID, (Vec4V&)(ms_gCurrentScalarGlobals[g_RenderThreadIndex]));
|
|
}
|
|
}
|
|
|
|
float CShaderLib::GetGlobalNaturalAmbientScale()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
return ms_gCurrentScalarGlobals[g_RenderThreadIndex].z;
|
|
}
|
|
|
|
void CShaderLib::SetGlobalArtificialAmbientScale(float ambScale)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
if (ms_gCurrentScalarGlobals[g_RenderThreadIndex].y!=ambScale DEV_ONLY(||ms_gDisableShaderVarCaching))
|
|
{
|
|
SetScalarGlobalConstant(1, (u32)(ambScale * 255.0f), ambScale);
|
|
grcEffect::SetGlobalVar(ms_globalScalarsID, (Vec4V&)(ms_gCurrentScalarGlobals[g_RenderThreadIndex]));
|
|
}
|
|
}
|
|
|
|
float CShaderLib::GetGlobalArtificialAmbientScale()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
return ms_gCurrentScalarGlobals[g_RenderThreadIndex].y;
|
|
}
|
|
|
|
|
|
void CShaderLib::SetGlobalTimer(float time)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
if (ms_gCurrentScalarGlobals2[g_RenderThreadIndex].x != time DEV_ONLY(||ms_gDisableShaderVarCaching))
|
|
{
|
|
SetScalarGlobalConstant2(0, time);
|
|
grcEffect::SetGlobalVar(ms_globalScalars2ID, (Vec4V&)(ms_gCurrentScalarGlobals2[g_RenderThreadIndex]));
|
|
}
|
|
}
|
|
|
|
void CShaderLib::SetGlobalInInterior(bool inInterior)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
float inInteriorf = (inInterior) ? 1.0f : 0.0f;
|
|
SetScalarGlobalConstant2(2, inInteriorf);
|
|
grcEffect::SetGlobalVar(ms_globalScalars2ID, (Vec4V&)(ms_gCurrentScalarGlobals2[g_RenderThreadIndex]));
|
|
}
|
|
|
|
bool CShaderLib::GetGlobalInInterior()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
return (ms_gCurrentScalarGlobals2[g_RenderThreadIndex].z == 1.0f);
|
|
}
|
|
|
|
void CShaderLib::SetGlobalAmbientOcclusionEffect(const Vector4 &ambEffect)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
if (ms_gCurrentAOEffectScale[g_RenderThreadIndex].x!=ambEffect.x || ms_gCurrentAOEffectScale[g_RenderThreadIndex].y!=ambEffect.y || ms_gCurrentAOEffectScale[g_RenderThreadIndex].z!=ambEffect.z || ms_gCurrentAOEffectScale[g_RenderThreadIndex].w!=ambEffect.w DEV_ONLY(||ms_gDisableShaderVarCaching))
|
|
{
|
|
SetCurrentAOEffectScale(ambEffect);
|
|
grcEffect::SetGlobalVar(globalAOEffectScaleID, (Vec4V&)(ms_gCurrentAOEffectScale[g_RenderThreadIndex]));
|
|
}
|
|
}
|
|
|
|
void CShaderLib::SetGlobalPedRimLightScale(float rimScale)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
|
|
if (ms_gCurrentScalarGlobals2[g_RenderThreadIndex].w!=rimScale DEV_ONLY(||ms_gDisableShaderVarCaching))
|
|
{
|
|
SetScalarGlobalConstant2(3, rimScale);
|
|
grcEffect::SetGlobalVar(ms_globalScalars2ID, (Vec4V&)(ms_gCurrentScalarGlobals2[g_RenderThreadIndex]));
|
|
}
|
|
}
|
|
|
|
void CShaderLib::SetGlobalToneMapScalers(const Vector4& scalers)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
SetScalarGlobalConstant3(scalers);
|
|
grcEffect::SetGlobalVar(ms_globalScalars3ID, (Vec4V&)(ms_gCurrentScalarGlobals3[g_RenderThreadIndex]));
|
|
}
|
|
|
|
Vector4 CShaderLib::GetGlobalToneMapScalers()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
return ms_gCurrentScalarGlobals3[g_RenderThreadIndex].asVector4();
|
|
}
|
|
|
|
void CShaderLib::SetGlobalScreenSize(const Vector2& screenSize)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
if (ms_gCurrentScreenSize[g_RenderThreadIndex].x!=screenSize.x || ms_gCurrentScreenSize[g_RenderThreadIndex].y!=screenSize.y DEV_ONLY(||ms_gDisableShaderVarCaching))
|
|
{
|
|
SetCurrentScreenSize(screenSize);
|
|
grcEffect::SetGlobalVar(globalScreenSizeID, (Vec4V&)(ms_gCurrentScreenSize[g_RenderThreadIndex]));
|
|
}
|
|
}
|
|
|
|
void CShaderLib::SetPlayerFeetPos(const Vector4& LFootPos, const Vector4& RFootPos)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
|
|
const u8 rtIdx = g_RenderThreadIndex;
|
|
|
|
if (ms_gCurrentPlayerLFootPos[rtIdx].x!=LFootPos.x ||
|
|
ms_gCurrentPlayerLFootPos[rtIdx].y!=LFootPos.y ||
|
|
ms_gCurrentPlayerLFootPos[rtIdx].z!=LFootPos.z DEV_ONLY(||ms_gDisableShaderVarCaching))
|
|
{
|
|
SetCurrentPlayerLFootPos(LFootPos);
|
|
grcEffect::SetGlobalVar(globalPlayerLFootPosID, (Vec4V&)(ms_gCurrentPlayerLFootPos[rtIdx]));
|
|
}
|
|
|
|
if (ms_gCurrentPlayerRFootPos[rtIdx].x!=RFootPos.x ||
|
|
ms_gCurrentPlayerRFootPos[rtIdx].y!=RFootPos.y ||
|
|
ms_gCurrentPlayerRFootPos[rtIdx].z!=RFootPos.z DEV_ONLY(||ms_gDisableShaderVarCaching))
|
|
{
|
|
SetCurrentPlayerRFootPos(RFootPos);
|
|
grcEffect::SetGlobalVar(globalPlayerRFootPosID, (Vec4V&)(ms_gCurrentPlayerRFootPos[rtIdx]));
|
|
}
|
|
}
|
|
|
|
#if SHADERLIB_USE_MSAA_PARAMS
|
|
void CShaderLib::SetMSAAParams(const grcDevice::MSAAMode &mode, bool colorDecoding)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
#if DEVICE_EQAA
|
|
if (mode.m_uFragments == 1)
|
|
{
|
|
colorDecoding = false; // nothing to decode
|
|
}
|
|
// modePure is the one of Gbuffers[1,2,3],
|
|
// required to compute a secondary fragment shift
|
|
grcDevice::MSAAMode modePure = mode;
|
|
if (GBUFFER_REDUCED_COVERAGE)
|
|
{
|
|
modePure.DisableCoverage();
|
|
}
|
|
const IntVector AAParams = {
|
|
mode.m_uSamples, mode.m_uFragments,
|
|
colorDecoding*mode.GetFmaskShift(),
|
|
colorDecoding*modePure.GetFmaskShift()
|
|
};
|
|
#else
|
|
(void)colorDecoding;
|
|
const IntVector AAParams = {mode,mode,0,0};
|
|
#endif //DEVICE_EQAA
|
|
grcEffect::SetGlobalVar(globalTargetAAParamsID, AAParams);
|
|
|
|
#if !RSG_ORBIS && !RSG_DURANGO
|
|
const Vec4V vectorFadeMask(1.0f, 1.0f, 1.0f, 1.0f);
|
|
ms_FadeMask16 = 0xFFFF;
|
|
grcEffect::SetGlobalVar(ms_globalFadeID,vectorFadeMask);
|
|
#endif // !RSG_ORBIS
|
|
|
|
#if USE_TRANSPARENCYAA
|
|
grcEffect::SetGlobalVar(globalTransparencyAASamples, useTransparencyAA ? (float)GRCDEVICE.GetMSAA() : 0.0f);
|
|
#endif
|
|
}
|
|
#endif // SHADERLIB_USE_MSAA_PARAMS
|
|
|
|
void CShaderLib::SetTreesParams()
|
|
{
|
|
#if DEVICE_MSAA && RSG_PC
|
|
grcEffect::SetGlobalVar(globalTreesUseDiscardId, UsesStippleFades());
|
|
#endif
|
|
}
|
|
|
|
void CShaderLib::SetUseFogRay(bool bUse)
|
|
{
|
|
grcEffect::SetGlobalVar(globalUseFogRayId, bUse);
|
|
}
|
|
|
|
void CShaderLib::UpdateGlobalDevScreenSize()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
Vector2 screenSize=Vector2(GRCDEVICE.GetWidth()*1.0f, GRCDEVICE.GetHeight()*1.0f);
|
|
CShaderLib::SetGlobalScreenSize(screenSize);
|
|
}
|
|
|
|
void CShaderLib::UpdateGlobalGameScreenSize()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
Vector2 screenSize=Vector2(VideoResManager::GetSceneWidth()*1.0f, VideoResManager::GetSceneHeight()*1.0f);
|
|
CShaderLib::SetGlobalScreenSize(screenSize);
|
|
}
|
|
|
|
|
|
void CShaderLib::DisableGlobalFogAndDepthFx()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
Assert(ms_fogDepthFxEnabled[g_RenderThreadIndex]==true);
|
|
|
|
CFogParams fogParams;
|
|
fogParams.vFogParams[0].Setf(1000.0f, 2000.0f, 0.0f, ms_facingBackwards[g_RenderThreadIndex] ? 1.f : 0.f);
|
|
fogParams.vFogParams[1].Setf(0,0,0,0);
|
|
fogParams.vFogParams[2].Setf(0.f, 0.f, 0.f, 0.0f);
|
|
// Send setting for no-fog, but maintain the original settings.
|
|
grcEffect::SetGlobalVar(gFogParamsID, (Vec4V*)&fogParams, sizeof(CFogParams)/sizeof(Vec4V));
|
|
|
|
#if LINEAR_PIECEWISE_FOG
|
|
LinearPiecewiseFog_ShaderParams linearParams; // Default is off.
|
|
SetLinearPiecewiseFogParams(linearParams);
|
|
#endif // LINEAR_PIECEWISE_FOG
|
|
|
|
if(!g_IsSubRenderThread)
|
|
for(int i=0; i<NUMBER_OF_RENDER_THREADS; i++)
|
|
ms_fogDepthFxEnabled[i] = false;
|
|
else
|
|
ms_fogDepthFxEnabled[g_RenderThreadIndex] = false;
|
|
}
|
|
|
|
void CShaderLib::EnableGlobalFogAndDepthFx()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
Assert(ms_fogDepthFxEnabled[g_RenderThreadIndex]==false);
|
|
|
|
if(!g_IsSubRenderThread)
|
|
for(int i=0; i<NUMBER_OF_RENDER_THREADS; i++)
|
|
ms_fogDepthFxEnabled[i] = true;
|
|
else
|
|
ms_fogDepthFxEnabled[g_RenderThreadIndex] = true;
|
|
|
|
CShaderLib::ResendCurrentFogSettings();
|
|
}
|
|
|
|
void CShaderLib::SetGlobalFogParams(const CFogParams &fogParams)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
const float facing = ms_facingBackwards[g_RenderThreadIndex] ? 1.f : 0.f ;
|
|
|
|
ms_globalFogParams[g_RenderThreadIndex] = fogParams;
|
|
ms_globalFogParams[g_RenderThreadIndex].vFogParams[0].SetW(facing);
|
|
|
|
if(!g_IsSubRenderThread)
|
|
{
|
|
for(int i=0; i<NUMBER_OF_RENDER_THREADS; i++)
|
|
{
|
|
ms_globalFogParams[i] = fogParams;
|
|
ms_globalFogParams[i].vFogParams[0].SetW(facing);
|
|
}
|
|
}
|
|
|
|
if (ms_fogDepthFxEnabled[g_RenderThreadIndex]==false)
|
|
return;
|
|
|
|
grcEffect::SetGlobalVar(gFogParamsID, (Vec4V*)&ms_globalFogParams[g_RenderThreadIndex], sizeof(CFogParams)/sizeof(Vec4V));
|
|
}
|
|
|
|
void CShaderLib::SetFacingBackwards( bool facingBackwards)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
|
|
ms_facingBackwards[g_RenderThreadIndex] = facingBackwards;
|
|
const float facing = facingBackwards ? 1.f : 0.f;
|
|
ms_globalFogParams[g_RenderThreadIndex].vFogParams[0].SetW(facing);
|
|
|
|
if(!g_IsSubRenderThread)
|
|
{
|
|
for(int i=0; i<NUMBER_OF_RENDER_THREADS; i++)
|
|
{
|
|
ms_facingBackwards[i] = facingBackwards;
|
|
ms_globalFogParams[i].vFogParams[0].SetW(facing);
|
|
}
|
|
}
|
|
|
|
if (ms_fogDepthFxEnabled[g_RenderThreadIndex]==false)
|
|
return;
|
|
|
|
grcEffect::SetGlobalVar(gFogParamsID, VECTOR4_TO_VEC4V(ms_globalFogParams[g_RenderThreadIndex].vFogParams[0].asVector4()));
|
|
}
|
|
|
|
|
|
void CShaderLib::ResendCurrentFogSettings()
|
|
{
|
|
CFogParams fogParams = ms_globalFogParams[g_RenderThreadIndex];
|
|
SetGlobalFogParams(fogParams);
|
|
}
|
|
|
|
|
|
void CShaderLib::SetGlobalFogColors(Vec3V_In vFogColorSun, Vec3V_In vFogColorAtmosphere, Vec3V_In vFogColorGround, Vec3V_In vFogColorHaze, Vec3V_In vFogColorMoon)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
|
|
Vec4V params[4];
|
|
params[0] = Vec4V(vFogColorSun, vFogColorHaze.GetX());
|
|
params[1] = Vec4V(vFogColorAtmosphere, vFogColorHaze.GetY());
|
|
params[2] = Vec4V(vFogColorGround, vFogColorHaze.GetZ());
|
|
params[3] = Vec4V(vFogColorMoon, ScalarV(0.0f));
|
|
|
|
if (ms_fogDepthFxEnabled[g_RenderThreadIndex]==false)
|
|
return;
|
|
|
|
grcEffect::SetGlobalVar(gFogColorID, params, 4);
|
|
}
|
|
|
|
|
|
#if LINEAR_PIECEWISE_FOG
|
|
void CShaderLib::SetLinearPiecewiseFogParams(const class LinearPiecewiseFog_ShaderParams &fogParams)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
|
|
for(int i=0; i<LINEAR_PIECEWISE_FOG_NUM_SHADER_VARIABLES; i++)
|
|
(Vec4V&)(ms_linearPiecewiseFog[g_RenderThreadIndex][i]) = fogParams.shaderParams[i];
|
|
|
|
if(!g_IsSubRenderThread)
|
|
{
|
|
for(int threadIdx=0; threadIdx<NUMBER_OF_RENDER_THREADS; threadIdx++)
|
|
{
|
|
for(int i=0; i<LINEAR_PIECEWISE_FOG_NUM_SHADER_VARIABLES; i++)
|
|
(Vec4V&)(ms_linearPiecewiseFog[threadIdx][i]) = fogParams.shaderParams[i];
|
|
}
|
|
}
|
|
|
|
if (ms_fogDepthFxEnabled[g_RenderThreadIndex]==false)
|
|
return;
|
|
|
|
grcEffect::SetGlobalVar(gLinearPiecewiseFogParamsID, (Vec4V*)ms_linearPiecewiseFog[g_RenderThreadIndex], LINEAR_PIECEWISE_FOG_NUM_SHADER_VARIABLES);
|
|
|
|
}
|
|
#endif // LINEAR_PIECEWISE_FOG
|
|
|
|
|
|
void CShaderLib::SetGlobalReflectionCamDirAndEmissiveMult(const Vector3 &dir, const float emissiveMult)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_UPDATE));
|
|
float actualEmissiveMult = CRenderer::GetDisableArtificialLights() ? GetOverridesEmissiveMult() : emissiveMult;
|
|
ms_gReflectionTweaks.Setf(dir.x, dir.y, dir.z, actualEmissiveMult);
|
|
}
|
|
|
|
void CShaderLib::ApplyGlobalReflectionTweaks()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
Vector4 reflectionTweaks = ms_gReflectionTweaks.asVector4();
|
|
grcEffect::SetGlobalVar(gReflectionTweaksID, (Vec4V&)(reflectionTweaks));
|
|
}
|
|
|
|
void CShaderLib::SetGlobalDynamicBakeBoostAndWetness(Vec4V_In bakeParams)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
grcEffect::SetGlobalVar(gDynamicBakesAndWetnessID, bakeParams);
|
|
}
|
|
|
|
//
|
|
//
|
|
// Ingame Day/Night balance:
|
|
// 1.0 = full day
|
|
// 0.0 = full night
|
|
//
|
|
void CShaderLib::ApplyDayNightBalance()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
|
|
const float dayNightBalance = g_timeCycle.GetCurrDayNightBalance();
|
|
|
|
if (ms_gCurrentScalarGlobals2[g_RenderThreadIndex].y != dayNightBalance DEV_ONLY(||ms_gDisableShaderVarCaching))
|
|
{
|
|
SetScalarGlobalConstant2(1, dayNightBalance);
|
|
grcEffect::SetGlobalVar(ms_globalScalars2ID, (Vec4V&)(ms_gCurrentScalarGlobals2[g_RenderThreadIndex]));
|
|
}
|
|
}
|
|
|
|
float CShaderLib::GetDayNightBalance()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
return(ms_gCurrentScalarGlobals2[g_RenderThreadIndex].y);
|
|
}
|
|
|
|
void CShaderLib::SetMotionBlurMask(bool motion)
|
|
{
|
|
if(ms_gMotionBlurMask != motion)
|
|
{
|
|
ms_gMotionBlurMask = motion;
|
|
}
|
|
}
|
|
|
|
bool CShaderLib::GetMotionBlurMask()
|
|
{
|
|
return(ms_gMotionBlurMask);
|
|
}
|
|
|
|
void CShaderLib::BeginMotionBlurMask()
|
|
{
|
|
// only should do this when rendering to gbuffer:
|
|
if(ms_gMotionBlurMask && GBuffer::IsRenderingTo())
|
|
{
|
|
SetGlobalDeferredMaterialBit(DEFERRED_MATERIAL_MOTIONBLUR);
|
|
}
|
|
}
|
|
|
|
void CShaderLib::EndMotionBlurMask()
|
|
{
|
|
// only should do this when rendering to gbuffer:
|
|
if(ms_gMotionBlurMask && GBuffer::IsRenderingTo())
|
|
{
|
|
ClearGlobalDeferredMaterialBit(DEFERRED_MATERIAL_MOTIONBLUR);
|
|
}
|
|
}
|
|
|
|
void CShaderLib::SetDeferredWetBlendEnable(bool b)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
if(ms_gDeferredWetBlend[g_RenderThreadIndex] != b)
|
|
{
|
|
ms_gDeferredWetBlend[g_RenderThreadIndex] = b;
|
|
|
|
if(!g_IsSubRenderThread)
|
|
{
|
|
for(int i=0; i<NUMBER_OF_RENDER_THREADS; i++)
|
|
{
|
|
ms_gDeferredWetBlend[i] = b;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
bool CShaderLib::GetDeferredWetBlendEnable()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
return(ms_gDeferredWetBlend[g_RenderThreadIndex]);
|
|
}
|
|
|
|
|
|
#if __XENON
|
|
static unsigned long sm_OldHiStencilEnable=0;
|
|
static unsigned long sm_OldHiStencilWriteEnable=0;
|
|
#endif // __XENON
|
|
|
|
//static u32 prevStencilRef =0,
|
|
// prevStencilEnable =0,
|
|
// prevStencilMask =0,
|
|
// prevStencilWriteMask=0,
|
|
// prevStencilFunc =0,
|
|
// prevStencilPass =0,
|
|
// prevStencilFail =0,
|
|
// prevStencilZFail =0;
|
|
|
|
u32 CShaderLib::GetGlobalDeferredMaterial()
|
|
{
|
|
return(ms_gDeferredMaterial[g_RenderThreadIndex]);
|
|
}
|
|
|
|
void CShaderLib::SetGlobalDeferredMaterial(u32 material, bool forceSetMaterial MSAA_EDGE_PROCESS_FADING_ONLY(, bool reset))
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
|
|
if (GBuffer::IsRenderingTo() || forceSetMaterial)
|
|
{
|
|
material &= 0xFF; // max size is 8 bits
|
|
const u32 finalMaterial = (material | ms_gDeferredMaterialORMask[g_RenderThreadIndex]);
|
|
ms_gDeferredMaterial[g_RenderThreadIndex] = finalMaterial;
|
|
|
|
if(!g_IsSubRenderThread)
|
|
{
|
|
for(int i=0; i<NUMBER_OF_RENDER_THREADS; i++)
|
|
{
|
|
ms_gDeferredMaterial[i] = finalMaterial;
|
|
}
|
|
}
|
|
|
|
// State block path, set the current DSS block with a new reference.
|
|
u8 ref = static_cast<u8>(ms_gDeferredMaterial[g_RenderThreadIndex]);
|
|
#if MSAA_EDGE_PROCESS_FADING
|
|
if(!reset)
|
|
{
|
|
ref |= grcStateBlock::ActiveStencilRef & EDGE_FLAG;
|
|
}
|
|
#endif
|
|
grcStateBlock::SetDepthStencilState(grcStateBlock::DSS_Active, ref);
|
|
}
|
|
};
|
|
|
|
void CShaderLib::SetGlobalDeferredMaterialBit(u32 bit, bool forceSetMaterial)
|
|
{
|
|
bit &= 0xFF; // max size is 8 bits
|
|
ms_gDeferredMaterialORMask[g_RenderThreadIndex] |= (bit);
|
|
|
|
if(!g_IsSubRenderThread)
|
|
{
|
|
for(int i=0; i<NUMBER_OF_RENDER_THREADS; i++)
|
|
{
|
|
ms_gDeferredMaterialORMask[i] |= (bit);
|
|
}
|
|
}
|
|
|
|
SetGlobalDeferredMaterial(ms_gDeferredMaterial[g_RenderThreadIndex], forceSetMaterial);
|
|
}
|
|
|
|
void CShaderLib::ClearGlobalDeferredMaterialBit(u32 bit, bool forceSetMaterial)
|
|
{
|
|
bit &= 0xFF; // max size is 8 bits
|
|
ms_gDeferredMaterialORMask[g_RenderThreadIndex] &= (~bit);
|
|
|
|
if(!g_IsSubRenderThread)
|
|
{
|
|
for(int i=0; i<NUMBER_OF_RENDER_THREADS; i++)
|
|
{
|
|
ms_gDeferredMaterialORMask[i] &= (~bit);
|
|
}
|
|
}
|
|
|
|
SetGlobalDeferredMaterial(ms_gDeferredMaterial[g_RenderThreadIndex],forceSetMaterial);
|
|
}
|
|
|
|
void CShaderLib::ForceScalarGlobals2(const Vector4& vec)
|
|
{
|
|
grcEffect::SetGlobalVar(ms_globalScalars2ID, (Vec4V&)(vec));
|
|
}
|
|
|
|
void CShaderLib::ResetScalarGlobals2()
|
|
{
|
|
grcEffect::SetGlobalVar(ms_globalScalars2ID, (Vec4V&)(ms_gCurrentScalarGlobals2[g_RenderThreadIndex]));
|
|
}
|
|
#if RSG_PC
|
|
void CShaderLib::SetReticuleDistTexture(bool bDist)
|
|
{
|
|
if (bDist)
|
|
grcEffect::SetGlobalVar(gReticuleDistID, PostFX::CenterReticuleDist);
|
|
else
|
|
grcEffect::SetGlobalVar(gReticuleDistID, grcTexture::NoneBlack);
|
|
}
|
|
|
|
void CShaderLib::SetStereoTexture()
|
|
{
|
|
if (GRCDEVICE.IsStereoEnabled())
|
|
GRCDEVICE.SetStereoTexture();
|
|
}
|
|
|
|
void CShaderLib::SetStereoParams(const Vector4& vec)
|
|
{
|
|
if (GRCDEVICE.IsStereoEnabled())
|
|
grcEffect::SetGlobalVar(gStereoParamsID, (Vec4V&)vec);
|
|
}
|
|
|
|
void CShaderLib::SetStereoParams1(const Vector4& vec)
|
|
{
|
|
if (GRCDEVICE.IsStereoEnabled())
|
|
grcEffect::SetGlobalVar(gStereoParams1ID, (Vec4V&)vec);
|
|
}
|
|
#endif // __WIN32PC
|
|
|
|
void CShaderLib::SetFogRayTexture()
|
|
{
|
|
grcEffect::SetGlobalVar(gFogRayTextureID, PostFX::GetFogRayRT());
|
|
}
|
|
|
|
void CShaderLib::SetFogRayIntensity(float fIntensity)
|
|
{
|
|
grcEffect::SetGlobalVar(gFogRayIntensityID, fIntensity);
|
|
}
|
|
|
|
#if MSAA_EDGE_PASS
|
|
void CShaderLib::SetForcedEdge(bool bEdge)
|
|
{
|
|
// only should do this when rendering to gbuffer:
|
|
if(GBuffer::IsRenderingTo())
|
|
{
|
|
if (bEdge)
|
|
SetGlobalDeferredMaterialBit(EDGE_FLAG);
|
|
else
|
|
ClearGlobalDeferredMaterialBit(EDGE_FLAG);
|
|
}
|
|
}
|
|
#endif // MSAA_EDGE_PASS
|
|
|
|
void CShaderLib::SetAlphaRefConsts()
|
|
{
|
|
#if USE_ALPHAREF
|
|
const float global_ar = float(global_alphaRef)/255.0f;
|
|
const float ped_ar = float(ped_alphaRef)/255.0f;
|
|
const float ped_longhair_ar = float(ped_longhair_alphaRef)/255.0f;
|
|
const float foliage_ar = float(foliage_alphaRef)/255.0f;
|
|
const float foliageImposter_ar = float(foliageImposter_alphaRef)/255.0f;
|
|
const float billboard_ar = float(billboard_alphaRef)/255.0f;
|
|
const float shadowBillboard_ar = float(shadowBillboard_alphaRef)/255.0f;
|
|
const float grass_ar = float(grass_alphaRef)/255.0f;
|
|
|
|
Vector4 vecAlphaRef0, vecAlphaRef1;
|
|
vecAlphaRef0.x = global_ar;
|
|
vecAlphaRef0.y = ped_ar;
|
|
vecAlphaRef0.z = ped_longhair_ar;
|
|
vecAlphaRef0.w = foliage_ar;
|
|
|
|
vecAlphaRef1.x = foliageImposter_ar;
|
|
vecAlphaRef1.y = billboard_ar;
|
|
vecAlphaRef1.z = shadowBillboard_ar;
|
|
vecAlphaRef1.w = grass_ar;
|
|
|
|
grcEffect::SetGlobalVar(alphaRefVec0ID, (Vec4V&)(vecAlphaRef0));
|
|
grcEffect::SetGlobalVar(alphaRefVec1ID, (Vec4V&)(vecAlphaRef1));
|
|
#endif //USE_ALPHAREF...
|
|
}
|
|
|
|
void CShaderLib::ResetAllVar()
|
|
{
|
|
CShaderLib::SetGlobalEmissiveScale(1.0f);
|
|
grcEffect::SetGlobalVar(globalAOEffectScaleID, (Vec4V&)(ms_gCurrentAOEffectScale[g_RenderThreadIndex]));
|
|
grcEffect::SetGlobalVar(ms_globalScalarsID, (Vec4V&)(ms_gCurrentScalarGlobals[g_RenderThreadIndex]));
|
|
grcEffect::SetGlobalVar(ms_globalScalars2ID, (Vec4V&)(ms_gCurrentScalarGlobals2[g_RenderThreadIndex]));
|
|
grcEffect::SetGlobalVar(ms_globalScalars3ID, (Vec4V&)(ms_gCurrentScalarGlobals3[g_RenderThreadIndex]));
|
|
grcEffect::SetGlobalVar(globalScreenSizeID, (Vec4V&)(ms_gCurrentScreenSize[g_RenderThreadIndex]));
|
|
}
|
|
|
|
|
|
|
|
//
|
|
//
|
|
// Update any global vars once per frame:
|
|
//
|
|
void CShaderLib::Update()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_UPDATE));
|
|
|
|
const u32 bufIdx = gRenderThreadInterface.GetUpdateBuffer();
|
|
|
|
#if RSG_PC
|
|
ms_ShaderQuality[bufIdx] = (float)CSettingsManager::GetInstance().GetSettings().m_graphics.m_ShaderQuality;
|
|
#endif
|
|
|
|
CPed* pPlayerPed = CGameWorld::FindLocalPlayer();
|
|
if(pPlayerPed)
|
|
{
|
|
const s32 leftFootBoneIdx = pPlayerPed->GetBoneIndexFromBoneTag(BONETAG_L_FOOT);
|
|
const s32 rightFootBoneIdx = pPlayerPed->GetBoneIndexFromBoneTag(BONETAG_R_FOOT);
|
|
|
|
if (leftFootBoneIdx != -1 && rightFootBoneIdx != -1)
|
|
{
|
|
Matrix34 leftFootMat;
|
|
Matrix34 rightFootMat;
|
|
pPlayerPed->GetGlobalMtx(leftFootBoneIdx, leftFootMat);
|
|
pPlayerPed->GetGlobalMtx(rightFootBoneIdx, rightFootMat);
|
|
|
|
// move positions forward, so fur collision circle better encircles both feet:
|
|
const Vector3 vecForward(1,0,0);
|
|
Vector3 LForward, RForward;
|
|
leftFootMat.Transform3x3(vecForward, LForward);
|
|
rightFootMat.Transform3x3(vecForward, RForward);
|
|
static dev_float scaleLFwdX = 0.1f;
|
|
static dev_float scaleLFwdY = 0.1f;
|
|
static dev_float scaleLFwdZ = 0.0f;
|
|
const Vector3 vecScaleFwd(scaleLFwdX, scaleLFwdY, scaleLFwdZ);
|
|
|
|
Vector4 lFootPos(leftFootMat.d + LForward*vecScaleFwd);
|
|
Vector4 rFootPos(rightFootMat.d + RForward*vecScaleFwd);
|
|
lFootPos.w = rFootPos.w = 0.0f;
|
|
|
|
ms_PlayerLFootPos[bufIdx] = lFootPos;
|
|
ms_PlayerRFootPos[bufIdx] = rFootPos;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
//
|
|
void CShaderLib::SetGlobalShaderVariables()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
|
|
const u32 bufIdx = gRenderThreadInterface.GetRenderBuffer();
|
|
SetPlayerFeetPos(ms_PlayerLFootPos[bufIdx], ms_PlayerRFootPos[bufIdx]);
|
|
|
|
#if RSG_PC
|
|
grcEffect::SetGlobalVar(globalShaderQualityID, ms_ShaderQuality[bufIdx]);
|
|
#endif
|
|
}
|
|
|
|
|