11653 lines
413 KiB
C++
11653 lines
413 KiB
C++
// PS3 Base : Composite AA : 6.75ms
|
|
// PS3 No AA: 2.58ms
|
|
// PS3 Second Pass FXAA : 2.64 + 2.75 = 5.39ms
|
|
// PS3 Second Pass FXAA 2 : 2.63 + 2.11 = 4.74ms
|
|
|
|
// 360 Base : Composite AA : 7.5ms
|
|
// 360 No AA: 3.02ms
|
|
// 360 Second Pass FXAA : 3.0 + 0.5 + 4.45 = 8.1 ms
|
|
|
|
//
|
|
// renderer/PostProcessFX.cpp
|
|
//
|
|
// Copyright (C) 1999-2014 Rockstar Games. All Rights Reserved.
|
|
//
|
|
// Post-processing effects
|
|
//
|
|
#include "renderer/PostProcessFX.h"
|
|
#include "renderer/PostProcessFXHelper.h"
|
|
#include "render_channel.h"
|
|
|
|
// System
|
|
#if __XENON
|
|
#include "system/xtl.h"
|
|
#define DBG 0
|
|
#include <xgraphics.h>
|
|
#endif // __XENON
|
|
|
|
// Rage headers
|
|
#include "atl/functor.h"
|
|
#include "atl/hashstring.h"
|
|
#include "profile/profiler.h"
|
|
#include "profile/timebars.h"
|
|
#include "grcore/allocscope.h"
|
|
#include "grcore/debugdraw.h"
|
|
#include "grcore/gfxcontext.h"
|
|
#include "grcore/im.h"
|
|
#include "grcore/image.h"
|
|
#include "grcore/image_dxt.h"
|
|
#include "grcore/quads.h"
|
|
#include "grcore/fastquad.h"
|
|
#include "grcore/stateblock.h"
|
|
#include "grcore/texturedefault.h"
|
|
#include "system/param.h"
|
|
#include "system/memory.h"
|
|
#include "grmodel/setup.h"
|
|
#include "math/float16.h"
|
|
|
|
#if DISPLAY_NETWORK_INFO
|
|
#include "net/nethardware.h"
|
|
#endif
|
|
|
|
#if __XENON
|
|
#include "grcore/gprallocation.h"
|
|
#include "grcore/texturexenon.h"
|
|
#endif // __XENON
|
|
|
|
#if __PS3
|
|
#include "grcore/texture.h"
|
|
#include "grcore/texturegcm.h"
|
|
#endif
|
|
|
|
// Framework headers
|
|
#include "fwsys/timer.h"
|
|
#include "fwscene/stores/txdstore.h"
|
|
#include "vfx/vfxutil.h"
|
|
#include "vfx/clouds/CloudHat.h"
|
|
#include "vfx/VfxHelper.h"
|
|
|
|
// Game headers
|
|
#include "camera/base/BaseObject.h"
|
|
#include "camera/base/BaseCamera.h"
|
|
#include "camera/CamInterface.h"
|
|
#include "camera/debug/DebugDirector.h"
|
|
#include "camera/gameplay/aim/AimCamera.h"
|
|
#include "camera/helpers/ControlHelper.h"
|
|
#include "camera/gameplay/GameplayDirector.h"
|
|
#include "camera/gameplay/ThirdPersonCamera.h"
|
|
#include "camera/cinematic/camera/mounted/CinematicMountedCamera.h"
|
|
#include "camera/gameplay/ThirdPersonCamera.h"
|
|
#include "camera/system/CameraManager.h"
|
|
#include "control/videorecording/videorecording.h"
|
|
#include "core/game.h"
|
|
#include "cutscene/CutSceneManagerNew.h"
|
|
#include "cutscene/CutSceneCameraEntity.h"
|
|
#include "debug/Rendering/DebugDeferred.h"
|
|
#include "debug/Rendering/DebugView.h"
|
|
#include "debug/Debug.h"
|
|
#include "Debug/BudgetDisplay.h"
|
|
#include "debug/BugstarIntegration.h"
|
|
#include "debug/FrameDump.h"
|
|
#include "debug/LightProbe.h"
|
|
#include "debug/SceneGeometryCapture.h"
|
|
#include "debug/TiledScreenCapture.h"
|
|
#include "frontend/landing_page/LandingPageArbiter.h"
|
|
#include "frontend/NewHud.h"
|
|
#include "game/weather.h"
|
|
#include "network/NetworkInterface.h"
|
|
#include "network/Live/livemanager.h"
|
|
#include "peds/PlayerInfo.h"
|
|
#include "peds/ped.h"
|
|
#include "frontend/DisplayCalibration.h"
|
|
#include "frontend/MobilePhone.h"
|
|
#include "frontend/PauseMenu.h"
|
|
#include "renderer/LensArtefacts.h"
|
|
#include "renderer/Renderer.h"
|
|
#include "renderer/rendertargets.h"
|
|
#include "renderer/Deferred/GBuffer.h"
|
|
#include "renderer/Deferred/DeferredLighting.h"
|
|
#include "renderer/RenderPhases/RenderPhaseFX.h"
|
|
#include "renderer/RenderPhases/RenderPhaseCascadeShadows.h"
|
|
#include "renderer/RenderPhases/RenderPhaseReflection.h"
|
|
#include "renderer/Util/ShaderUtil.h"
|
|
#include "renderer/Util/ShmooFile.h"
|
|
#include "renderer/lights/lights.h"
|
|
#include "renderer/Lights/TiledLighting.h"
|
|
#include "renderer/sprite2d.h"
|
|
#include "renderer/Water.h"
|
|
#include "renderer/SSAO.h"
|
|
#include "renderer/ScreenshotManager.h"
|
|
#include "renderer/UI3DDrawManager.h"
|
|
#include "SaveLoad/savegame_photo_manager.h"
|
|
#include "scene//playerswitch/PlayerSwitchInterface.h"
|
|
#include "scene/world/GameWorld.h"
|
|
#include "TimeCycle/TimeCycle.h"
|
|
#include "TimeCycle/TimeCycleConfig.h"
|
|
#include "camera/viewports/viewportManager.h"
|
|
#include "vfx/misc/LensFlare.h"
|
|
#include "vfx/particles/PtFxManager.h"
|
|
#include "vfx/systems/VfxLens.h"
|
|
#include "camera/helpers/Frame.h"
|
|
|
|
#if GTA_REPLAY
|
|
#include "camera/replay/ReplayDirector.h"
|
|
#include "control/replay/IReplayMarkerStorage.h"
|
|
#include "frontend/VideoEditor/ui/Editor.h"
|
|
#include "replaycoordinator/ReplayCoordinator.h"
|
|
#endif // #if GTA_REPLAY
|
|
|
|
#if __D3D11
|
|
#include "grcore/rendertarget_d3d11.h"
|
|
#include "grcore/texturefactory_d3d11.h"
|
|
#endif
|
|
#if RSG_ORBIS
|
|
#include "grcore/buffer_gnm.h"
|
|
#endif
|
|
#if RSG_ORBIS && SUPPORT_RENDERTARGET_DUMP
|
|
#include "grcore/texturefactory_gnm.h"
|
|
#endif
|
|
|
|
#include "AdaptiveDOF.h"
|
|
|
|
#if USE_SCREEN_WATERMARK
|
|
#include "Peds/ped.h"
|
|
#include "frontend/HudTools.h"
|
|
#include "frontend/Scaleform/ScaleformMgr.h"
|
|
#include "text/text.h"
|
|
#include "text/TextConversion.h"
|
|
#include "text/textFile.h"
|
|
#include "text/TextFormat.h"
|
|
#include "scaleform/scaleform.h"
|
|
#include "script/script_hud.h"
|
|
PARAM(no_screen_watermark,"Disable screen watermark");
|
|
#endif
|
|
|
|
#if USE_NV_TXAA
|
|
#define __GFSDK_OS_WINDOWS__
|
|
#define __GFSDK_DX11__
|
|
#include "../../3rdParty/NVidia/NVTXAA/include/GFSDK_TXAA.h"
|
|
#include "../../3rdParty/NVidia/nvapi.h"
|
|
extern TxaaCtxDX g_txaaContext;
|
|
gfsdk_U32 g_TXAADevMode = TXAA_MODE_TOTAL;
|
|
|
|
static grcTexture* g_TXAAResolve = NULL;
|
|
PARAM(txaaEnable,"Enable TXAA [0,1]");
|
|
PARAM(txaaDevMode,"0-11 see header file");
|
|
#endif
|
|
|
|
RENDER_OPTIMISATIONS()
|
|
//OPTIMISATIONS_OFF()
|
|
|
|
#define POSTFX_FOGRAY (RSG_PC || RSG_DURANGO || (RSG_ORBIS && (SCE_ORBIS_SDK_VERSION >= 0x01600071u)))
|
|
#define POSTFX_TILED_LIGHTING_ENABLED ((TILED_LIGHTING_ENABLED) && (__XENON || __PS3 || __D3D11 || RSG_ORBIS))
|
|
#define POSTFX_USE_TILEDFOG 0 && POSTFX_TILED_LIGHTING_ENABLED
|
|
|
|
#define DEBUG_MOTIONBLUR (0 && __BANK)
|
|
#define DEBUG_HDR_BUFFER (0)
|
|
#define USE_FXAA 1
|
|
|
|
#define FILM_EFFECT (RSG_PC)
|
|
PARAM(postfxusesFP16, "Force FP16 render targets for postfx");
|
|
|
|
PARAM(simplepfx,"Use simplified postfx shader");
|
|
#if !__FINAL && (__D3D11 || RSG_ORBIS)
|
|
PARAM(DX11Use8BitTargets,"Use 8 bit targets in DX11.");
|
|
PARAM(disableBokeh,"Disable Bokeh effects in DX11");
|
|
#endif // !__FINAL && (__D3D11 || RSG_ORBIS)
|
|
PARAM(dontDelayFlipSwitch,"Don't delay flip : wait flip will be done at the end of the frame, like normal people do.");
|
|
#if __WIN32PC || RSG_DURANGO || RSG_ORBIS
|
|
PARAM(filmeffect, "Enable the film effect shader");
|
|
#endif
|
|
|
|
PARAM(pcTiledPostFx, "Use tiling for PostFX shading");
|
|
|
|
#if USE_HQ_ANTIALIASING
|
|
PARAM(fxaaMode,"0: Off, 1: Default, 2: HQ FXAA");
|
|
#endif // USE_HQ_ANTIALIASING
|
|
|
|
NOSTRIP_PARAM(setGamma, "Allow to force a specific gamma setting on boot.");
|
|
|
|
EXT_PF_GROUP(RenderPhase);
|
|
PF_TIMER(PostFx,RenderPhase);
|
|
|
|
PF_PAGE(ExposureAndLumPage, "Exposure and Luminance");
|
|
PF_GROUP(ExposureAndLum);
|
|
PF_LINK(ExposureAndLumPage, ExposureAndLum);
|
|
PF_VALUE_FLOAT(UpdateExposure, ExposureAndLum);
|
|
PF_VALUE_FLOAT(Luminance, ExposureAndLum);
|
|
PF_VALUE_FLOAT(RenderExposure, ExposureAndLum);
|
|
PF_VALUE_INT(CalculationType, ExposureAndLum);
|
|
|
|
#if LIGHT_VOLUME_USE_LOW_RESOLUTION
|
|
extern grcRenderTarget* m_volumeOffscreenBuffer;
|
|
extern grcRenderTarget* m_volumeReconstructionBuffer;
|
|
#endif
|
|
|
|
namespace rage {
|
|
extern bool s_NeedWaitFlip;
|
|
}
|
|
|
|
extern bool gLastGenMode;
|
|
|
|
namespace PostFX {
|
|
|
|
|
|
PostFXParamBlock::paramBlock PostFXParamBlock::ms_params[2];
|
|
|
|
PedKillOverlay g_pedKillOverlay;
|
|
ScreenBlurFade g_screenBlurFade;
|
|
BulletImpactOverlay g_bulletImpactOverlay;
|
|
Adaptation g_adaptation;
|
|
DofTODOverrideHelper g_cutsceneDofTODOverride;
|
|
|
|
grcRenderTarget* g_prevExposureRT = NULL;
|
|
grcRenderTarget* g_currentExposureRT = NULL;
|
|
|
|
int g_resetAdaptedLumCount = NUM_RESET_FRAMES;
|
|
bool g_enableLightRays=false;
|
|
bool g_lightRaysAboveWaterLine=true;
|
|
bool g_enableNightVision=false;
|
|
#if __BANK
|
|
bool g_overrideNightVision=false;
|
|
#endif
|
|
bool g_enableSeeThrough=false;
|
|
bool g_overrideDistanceBlur=false;
|
|
float g_distanceBlurOverride=0.0f;
|
|
|
|
bool g_scriptHighDOFOverrideToggle=false;
|
|
bool g_scriptHighDOFOverrideEnableDOF=false;
|
|
Vector4 g_scriptHighDOFOverrideParams=Vector4(0.0f,0.0f,0.0f,0.0f);
|
|
|
|
#if __ASSERT
|
|
sysIpcCurrentThreadId g_FogRayCascadeShadowMapDownsampleThreadId = sysIpcCurrentThreadIdInvalid;
|
|
#endif
|
|
|
|
#if __PS3
|
|
u16 g_RTPoolIdPostFX = kRTPoolIDInvalid;
|
|
#endif
|
|
|
|
#if __BANK
|
|
bool g_Override = false;
|
|
bool g_UseTiledTechniques = true;
|
|
#if __PS3
|
|
bool g_PS3UseCompositeTiledTechniques = true;
|
|
#endif
|
|
bool g_ForceUnderWaterTech = false;
|
|
bool g_ForceAboveWaterTech = false;
|
|
bool g_ForceUseSimple = false;
|
|
bool g_AutoExposureSkip = false;
|
|
float g_overwrittenExposure = -3.0f;
|
|
bool g_JustExposure = false;
|
|
bool g_delayFlipWait = true;
|
|
|
|
bool g_bDebugTriggerPulseEffect = false;
|
|
u32 g_debugPulseEffectRampUpDuration = 0;
|
|
u32 g_debugPulseEffectHoldDuration = 10;
|
|
u32 g_debugPulseEffectRampDownDuration = 350;
|
|
Vector4 g_debugPulseEffectParams = Vector4(-0.3f,0.0f,0.1f,0.0f);
|
|
|
|
bool g_DrawCOCOverlay = false;
|
|
float g_cocOverlayAlphaVal = 1.0f;
|
|
static grcEffectVar g_cocOverlayAlpha;
|
|
#endif //__BANK
|
|
|
|
static BankBool g_fadeSSLROffscreen = true;
|
|
static BankFloat g_fadeSSLROffscreenValue = 1.3f;
|
|
|
|
bool g_setExposureToTarget = false;
|
|
BANK_ONLY(static char adaptionInfoStr[255]);
|
|
|
|
atArray<historyValues> g_historyArray;
|
|
s8 g_historyIndex = 0;
|
|
s8 g_historySize = 0;
|
|
|
|
bool g_enableExposureTweak = true;
|
|
bool g_forceExposureReadback = false;
|
|
|
|
float g_filmicTonemapParams[TONEMAP_VAR_COUNT];
|
|
|
|
Vector4 g_sniperSightDefaultDOFParams;
|
|
bool g_sniperSightDefaultEnabled = true;
|
|
|
|
bool g_sniperSightOverrideEnabled = false;
|
|
bool g_sniperSightOverrideDisableDOF = true;
|
|
Vector4 g_sniperSightOverrideDOFParams = Vector4(0.0f, 0.0f, 0.0f, 2180.0f);
|
|
|
|
bool g_DefaultMotionBlurEnabled = false;
|
|
float g_DefaultMotionBlurStrength = 0.05f;
|
|
|
|
#if RSG_PC
|
|
static __THREAD PostFX::eResolvePause g_DoPauseResolve = PostFX::NOT_RESOVE_PAUSE;
|
|
static bool g_RequestResetDOFRenderTargets = false;
|
|
#else
|
|
static PostFX::eResolvePause g_DoPauseResolve = PostFX::NOT_RESOVE_PAUSE;
|
|
#endif
|
|
|
|
#if RSG_PC
|
|
// force postfx setting to High at most
|
|
// need to do this to avoid flickering caused by dof effects in multi-GPUs
|
|
#define GET_POSTFX_SETTING(s) (PostFX::g_DoPauseResolve == PostFX::IN_RESOLVE_PAUSE ? Min(s,CSettings::Medium) : s)
|
|
#else
|
|
#define GET_POSTFX_SETTING(s) (s)
|
|
#endif
|
|
|
|
#if DEBUG_MOTIONBLUR
|
|
bool g_debugPrintMotionBlur = false;
|
|
#endif
|
|
|
|
#if __WIN32PC || RSG_DURANGO || RSG_ORBIS
|
|
bool g_FXAAEnable = true;
|
|
#else
|
|
bank_bool g_FXAAEnable = true;
|
|
#endif
|
|
#if USE_NV_TXAA
|
|
bool g_TXAAEnable = false;
|
|
#endif // USE_NV_TXAA
|
|
|
|
MLAA_ONLY(MLAA g_MLAA;)
|
|
|
|
typedef enum
|
|
{
|
|
AA_FXAA_DEFAULT = 0,
|
|
#if USE_HQ_ANTIALIASING
|
|
AA_FXAA_HQ,
|
|
#endif // USE_HQ_ANTIALIASING
|
|
AA_FXAA_UI
|
|
} AntiAliasingEnum;
|
|
|
|
AntiAliasingEnum g_AntiAliasingType = AA_FXAA_DEFAULT;
|
|
|
|
#if USE_HQ_ANTIALIASING
|
|
float g_AntiAliasingSwitchDistance = 150.f;
|
|
static grcEffectTechnique g_HQAATiledTechnique;
|
|
static grcEffectVar g_HQAA_srcMapID;
|
|
#endif
|
|
|
|
#if FILM_EFFECT
|
|
bool g_EnableFilmEffect;
|
|
float g_BaseDistortionCoefficient;
|
|
float g_BaseCubeDistortionCoefficient;
|
|
float g_ChromaticAberrationOffset;
|
|
float g_ChromaticAberrationCubeOffset;
|
|
float g_FilmNoise;
|
|
float g_FilmVignettingIntensity;
|
|
float g_FilmVignettingRadius;
|
|
float g_FilmVignettingContrast;
|
|
#endif
|
|
|
|
bool g_UseSubSampledAlpha = (RSG_ORBIS || RSG_DURANGO);
|
|
bool g_UseSinglePassSSA = (RSG_ORBIS || RSG_DURANGO || RSG_PC);
|
|
bool g_UseSSAOnFoliage = false;
|
|
#if SSA_USES_CONDITIONALRENDER
|
|
static BankBool g_UseConditionalSSA = true;
|
|
#endif
|
|
DECLARE_MTR_THREAD bool g_MarkingSubSamples=false;
|
|
|
|
#if __XENON
|
|
static BankBool g_UsePacked7e3IntBackBuffer = true;
|
|
#endif
|
|
|
|
float g_gammaFrontEnd = 2.2f;
|
|
|
|
float g_linearExposure;
|
|
float g_averageLinearExposure;
|
|
|
|
|
|
float g_sunExposureAdjust = 0.0f;
|
|
|
|
bool g_noiseOverride = false;
|
|
float g_noisinessOverride = 0.0f;
|
|
|
|
bool g_useAutoColourCompression = true;
|
|
|
|
#if RSG_PC
|
|
bool g_allowDOFInReplay = true;
|
|
#endif
|
|
|
|
grcTexture* g_pNoiseTexture = NULL;
|
|
grcTexture* g_pDamageOverlayTexture = NULL;
|
|
|
|
AnimatedPostFX g_defaultFlashEffect;
|
|
|
|
Vector4 g_vInitialPulseParams = Vector4(0.0f, 0.0f, 0.0f, 0.0f);
|
|
Vector4 g_vTargetPulseParams = Vector4(0.0f, 0.0f, 0.0f, 0.0f);
|
|
u32 g_uPulseStartTime = 0;
|
|
u32 g_uPulseRampUpDuration = 0;
|
|
u32 g_uPulseRampDownDuration = 0;
|
|
u32 g_uPulseHoldDuration = 0;
|
|
|
|
float g_fSniperScopeOverrideStrength = 1.0f;
|
|
|
|
float g_motionBlurMaxVelocityMult = 2.0f;
|
|
bool g_motionBlurCutTestDisabled = false;
|
|
bool g_bMotionBlurOverridePrevMat = false;
|
|
Matrix34 g_motionBlurPrevMatOverride;
|
|
|
|
float g_bloomThresholdExposureDiffMin;
|
|
float g_bloomThresholdExposureDiffMax;
|
|
float g_bloomThresholdMin;
|
|
float g_bloomThresholdPower;
|
|
|
|
static float g_fograyJitterStart = 800.0f;
|
|
static float g_fograyJitterEnd = 1100.0f;
|
|
|
|
float g_bloomLargeBlurBlendMult = 0.5f;
|
|
float g_bloomMedBlurBlendMult = 0.5f;
|
|
float g_bloomSmallBlurBlendMult = 1.0f;
|
|
|
|
bool g_bloomEnable = true;
|
|
|
|
float g_cachedDefaultMotionBlur = 0.0f;
|
|
|
|
#if GTA_REPLAY
|
|
//When paused during replay we still want to update some effects when in the effects menu of the editor.
|
|
bool g_UpdateReplayEffectsWhilePaused = false;
|
|
#endif
|
|
|
|
// For drawing damage overlay in slices
|
|
struct grcSliceVertex {
|
|
float x, y, z;
|
|
unsigned cpv;
|
|
float u, v, q;
|
|
void Set(float x_,float y_,float z_,unsigned cpv_,float u_,float v_,float q_) XENON_ONLY(volatile)
|
|
{
|
|
x = x_; y = y_; z = z_; cpv = cpv_; u = u_; v = v_; q = q_;
|
|
}
|
|
};
|
|
// vert decl for slice vertices
|
|
grcVertexDeclaration* g_damageSliceDecl;
|
|
|
|
grcRenderTarget* LumDownsampleRT[5];
|
|
int LumDownsampleRTCount;
|
|
|
|
#if AVG_LUMINANCE_COMPUTE
|
|
grcRenderTarget* LumCSDownsampleUAV[6];
|
|
int LumCSDownsampleUAVCount;
|
|
#endif
|
|
|
|
#if (RSG_PC)
|
|
grcRenderTarget* ImLumDownsampleRT[5];
|
|
int ImLumDownsampleRTCount;
|
|
#endif
|
|
|
|
grcRenderTarget* FogOfWarRT0;
|
|
grcRenderTarget* FogOfWarRT1;
|
|
grcRenderTarget* FogOfWarRT2;
|
|
|
|
grcRenderTarget* FogRayRT;
|
|
grcRenderTarget* FogRayRT2;
|
|
|
|
#if RSG_PC
|
|
// for nvstereo
|
|
grcRenderTarget* CenterReticuleDist;
|
|
#endif
|
|
};
|
|
|
|
static atHashString DefaultFlashEffectModName;
|
|
|
|
static grmShader* PostFXShader;
|
|
static grcEffectTechnique PostFXTechnique;
|
|
#if GENERATE_SHMOO
|
|
static int PostFxShmoo;
|
|
#else
|
|
#define PostFxShmoo (-1)
|
|
#endif
|
|
|
|
#if MSAA_EDGE_PASS
|
|
static grmShader* PostFXShaderMS0;
|
|
static grcDepthStencilStateHandle edgeMaskDepthEffectFace_DS;
|
|
#endif // MSAA_EDGE_PASS
|
|
|
|
#if DOF_COMPUTE_GAUSSIAN || DOF_DIFFUSION
|
|
static grmShader* dofComputeShader;
|
|
static grcEffectTechnique dofComputeTechnique;
|
|
#endif
|
|
|
|
#if DOF_DIFFUSION
|
|
static grmShader* dofDiffusionShader;
|
|
static grcEffectTechnique dofDiffusiontechnique;
|
|
#endif
|
|
|
|
#if BOKEH_SUPPORT
|
|
static grcEffectTechnique PostFXBokehTechnique;
|
|
#endif
|
|
#if FILM_EFFECT
|
|
static grcEffectTechnique PostFXFilmEffectTechnique;
|
|
#endif
|
|
|
|
#if BOKEH_SUPPORT
|
|
strLocalIndex g_BokehTxdSlot;
|
|
#endif
|
|
#if WATERMARKED_BUILD
|
|
strLocalIndex g_TxdSlot;
|
|
#endif
|
|
|
|
static int CloudDepthTechGroup;
|
|
|
|
#if ADAPTIVE_DOF
|
|
PostFX::AdaptiveDOF AdaptiveDepthOfField;
|
|
bool WasAdaptiveDofProcessedOnPreviousUpdate = false;
|
|
#endif
|
|
|
|
#if __BANK
|
|
#define NUM_DEBUG_PARAMS 2
|
|
static Vector4 DebugParams[NUM_DEBUG_PARAMS];
|
|
static grcEffectVar DebugParamsId[NUM_DEBUG_PARAMS];
|
|
#endif
|
|
|
|
//// Variables
|
|
// Miscs
|
|
static grcEffectVar TexelSizeId;
|
|
static grcEffectVar GBufferTexture0ParamId;
|
|
|
|
#if AVG_LUMINANCE_COMPUTE
|
|
static grcEffectVar LumCSDownsampleSrcId;
|
|
static grcEffectVar LumCSDownsampleInitSrcId;
|
|
static grcEffectVar LumCSDownsampleDstId;
|
|
static grcEffectVar LumCSDownsampleTexSizeId;
|
|
|
|
static grmShader* avgLuminanceShader;
|
|
static grcEffectTechnique avgLuminanceTechnique;
|
|
#endif
|
|
|
|
// DOF
|
|
static grcEffectVar DofProjId;
|
|
static grcEffectVar DofShearId;
|
|
static grcEffectVar DofParamsId;
|
|
static grcEffectVar HiDofParamsId;
|
|
static grcEffectVar HiDofSmallBlurId;
|
|
static grcEffectVar HiDofMiscParamsId;
|
|
#if ADAPTIVE_DOF_OUTPUT_UAV
|
|
static grcEffectVar PostFXAdaptiveDOFParamsBufferVar;
|
|
static grcEffectVar DofComputeAdaptiveDOFParamsBufferVar;
|
|
#endif //ADAPTIVE_DOF_OUTPUT_UAV
|
|
#if BOKEH_SUPPORT
|
|
static grcEffectVar BokehBrightnessParams;
|
|
static grcEffectVar BokehParams1;
|
|
static grcEffectVar BokehParams2;
|
|
static grcEffectVar DOFTargetSize;
|
|
static grcEffectVar RenderTargetSize;
|
|
static grcEffectVar BokehEnableVar;
|
|
static grcEffectVar BokehSpritePointBufferVar;
|
|
static grcEffectVar BokehSortedIndexBufferVar;
|
|
static grcEffectVar GaussianWeightsBufferVar;
|
|
static grcEffectVar LuminanceDownsampleOOSrcDstSizeId;
|
|
static grcEffectVar BokehAlphaCutoffVar;
|
|
static grcEffectVar BokehGlobalAlphaVar;
|
|
static grcEffectVar BokehSortLevelVar;
|
|
static grcEffectVar BokehSortLevelMaskVar;
|
|
#if BOKEH_SORT_BITONIC_TRANSPOSE
|
|
static grcEffectVar BokehSortTransposeMatWidthVar;
|
|
static grcEffectVar BokehSortTransposeMatHeightVar;
|
|
#endif
|
|
|
|
static grcEffectVar PostFXAdaptiveDofEnvBlurParamsVar;
|
|
static grcEffectVar PostFXAdaptiveDofCustomPlanesParamsVar;
|
|
|
|
enum eBokeh_Shapes
|
|
{
|
|
BOKEH_SHAPE_HEXAGON = 0,
|
|
BOKEH_SHAPE_OCTAGON,
|
|
BOKEH_SHAPE_CIRCLE,
|
|
BOKEH_SHAPE_CROSS,
|
|
BOKEH_SHAPE_MAX
|
|
};
|
|
grcTextureHandle m_BokehShapeTextureSheet;
|
|
#endif
|
|
|
|
#if DOF_TYPE_CHANGEABLE_IN_RAG
|
|
static grcEffectVar CurrentDOFTechniqueVar;
|
|
#endif
|
|
|
|
#if DOF_COMPUTE_GAUSSIAN || DOF_DIFFUSION
|
|
static grcEffectVar DofKernelSize;
|
|
#if COC_SPREAD
|
|
static grcEffectVar DofCocSpreadKernelRadius;
|
|
#endif
|
|
static grcEffectVar DofProjCompute;
|
|
static grcEffectVar DofSkyWeightModifierVar;
|
|
static grcEffectVar DofLumFilterParams;
|
|
static grcEffectVar DofRenderTargetSizeVar;
|
|
static grcEffectVar fourPlaneDofVar;
|
|
#endif //DOF_COMPUTE_GAUSSIAN
|
|
#if DOF_DIFFUSION
|
|
static grcEffectVar dofDiffusion_lastbufferSizeVar;
|
|
static grcEffectVar dofDiffusion_DiffusionRadiusVar;
|
|
static grcEffectVar dofDiffusion_txABC_ID; //0
|
|
static grcEffectVar dofDiffusion_txCOC_ID; //1
|
|
static grcEffectVar dofDiffusion_txX_ID; //2
|
|
static grcEffectVar dofDiffusion_txY_ID; //3
|
|
#endif //DOF_DIFFUSION
|
|
|
|
// HDR
|
|
static grcEffectVar BloomParamsId;
|
|
static grcEffectVar FilmicId[2];
|
|
|
|
static grcEffectVar tonemapParams;
|
|
static grcEffectVar brightTonemapParams[2];
|
|
static grcEffectVar darkTonemapParams[2];
|
|
|
|
// Noise
|
|
static grcEffectVar NoiseParamsId;
|
|
|
|
// Motion Blur
|
|
static grcEffectVar DirectionalMotionBlurParamsId;
|
|
static grcEffectVar DirectionalMotionBlurIterParamsId;
|
|
|
|
static grcEffectVar MBPrevViewProjMatrixXId;
|
|
static grcEffectVar MBPrevViewProjMatrixYId;
|
|
static grcEffectVar MBPrevViewProjMatrixWId;
|
|
|
|
// Night Vision
|
|
static grcEffectVar lowLumId;
|
|
static grcEffectVar highLumId;
|
|
static grcEffectVar topLumId;
|
|
|
|
static grcEffectVar scalerLumId;
|
|
|
|
static grcEffectVar offsetLumId;
|
|
static grcEffectVar offsetLowLumId;
|
|
static grcEffectVar offsetHighLumId;
|
|
|
|
static grcEffectVar noiseLumId;
|
|
static grcEffectVar noiseLowLumId;
|
|
static grcEffectVar noiseHighLumId;
|
|
|
|
static grcEffectVar bloomLumId;
|
|
|
|
static grcEffectVar colorLumId;
|
|
static grcEffectVar colorLowLumId;
|
|
static grcEffectVar colorHighLumId;
|
|
|
|
#if RSG_PC
|
|
static grcEffectVar globalFreeAimDirId;
|
|
#endif
|
|
|
|
// Light rays
|
|
static grcEffectVar globalFograyParamId;
|
|
static grcEffectVar globalFograyFadeParamId;
|
|
static grcEffectVar lightrayParamsId;
|
|
static grcEffectVar lightrayParams2Id;
|
|
|
|
static grcEffectVar sslrParamsId; // additive reducer, blit size, ray Length, enable intensity map for non SSLR light rays
|
|
static grcEffectVar sslrCenterId;
|
|
static grcEffectVar SSLRTextureId;
|
|
static grcEffectVar GLRTextureId;
|
|
|
|
// HeatHaze
|
|
static grcEffectVar heatHazeParamsId;
|
|
static grcEffectVar HeatHazeTex1ParamsId;
|
|
static grcEffectVar HeatHazeTex2ParamsId;
|
|
static grcEffectVar HeatHazeOffsetParamsId;
|
|
|
|
// SeeThrough
|
|
static grcEffectVar seeThroughParamsId;
|
|
static grcEffectVar seeThroughColorNearId;
|
|
static grcEffectVar seeThroughColorFarId;
|
|
static grcEffectVar seeThroughColorVisibleBaseId;
|
|
static grcEffectVar seeThroughColorVisibleWarmId;
|
|
static grcEffectVar seeThroughColorVisibleHotId;
|
|
|
|
// AA
|
|
static grcEffectVar rcpFrameId;
|
|
|
|
// Vignetting (test)
|
|
static grcEffectVar VignettingParamsId;
|
|
static grcEffectVar VignettingColorId;
|
|
|
|
// Damage Overlay Params
|
|
static grcEffectVar DamageOverlayMiscId;
|
|
static grcEffectVar DamageOverlayForwardId;
|
|
static grcEffectVar DamageOverlayTangentId;
|
|
static grcEffectVar DamageOverlayCenterPosId;
|
|
|
|
// Lens Gradient
|
|
static grcEffectVar GradientFilterColTopId;
|
|
static grcEffectVar GradientFilterColMiddleId;
|
|
static grcEffectVar GradientFilterColBottomId;
|
|
|
|
// Scanline
|
|
static grcEffectVar ScanlineFilterParamsId;
|
|
|
|
// Colour correction
|
|
static grcEffectVar ColorCorrectId;
|
|
static grcEffectVar ColorShiftId;
|
|
static grcEffectVar DesaturateId;
|
|
static grcEffectVar GammaId;
|
|
|
|
// Exposure calculation
|
|
static grcEffectVar ExposureParams0Id;
|
|
static grcEffectVar ExposureParams1Id;
|
|
static grcEffectVar ExposureParams2Id;
|
|
static grcEffectVar ExposureParams3Id;
|
|
|
|
#if FILM_EFFECT
|
|
//lens effects
|
|
static grcEffectVar LensDistortionId;
|
|
#endif
|
|
//// Samplers
|
|
|
|
// Miscs
|
|
static grcEffectVar GBufferTextureId0;
|
|
|
|
#if USE_FXAA
|
|
static grcEffectVar FXAABackBuffer;
|
|
#endif // USE_FXAA
|
|
|
|
#if PTFX_APPLY_DOF_TO_PARTICLES
|
|
static grcEffectVar PtfxDepthBuffer;
|
|
static grcEffectVar PtfxAlphaBuffer;
|
|
#endif // PTFX_APPLY_DOF_TO_PARTICLES
|
|
|
|
#if __XENON
|
|
static grcEffectVar GBufferTextureId2;
|
|
#endif // __XENON
|
|
static grcEffectVar GBufferTextureIdDepth;
|
|
static grcEffectVar ResolvedTextureIdDepth;
|
|
static grcEffectVar GBufferTextureIdSSAODepth;
|
|
|
|
#if DEVICE_MSAA
|
|
static grcEffectVar TextureHDR_AA;
|
|
#endif //DEVICE_MSAA
|
|
|
|
static grcEffectVar TextureID_0;
|
|
|
|
#if __PPU
|
|
static grcEffectVar TextureID_0a;
|
|
#endif // __PPU
|
|
static grcEffectVar TextureID_1;
|
|
|
|
static grcEffectVar TextureID_v0;
|
|
static grcEffectVar TextureID_v1;
|
|
|
|
#if __XENON || __D3D11 || RSG_ORBIS
|
|
static grcEffectVar StencilCopyTextureId;
|
|
static grcEffectVar TiledDepthTextureId;
|
|
#endif
|
|
|
|
#if !__PS3
|
|
static grcEffectVar BloomTexelSizeId;
|
|
#endif
|
|
|
|
static grcEffectVar PostFxTexture2Id;
|
|
static grcEffectVar PostFxTexture3Id;
|
|
|
|
|
|
// MotionBlur
|
|
static grcEffectVar PostFxMotionBlurTextureID;
|
|
|
|
// HDR
|
|
static grcEffectVar BloomTextureID;
|
|
static grcEffectVar BloomTextureGID;
|
|
|
|
// Motion Blur
|
|
static grcEffectVar JitterTextureId;
|
|
static grcEffectVar MBPerspectiveShearParams0Id;
|
|
static grcEffectVar MBPerspectiveShearParams1Id;
|
|
static grcEffectVar MBPerspectiveShearParams2Id;
|
|
|
|
// Heat Haze
|
|
static grcEffectVar HeatHazeTextureId;
|
|
static grcEffectVar PostFxHHTextureID;
|
|
static grcEffectVar HeatHazeMaskTextureID;
|
|
|
|
// Screen Blur Fade
|
|
static grcEffectVar ScreenBlurFadeID;
|
|
|
|
// Lens Distortion
|
|
static grcEffectVar DistortionParamsID;
|
|
|
|
// Lens Artefacts
|
|
static grcEffectVar LensArtefactParams0ID;
|
|
static grcEffectVar LensArtefactParams1ID;
|
|
static grcEffectVar LensArtefactParams2ID;
|
|
static grcEffectVar LensArtefactTextureID;
|
|
|
|
// Light Streaks
|
|
static grcEffectVar LightStreaksColorShift0ID;
|
|
static grcEffectVar LightStreaksBlurColWeightsID;
|
|
static grcEffectVar LightStreaksBlurDirID;
|
|
|
|
// Blur Vignette
|
|
static grcEffectVar BlurVignettingParamsID;
|
|
|
|
#if DOF_COMPUTE_GAUSSIAN || DOF_DIFFUSION
|
|
static grcEffectVar dofComputeColorTex;
|
|
static grcEffectVar dofComputeDepthBlurTex;
|
|
static grcEffectVar dofComputeOutputTex;
|
|
static grcEffectVar dofComputeDepthBlurHalfResTex;
|
|
static grcEffectVar dofBlendParams;
|
|
#if COC_SPREAD
|
|
static grcEffectVar cocComputeOutputTex;
|
|
#endif
|
|
#endif //DOF_COMPUTE_GAUSSIAN
|
|
|
|
#if POSTFX_UNIT_QUAD
|
|
namespace quad
|
|
{
|
|
static grcEffectVar Position;
|
|
static grcEffectVar TexCoords;
|
|
static grcEffectVar Scale;
|
|
#if USE_IMAGE_WATERMARKS
|
|
static grcEffectVar Alpha;
|
|
#endif
|
|
}
|
|
namespace exposure_quad
|
|
{
|
|
static grcEffectVar Position;
|
|
}
|
|
#endif
|
|
|
|
// Render Targets
|
|
static grcRenderTarget* HalfScreen0;
|
|
static grcRenderTarget* SSLRCutout;
|
|
static grcRenderTarget* LRIntensity;
|
|
#if BOKEH_SUPPORT
|
|
#if RSG_DURANGO && __BANK
|
|
static grcRenderTarget* AltBokehDepthBlur;
|
|
#endif
|
|
static grcRenderTarget* BokehDepthBlur;
|
|
static grcRenderTarget* BokehDepthBlurHalfRes;
|
|
#if COC_SPREAD
|
|
static grcRenderTarget* BokehDepthBlurHalfResTemp;
|
|
#endif
|
|
static grcRenderTarget* BokehPoints;
|
|
static grcRenderTarget* BokehPointsTemp;
|
|
static grcTexture* BokehNoneRenderedTexture;
|
|
#endif //BOKEH_SUPPORT
|
|
#if DOF_DIFFUSION
|
|
//Should be able to reduce the number needed by added in packing code
|
|
grcRenderTarget* dofDiffusionHorzABC[16];
|
|
grcRenderTarget* dofDiffusionHorzX[16];
|
|
grcRenderTarget* dofDiffusionHorzY[16];
|
|
grcRenderTarget* dofDiffusionVertABC[16];
|
|
grcRenderTarget* dofDiffusionVertX[16];
|
|
grcRenderTarget* dofDiffusionVertY[16];
|
|
#endif
|
|
#if FILM_EFFECT
|
|
static grcRenderTarget* PreFilmEffect;
|
|
#endif
|
|
#if !__PS3
|
|
static grcRenderTarget* LRIntensity2;
|
|
#endif
|
|
|
|
#if RSG_PC
|
|
#define MAX_EXP_TARGETS (3 + MAX_GPUS)
|
|
#define NUM_EXP_TARGETS (3 + GRCDEVICE.GetGPUCount())
|
|
#else
|
|
#define MAX_EXP_TARGETS (3)
|
|
#define NUM_EXP_TARGETS MAX_EXP_TARGETS
|
|
#endif // RSG_PC
|
|
|
|
#if __PPU
|
|
static ALIGNAS(16) float* CurExposureRTBasePtr[MAX_EXP_TARGETS] ;
|
|
#endif
|
|
|
|
#if __XENON
|
|
static ALIGNAS(16) Float16Vec4* CurExposureRTBasePtr[MAX_EXP_TARGETS] ;
|
|
#endif // __PPU || __XENON
|
|
|
|
static grcRenderTarget* LumRT = NULL;
|
|
|
|
#if __D3D11
|
|
static grcTexture* CurExposureTex[MAX_EXP_TARGETS] = {NULL};
|
|
#endif
|
|
static grcRenderTarget* CurExposureRT[MAX_EXP_TARGETS];
|
|
static u32 CurExportRTIndex = 0;
|
|
static bool ExposureInitialised = false;
|
|
static grcTexture* JitterTexture;
|
|
|
|
static grcTexture* HeatHazeTexture;
|
|
|
|
static grcRenderTarget* DepthOfField0;
|
|
static grcRenderTarget* DepthOfField1;
|
|
static grcRenderTarget* DepthOfField2;
|
|
|
|
static grcRenderTarget* HeatHaze0;
|
|
static grcRenderTarget* HeatHaze1;
|
|
|
|
static grcRenderTarget* BloomBuffer;
|
|
static grcRenderTarget* BloomBufferUnfiltered;
|
|
static grcRenderTarget* BloomBufferHalf0;
|
|
static grcRenderTarget* BloomBufferHalf1;
|
|
static grcRenderTarget* BloomBufferQuarter0;
|
|
static grcRenderTarget* BloomBufferQuarter1;
|
|
static grcRenderTarget* BloomBufferEighth0;
|
|
static grcRenderTarget* BloomBufferEighth1;
|
|
static grcRenderTarget* BloomBufferSixteenth0;
|
|
static grcRenderTarget* BloomBufferSixteenth1;
|
|
#if RSG_DURANGO
|
|
static grcRenderTarget* BloomBufferQuarterX;
|
|
|
|
static grcRenderTarget* DSBB2;
|
|
static grcRenderTarget* DSBB4;
|
|
static grcRenderTarget* DSBB8;
|
|
static grcRenderTarget* DSBB16;
|
|
#endif
|
|
|
|
static grcRenderTarget* LensArtefactsFinalBuffer;
|
|
static grcRenderTarget* LensArtefactSrcBuffers[LENSARTEFACT_BUFFER_COUNT];
|
|
static grcRenderTarget* LensArtefactsBuffers0[LENSARTEFACT_BUFFER_COUNT];
|
|
static grcRenderTarget* LensArtefactsBuffers1[LENSARTEFACT_BUFFER_COUNT];
|
|
|
|
static grcVertexDeclaration* sm_FogVertexDeclaration;
|
|
static grcVertexBuffer* sm_FogVertexBuffer;
|
|
|
|
#if BOKEH_SUPPORT
|
|
static u32 s_BokehAllocatedSize = 0;
|
|
static u32 s_BokehMaxElements = 0;
|
|
#if RSG_PC
|
|
static const u32 s_BokehBufferStride = 36;
|
|
#else
|
|
static const u32 s_BokehBufferStride = 32;
|
|
#endif
|
|
static const u32 s_BokehIndexListBufferStride = 8;
|
|
static const u32 s_BokehBucketsNumAddedBufferStride = 4;
|
|
|
|
static grcEffectVar BokehSortOffsetsBufferVar;
|
|
static grcEffectVar BokehSortedBufferVar;
|
|
|
|
# if RSG_ORBIS
|
|
static grcEffectVar BokehOutputPointBufferVar;
|
|
static grcBufferUAV s_BokehAccumBuffer( grcBuffer_Structured, true );
|
|
static grcBufferBasic s_indirectArgsBuffer( grcBuffer_Raw, true );
|
|
static grcBufferUAV s_BokehIndexListBuffer( grcBuffer_Structured, true );
|
|
static grcBufferUAV s_bokehNumAddedToBuckets( grcBuffer_Structured, true );
|
|
static grcBufferUAV s_bokehSortedIndexListBuffer( grcBuffer_Structured, true );
|
|
#if BOKEH_SORT_BITONIC_TRANSPOSE
|
|
static grcBufferUAV s_bokehSortedIndexListBuffer2( grcBuffer_Structured, true );
|
|
#endif //BOKEH_SORT_BITONIC_TRANSPOSE
|
|
# else //RSG_ORBIS
|
|
|
|
# if RSG_DURANGO
|
|
static grcEffectVar BokehOutputPointBufferVar;
|
|
# endif
|
|
static grcBufferUAV s_BokehAccumBuffer;
|
|
static grcBufferBasic s_indirectArgsBuffer;
|
|
static grcBufferUAV s_BokehIndexListBuffer;
|
|
static grcBufferUAV s_bokehNumAddedToBuckets;
|
|
static grcBufferUAV s_bokehSortedIndexListBuffer;
|
|
#if BOKEH_SORT_BITONIC_TRANSPOSE
|
|
static grcBufferUAV s_bokehSortedIndexListBuffer2;
|
|
#endif //BOKEH_SORT_BITONIC_TRANSPOSE
|
|
static u32 s_curAddedBucket = 0;
|
|
# endif //RSG_ORBIS
|
|
|
|
#if __BANK
|
|
sysTimer s_BokehRenderCountTimer;
|
|
#endif
|
|
#endif //BOKEH_SUPPORT
|
|
|
|
#if RSG_ORBIS
|
|
static grcBufferUAV s_GaussianWeightsBuffer( grcBuffer_Structured, true );
|
|
static grcBufferUAV s_GaussianWeightsCOCBuffer( grcBuffer_Structured, true );
|
|
#else
|
|
static grcBufferUAV s_GaussianWeightsBuffer;
|
|
static grcBufferUAV s_GaussianWeightsCOCBuffer;
|
|
#endif
|
|
|
|
|
|
#if FXAA_CUSTOM_TUNING
|
|
static grcEffectVar fxaaBlurinessId;
|
|
static grcEffectVar fxaaConsoleEdgeSharpnessId;
|
|
static grcEffectVar fxaaConsoleEdgeThresholdId;
|
|
static grcEffectVar fxaaConsoleEdgeThresholdMinId;
|
|
static grcEffectVar fxaaQualitySubpixId;
|
|
static grcEffectVar fxaaEdgeThresholdId;
|
|
static grcEffectVar fxaaEdgeThresholdMinId;
|
|
|
|
static float fxaaBluriness;
|
|
static float fxaaConsoleEdgeSharpness;
|
|
static float fxaaConsoleEdgeThreshold;
|
|
static float fxaaConsoleEdgeThresholdMin;
|
|
static float fxaaQualitySubpix;
|
|
static float fxaaEdgeThreshold;
|
|
static float fxaaEdgeThresholdMin;
|
|
#endif
|
|
|
|
bool g_fpvMotionBlurEnable = false;
|
|
bool g_fpvMotionBlurEnableInVehicle = false;
|
|
bool g_fpvMotionBlurEnableDynamicUpdate = false;
|
|
bool g_fpvMotionBlurDrawDebug = false;
|
|
bool g_fpvMotionBlurOverrideTagData = false;
|
|
grcRenderTarget* fpvMotionBlurTarget[2];
|
|
|
|
|
|
static Vector4 fpvMotionBlurWeights;
|
|
static float fpvMotionBlurSize;
|
|
static float fpvMotionVelocityMaxSize;
|
|
|
|
static Vec2V fpvMotionBlurVelocity;
|
|
static Vec3V fpvMotionBlurPrevCameraPos[2];
|
|
static Mat44V fpvMotionBlurPrevModelViewMtx;
|
|
|
|
static bool fpvMotionBlurFirstFrame;
|
|
|
|
static Vec3V fpvMotionBlurCurrCameraPos;
|
|
|
|
static grcEffectVar fpvMotionBlurWeightsId;
|
|
static grcEffectVar fpvMotionBlurVelocityId;
|
|
static grcEffectVar fpvMotionBlurSizeId;
|
|
|
|
|
|
#if BOKEH_SUPPORT || DOF_COMPUTE_GAUSSIAN
|
|
void InitBokehDOF();
|
|
#endif // BOKEH_SUPPORT || DOF_COMPUTE_GAUSSIAN
|
|
|
|
|
|
#if USE_SCREEN_WATERMARK
|
|
static grcBlendStateHandle ms_watermarkBlendState = grcStateBlock::BS_Invalid;
|
|
static PostFX::WatermarkParams ms_watermarkParams;
|
|
|
|
void PostFX::WatermarkParams::Init()
|
|
{
|
|
alphaDay = 0.25f;
|
|
alphaNight = 0.055f;
|
|
textColor = Color32(255, 255, 255, 64);
|
|
textSize = 4.0f;
|
|
textPos = Vector2(0.135f, 3.894f);
|
|
#if DISPLAY_NETWORK_INFO
|
|
netTextColor = Color32(255, 255, 255, 64);
|
|
netTextSize = 0.9f;
|
|
netTextPos = Vector2(0.398f, 0.51f);
|
|
#endif
|
|
useOutline = true;
|
|
|
|
if (CHudTools::GetWideScreen() == false)
|
|
{
|
|
textPos.x = 0.187f;
|
|
}
|
|
|
|
text[0] = 0;
|
|
#if __BANK
|
|
bForceWatermark = false;
|
|
bUseDebugText = false;
|
|
debugText[0] = 0;
|
|
#endif
|
|
|
|
}
|
|
#endif // USE_PHOTO_WATERMARK
|
|
|
|
static bool g_bRunBlurVignettingTiled = (0 && (RSG_ORBIS || RSG_DURANGO));
|
|
|
|
// If you change this, don't forget to change the following string array.
|
|
//
|
|
enum PostFXPass
|
|
{
|
|
pp_lum_4x3_conversion,
|
|
pp_lum_4x3,
|
|
pp_lum_4x5,
|
|
pp_lum_5x5,
|
|
pp_lum_2x2,
|
|
pp_lum_3x3,
|
|
pp_min,
|
|
pp_max,
|
|
pp_maxx,
|
|
pp_maxy,
|
|
pp_composite,
|
|
pp_composite_mb,
|
|
pp_composite_highdof,
|
|
pp_composite_mb_highdof,
|
|
pp_composite_noise,
|
|
pp_composite_mb_noise,
|
|
pp_composite_highdof_noise,
|
|
pp_composite_mb_highdof_noise,
|
|
pp_composite_nv,
|
|
pp_composite_mb_nv,
|
|
pp_composite_highdof_nv,
|
|
pp_composite_mb_highdof_nv,
|
|
pp_composite_hh,
|
|
pp_composite_mb_hh,
|
|
pp_composite_highdof_hh,
|
|
pp_composite_mb_highdof_hh,
|
|
pp_composite_noise_hh,
|
|
pp_composite_mb_noise_hh,
|
|
pp_composite_highdof_noise_hh,
|
|
pp_composite_mb_highdof_noise_hh,
|
|
pp_composite_nv_hh,
|
|
pp_composite_mb_nv_hh,
|
|
pp_composite_highdof_nv_hh,
|
|
pp_composite_mb_highdof_nv_hh,
|
|
pp_composite_shallowhighdof,
|
|
pp_composite_mb_shallowhighdof,
|
|
pp_composite_noise_shallowhighdof,
|
|
pp_composite_noise_mb_shallowhighdof,
|
|
pp_composite_shallowhighdof_nv,
|
|
pp_composite_mb_shallowhighdof_nv,
|
|
pp_composite_shallowhighdof_hh,
|
|
pp_composite_mb_shallowhighdof_hh,
|
|
pp_composite_noise_shallowhighdof_hh,
|
|
pp_composite_noise_mb_shallowhighdof_hh,
|
|
pp_composite_shallowhighdof_nv_hh,
|
|
pp_composite_mb_shallowhighdof_nv_hh,
|
|
pp_composite_ee,
|
|
pp_composite_mb_ee,
|
|
pp_composite_highdof_ee,
|
|
pp_composite_mb_highdof_ee,
|
|
pp_composite_hh_ee,
|
|
pp_composite_mb_hh_ee,
|
|
pp_composite_highdof_hh_ee,
|
|
pp_composite_mb_highdof_hh_ee,
|
|
pp_composite_shallowhighdof_ee,
|
|
pp_composite_mb_shallowhighdof_ee,
|
|
pp_composite_shallowhighdof_hh_ee,
|
|
pp_composite_mb_shallowhighdof_hh_ee,
|
|
pp_composite_seethrough,
|
|
pp_composite_tiled,
|
|
pp_composite_tiled_noblur,
|
|
pp_depthfx,
|
|
pp_depthfx_tiled,
|
|
#if RSG_PC
|
|
pp_depthfx_nogather,
|
|
pp_depthfx_tiled_nogather,
|
|
#endif
|
|
pp_simple,
|
|
pp_passthrough,
|
|
pp_lightrays1,
|
|
pp_sslrcutout,
|
|
pp_sslrcutout_tiled,
|
|
pp_sslrextruderays,
|
|
pp_fogray,
|
|
pp_fogray_high,
|
|
#if RSG_PC
|
|
pp_fogray_nogather,
|
|
pp_fogray_high_nogather,
|
|
#endif
|
|
pp_shadowmapblit,
|
|
pp_calcbloom0,
|
|
pp_calcbloom1,
|
|
pp_calcbloom_seethrough,
|
|
pp_sslrblur,
|
|
pp_subsampleAlpha,
|
|
pp_subsampleAlphaSinglePass,
|
|
pp_DownSampleBloom,
|
|
pp_DownSampleStencil,
|
|
pp_DownSampleCoc,
|
|
pp_Blur,
|
|
pp_DOFCoC,
|
|
pp_HeatHaze,
|
|
pp_HeatHaze_Tiled,
|
|
pp_HeatHazeDilateBinary,
|
|
pp_HeatHazeDilate,
|
|
pp_HeatHazeWater,
|
|
pp_GaussBlur_Hor,
|
|
pp_GaussBlur_Ver,
|
|
pp_BloomComposite,
|
|
pp_BloomComposite_SeeThrough,
|
|
pp_gradientfilter,
|
|
pp_scanlinefilter,
|
|
pp_AA,
|
|
#if RSG_PC
|
|
pp_AA_sm50,
|
|
#endif
|
|
#if __PS3
|
|
pp_AA_720p,
|
|
#endif
|
|
pp_UIAA,
|
|
pp_JustExposure,
|
|
pp_CopyDepth,
|
|
pp_DamageOverlay,
|
|
pp_exposure,
|
|
pp_exposure_reset,
|
|
pp_copy,
|
|
#if !__FINAL
|
|
pp_exposure_set,
|
|
#endif
|
|
pp_composite_highdof_blur_tiled,
|
|
pp_composite_highdof_noblur_tiled,
|
|
pp_subsampleAlphaUI,
|
|
pp_lens_distortion,
|
|
pp_lens_artefacts,
|
|
pp_lens_artefacts_combined,
|
|
pp_light_streaks_blur_low,
|
|
pp_light_streaks_blur_med,
|
|
pp_light_streaks_blur_high,
|
|
pp_blur_vignetting,
|
|
pp_blur_vignetting_tiled,
|
|
pp_blur_vignetting_blur_hor_tiled,
|
|
pp_blur_vignetting_blur_ver_tiled,
|
|
pp_bloom_min,
|
|
pp_motion_blur_fpv,
|
|
pp_motion_blur_fpv_ds,
|
|
pp_motion_blur_fpv_composite,
|
|
pp_GaussBlurBilateral_Hor,
|
|
pp_GaussBlurBilateral_Ver,
|
|
pp_GaussBlurBilateral_Hor_High,
|
|
pp_GaussBlurBilateral_Ver_High,
|
|
#if RSG_PC
|
|
pp_centerdist,
|
|
#endif
|
|
pp_count
|
|
};
|
|
|
|
#if AVG_LUMINANCE_COMPUTE
|
|
enum PostFXAvgLuminancePass
|
|
{
|
|
pp_luminance_downsample_init,
|
|
pp_luminance_downsample,
|
|
count
|
|
};
|
|
#endif
|
|
|
|
#if BOKEH_SUPPORT
|
|
enum PostFXBokehPass
|
|
{
|
|
pp_Bokeh_DepthBlur, //generates target containing linear depth and blurred backbuffer
|
|
#if ADAPTIVE_DOF_GPU
|
|
pp_Bokeh_DepthBlurAdaptive, //generates COC differently when using adaptive dof
|
|
#endif
|
|
pp_Bokeh_DepthBlurDownsample,
|
|
pp_Bokeh_Generation, //determines where bokeh should be applied
|
|
pp_Bokeh_Sprites, //Draw bokeh sprites with geometry shader
|
|
#if ADAPTIVE_DOF_OUTPUT_UAV
|
|
pp_Bokeh_Sprites_Adaptive,
|
|
#endif
|
|
pp_Bokeh_Downsample, //Downsample backbuffer for use with Bokeh
|
|
pp_Bokeh_count
|
|
};
|
|
#endif // BOKEH_SUPPORT
|
|
|
|
enum PostFXCompute
|
|
{
|
|
pp_Bokeh_ComputeBitonicSort = 0
|
|
#if BOKEH_SORT_BITONIC_TRANSPOSE
|
|
, pp_Bokeh_ComputeBitonicSortTranspose
|
|
#endif //BOKEH_SORT_BITONIC_TRANSPOSE
|
|
};
|
|
|
|
#if DOF_DIFFUSION
|
|
enum PostFXDofDiffusionPass
|
|
{
|
|
//Vertical Phase
|
|
pp_DOF_Diffusion_InitialReduceVert4,
|
|
pp_DOF_Diffusion_ReduceVert,
|
|
pp_DOF_Diffusion_ReduceFinalVert2,
|
|
pp_DOF_Diffusion_ReduceFinalVert3,
|
|
pp_DOF_Diffusion_SolveVert,
|
|
pp_DOF_FinalSolveVert4,
|
|
//Horizontal Phase
|
|
pp_DOF_Diffusion_InitialReduceHorz4,
|
|
pp_DOF_Diffusion_ReduceHorz,
|
|
pp_DOF_Diffusion_ReduceFinalHorz2,
|
|
pp_DOF_Diffusion_ReduceFinalHorz3,
|
|
pp_DOF_Diffusion_SolveHorz,
|
|
pp_DOF_FinalSolveHorz4,
|
|
|
|
pp_DOF_Diffusion_count
|
|
};
|
|
#endif
|
|
|
|
#if DOF_COMPUTE_GAUSSIAN
|
|
enum PostFXDofComputeGaussianPass
|
|
{
|
|
#if COC_SPREAD
|
|
pp_DOF_ComputeGaussian_COCSpread_H,
|
|
pp_DOF_ComputeGaussian_COCSpread_V,
|
|
#endif
|
|
pp_DOF_ComputeGaussian_Blur_H,
|
|
pp_DOF_ComputeGaussian_Blur_V,
|
|
#if ADAPTIVE_DOF_OUTPUT_UAV
|
|
pp_DOF_ComputeGaussian_Blur_H_Adaptive,
|
|
pp_DOF_ComputeGaussian_Blur_V_Adaptive,
|
|
pp_DOF_ComputeGaussian_Blur_H_Adaptive_LumFilter,
|
|
#endif //ADAPTIVE_DOF_OUTPUT_UAV
|
|
pp_DOF_ComputeGaussian_Blur_H_LumFilter,
|
|
pp_DOF_ComputeGaussian_MSAA_Blend,
|
|
pp_DOF_ComputeGaussian_MSAA_BlendMS0,
|
|
#if ADAPTIVE_DOF_OUTPUT_UAV
|
|
pp_DOF_ComputeGaussian_MSAA_Blend_Adaptive,
|
|
pp_DOF_ComputeGaussian_MSAA_Blend_AdaptiveMS0,
|
|
#endif //ADAPTIVE_DOF_OUTPUT_UAV
|
|
pp_DOF_ComputeGaussian_COC_Overlay, //!__SHADER_FINAL
|
|
#if ADAPTIVE_DOF_OUTPUT_UAV
|
|
pp_DOF_ComputeGaussian_COC_Overlay_Adaptive //!__SHADER_FINAL
|
|
#endif //ADAPTIVE_DOF_OUTPUT_UAV
|
|
};
|
|
#endif
|
|
|
|
#if FILM_EFFECT
|
|
enum PostFXFilmEffectPass
|
|
{
|
|
pp_filmeffect,
|
|
pp_filmeffectcount,
|
|
};
|
|
#endif
|
|
|
|
#if RAGE_TIMEBARS || ENABLE_PIX_TAGGING
|
|
const char * passName[] = {
|
|
"pp_lum_4x3_conversion",
|
|
"pp_lum_4x3",
|
|
"pp_lum_4x5",
|
|
"pp_lum_5x5",
|
|
"pp_lum_2x2",
|
|
"pp_lum_3x3",
|
|
"pp_min",
|
|
"pp_max",
|
|
"pp_maxx",
|
|
"pp_maxy",
|
|
"pp_composite",
|
|
"pp_composite_mb",
|
|
"pp_composite_highdof",
|
|
"pp_composite_mb_highdof",
|
|
"pp_composite_noise",
|
|
"pp_composite_mb_noise",
|
|
"pp_composite_highdof_noise",
|
|
"pp_composite_mb_highdof_noise",
|
|
"pp_composite_nv",
|
|
"pp_composite_mb_nv",
|
|
"pp_composite_highdof_nv",
|
|
"pp_composite_mb_highdof_nv",
|
|
"pp_composite_hh",
|
|
"pp_composite_mb_hh",
|
|
"pp_composite_highdof_hh",
|
|
"pp_composite_mb_highdof_hh",
|
|
"pp_composite_noise_hh",
|
|
"pp_composite_mb_noise_hh",
|
|
"pp_composite_highdof_noise_hh",
|
|
"pp_composite_mb_highdof_noise_hh",
|
|
"pp_composite_nv_hh",
|
|
"pp_composite_mb_nv_hh",
|
|
"pp_composite_highdof_nv_hh",
|
|
"pp_composite_mb_highdof_nv_hh",
|
|
"pp_composite_shallowhighdof",
|
|
"pp_composite_mb_shallowhighdof",
|
|
"pp_composite_noise_shallowhighdof",
|
|
"pp_composite_noise_mb_shallowhighdof",
|
|
"pp_composite_shallowhighdof_nv",
|
|
"pp_composite_mb_shallowhighdof_nv",
|
|
"pp_composite_shallowhighdof_hh",
|
|
"pp_composite_mb_shallowhighdof_hh",
|
|
"pp_composite_noise_shallowhighdof_hh",
|
|
"pp_composite_noise_mb_shallowhighdof_hh",
|
|
"pp_composite_shallowhighdof_nv_hh",
|
|
"pp_composite_mb_shallowhighdof_nv_hh",
|
|
"pp_composite_ee",
|
|
"pp_composite_mb_ee",
|
|
"pp_composite_highdof_ee",
|
|
"pp_composite_mb_highdof_ee",
|
|
"pp_composite_hh_ee",
|
|
"pp_composite_mb_hh_ee",
|
|
"pp_composite_highdof_hh_ee",
|
|
"pp_composite_mb_highdof_hh_ee",
|
|
"pp_composite_shallowhighdof_ee",
|
|
"pp_composite_mb_shallowhighdof_ee",
|
|
"pp_composite_shallowhighdof_hh_ee",
|
|
"pp_composite_mb_shallowhighdof_hh_ee",
|
|
"pp_composite_seethrough",
|
|
"pp_composite_tiled",
|
|
"pp_composite_tiled_noblur",
|
|
"pp_depthfx",
|
|
"pp_depthfx_tiled",
|
|
#if RSG_PC
|
|
"pp_depthfx_nogather",
|
|
"pp_depthfx_tiled",
|
|
#endif
|
|
"pp_simple",
|
|
"pp_passthrough",
|
|
"pp_lightrays1",
|
|
"pp_sslrcutout",
|
|
"pp_sslrcutout_tiled",
|
|
"pp_sslrextruderays",
|
|
"pp_fogray",
|
|
"pp_fogray_high",
|
|
#if RSG_PC
|
|
"pp_fogray_nogather",
|
|
"pp_fogray_high_nogather",
|
|
#endif
|
|
"pp_shadowmapblit",
|
|
"pp_calcbloom0",
|
|
"pp_calcbloom1",
|
|
"pp_calcbloom_seethrough",
|
|
"pp_sslrblur",
|
|
"pp_subsampleAlpha",
|
|
"pp_subsampleAlphaSinglePass",
|
|
"pp_DownSampleBloom",
|
|
"pp_DownSampleStencil",
|
|
"pp_DownSampleCoc",
|
|
"pp_Blur",
|
|
"pp_DOFCoC",
|
|
"pp_HeatHaze",
|
|
"pp_HeatHaze_Tiled",
|
|
"pp_HeatHazeDilateBinary",
|
|
"pp_HeatHazeDilate",
|
|
"pp_HeatHazeWater",
|
|
"pp_GaussBlur_Hor",
|
|
"pp_GaussBlur_Ver",
|
|
"pp_BloomComposite",
|
|
"pp_BloomComposite_SeeThrough",
|
|
"pp_gradientfilter",
|
|
"pp_scanlinefilter",
|
|
"pp_AA",
|
|
#if RSG_PC
|
|
"pp_AA_sm50",
|
|
#endif
|
|
#if __PS3
|
|
"pp_AA_720p",
|
|
#endif
|
|
"pp_UIAA",
|
|
"pp_JustExposure",
|
|
"pp_CopyDepth",
|
|
"pp_DamageOverlay",
|
|
"pp_exposure",
|
|
"pp_exposure_reset",
|
|
"pp_copy",
|
|
#if !__FINAL
|
|
"pp_exposure_set",
|
|
#endif
|
|
"pp_composite_highdof_blur_tiled",
|
|
"pp_composite_highdof_noblur_tiled",
|
|
"pp_subsampleAlphaUI",
|
|
"pp_lens_distortion",
|
|
"pp_lens_artefacts",
|
|
"pp_lens_artefacts_combined",
|
|
"pp_light_streaks_blur_low",
|
|
"pp_light_streaks_blur_med",
|
|
"pp_light_streaks_blur_high",
|
|
"pp_blur_vignetting",
|
|
"pp_blur_vignetting_tiled",
|
|
"pp_blur_vignetting_blur_hor_tiled",
|
|
"pp_blur_vignetting_blur_ver_tiled",
|
|
"pp_bloom_min",
|
|
"pp_motion_blur_fpv",
|
|
"pp_motion_blur_fpv_ds",
|
|
"pp_motion_blur_fpv_composite",
|
|
"pp_GaussBlurBilateral_Hor",
|
|
"pp_GaussBlurBilateral_Ver",
|
|
"pp_GaussBlurBilateral_Hor_High",
|
|
"pp_GaussBlurBilateral_Ver_High"
|
|
#if RSG_PC
|
|
,"pp_centerdist"
|
|
#endif
|
|
};
|
|
|
|
CompileTimeAssert(NELEM(passName) == pp_count);
|
|
|
|
#if BOKEH_SUPPORT
|
|
const char * bokehPassName[pp_Bokeh_count] = {
|
|
"pp_BokehDepthBlur",
|
|
#if ADAPTIVE_DOF_GPU
|
|
"pp_BokehDepthBlurAdaptive",
|
|
#endif
|
|
"pp_BokehDepthBlurDownsample",
|
|
"pp_BokehGeneration",
|
|
"pp_BokehSprites",
|
|
#if ADAPTIVE_DOF_OUTPUT_UAV
|
|
"pp_BokehSprites_Adaptive",
|
|
#endif //ADAPTIVE_DOF_OUTPUT_UAV
|
|
"pp_Bokeh_Downsample"
|
|
};
|
|
|
|
CompileTimeAssert(NELEM(bokehPassName) == pp_Bokeh_count);
|
|
#endif // BOKEH_SUPPORT
|
|
|
|
#if FILM_EFFECT
|
|
const char * filmEffectPassName[pp_filmeffectcount] = {
|
|
"pp_filmeffect",
|
|
};
|
|
#endif
|
|
|
|
#endif // RAGE_TIMEBARS
|
|
|
|
enum dofTechniques
|
|
{
|
|
dof_console,
|
|
#if DOF_COMPUTE_GAUSSIAN || DOF_DIFFUSION
|
|
dof_computeGaussian,
|
|
dof_diffusion,
|
|
#endif
|
|
dof_count
|
|
};
|
|
dofTechniques CurrentDOFTechnique;
|
|
|
|
#if DOF_TYPE_CHANGEABLE_IN_RAG
|
|
bool ProcessDOFChangeOnRenderThread = false;
|
|
|
|
const char * dofTechniqueNames[dof_count] = {
|
|
"Console"
|
|
#if DOF_COMPUTE_GAUSSIAN || DOF_DIFFUSION
|
|
,
|
|
"Gaussian Compute Shader",
|
|
"Diffusion"
|
|
#endif
|
|
};
|
|
|
|
CompileTimeAssert(NELEM(dofTechniqueNames) == dof_count);
|
|
#endif // DOF_TYPE_CHANGEABLE_IN_RAG
|
|
|
|
#define BM_MotionBlur (0x00001)
|
|
#define BM_HighDof (0x00002)
|
|
#define BM_NightVision (0x00004)
|
|
#define BM_Noise (0x00008)
|
|
#define BM_HeatHaze (0x00010)
|
|
#define BM_HighDofShallow (0x00020)
|
|
#define BM_ExtraEffects (0x00040)
|
|
|
|
#define UseAll (BM_ExtraEffects | BM_HighDofShallow | BM_HeatHaze | BM_Noise | BM_NightVision | BM_HighDof | BM_MotionBlur)
|
|
|
|
static PostFXPass PassLookupTable[UseAll+1] = {
|
|
/* EE0 SD0 HH0 NN0 NV0 HD0 MB0*/ pp_composite, //00
|
|
/* EE0 SD0 HH0 NN0 NV0 HD0 MB1*/ pp_composite_mb, //01
|
|
/* EE0 SD0 HH0 NN0 NV0 HD1 MB0*/ pp_composite_highdof, //02
|
|
/* EE0 SD0 HH0 NN0 NV0 HD1 MB1*/ pp_composite_mb_highdof, //03
|
|
/* EE0 SD0 HH0 NN0 NV1 HD0 MB0*/ pp_composite_nv, //04
|
|
/* EE0 SD0 HH0 NN0 NV1 HD0 MB1*/ pp_composite_mb_nv, //05
|
|
/* EE0 SD0 HH0 NN0 NV1 HD1 MB0*/ pp_composite_highdof_nv, //06
|
|
/* EE0 SD0 HH0 NN0 NV1 HD1 MB1*/ pp_composite_mb_highdof_nv, //07
|
|
/* EE0 SD0 HH0 NN1 NV0 HD0 MB0*/ pp_composite_noise, //08
|
|
/* EE0 SD0 HH0 NN1 NV0 HD0 MB1*/ pp_composite_mb_noise, //09
|
|
/* EE0 SD0 HH0 NN1 NV0 HD1 MB0*/ pp_composite_highdof_noise, //10
|
|
/* EE0 SD0 HH0 NN1 NV0 HD1 MB1*/ pp_composite_mb_highdof_noise, //11
|
|
/* EE0 SD0 HH0 NN1 NV1 HD0 MB0*/ pp_composite_nv, //12 Nightvision is always noisy...
|
|
/* EE0 SD0 HH0 NN1 NV1 HD0 MB1*/ pp_composite_mb_nv, //13 Nightvision is always noisy...
|
|
/* EE0 SD0 HH0 NN1 NV1 HD1 MB0*/ pp_composite_highdof_nv, //14 Nightvision is always noisy...
|
|
/* EE0 SD0 HH0 NN1 NV1 HD1 MB1*/ pp_composite_mb_highdof_nv, //15 Nightvision is always noisy...
|
|
/* EE0 SD0 HH1 NN0 NV0 HD0 MB0*/ pp_composite_hh, //16
|
|
/* EE0 SD0 HH1 NN0 NV0 HD0 MB1*/ pp_composite_mb_hh, //17
|
|
/* EE0 SD0 HH1 NN0 NV0 HD1 MB0*/ pp_composite_highdof_hh, //18
|
|
/* EE0 SD0 HH1 NN0 NV0 HD1 MB1*/ pp_composite_mb_highdof_hh, //19
|
|
/* EE0 SD0 HH1 NN0 NV1 HD0 MB0*/ pp_composite_nv_hh, //20
|
|
/* EE0 SD0 HH1 NN0 NV1 HD0 MB1*/ pp_composite_mb_nv_hh, //21
|
|
/* EE0 SD0 HH1 NN0 NV1 HD1 MB0*/ pp_composite_highdof_nv_hh, //22
|
|
/* EE0 SD0 HH1 NN0 NV1 HD1 MB1*/ pp_composite_mb_highdof_nv_hh, //23
|
|
/* EE0 SD0 HH1 NN1 NV0 HD0 MB0*/ pp_composite_noise_hh, //24
|
|
/* EE0 SD0 HH1 NN1 NV0 HD0 MB1*/ pp_composite_mb_noise_hh, //25
|
|
/* EE0 SD0 HH1 NN1 NV0 HD1 MB0*/ pp_composite_highdof_noise_hh, //26
|
|
/* EE0 SD0 HH1 NN1 NV0 HD1 MB1*/ pp_composite_mb_highdof_noise_hh, //27
|
|
/* EE0 SD0 HH1 NN1 NV1 HD0 MB0*/ pp_composite_nv_hh, //28 Nightvision is always noisy...
|
|
/* EE0 SD0 HH1 NN1 NV1 HD0 MB1*/ pp_composite_mb_nv_hh, //29 Nightvision is always noisy...
|
|
/* EE0 SD0 HH1 NN1 NV1 HD1 MB0*/ pp_composite_highdof_nv_hh, //30 Nightvision is always noisy...
|
|
/* EE0 SD0 HH1 NN1 NV1 HD1 MB1*/ pp_composite_mb_highdof_nv_hh, //31 Nightvision is always noisy...
|
|
/* EE0 SD1 HH0 NN0 NV0 HD0 MB0*/ pp_composite_shallowhighdof, //32
|
|
/* EE0 SD1 HH0 NN0 NV0 HD0 MB1*/ pp_composite_mb_shallowhighdof, //33
|
|
/* EE0 SD1 HH0 NN0 NV0 HD1 MB0*/ pp_composite_shallowhighdof_nv, //34
|
|
/* EE0 SD1 HH0 NN0 NV0 HD1 MB1*/ pp_composite_mb_shallowhighdof, //35
|
|
/* EE0 SD1 HH0 NN0 NV1 HD0 MB0*/ pp_composite_shallowhighdof_nv, //36
|
|
/* EE0 SD1 HH0 NN0 NV1 HD0 MB1*/ pp_composite_mb_shallowhighdof_nv, //37
|
|
/* EE0 SD1 HH0 NN0 NV1 HD1 MB0*/ pp_composite_shallowhighdof_nv, //38
|
|
/* EE0 SD1 HH0 NN0 NV1 HD1 MB1*/ pp_composite_mb_shallowhighdof_nv, //39
|
|
/* EE0 SD1 HH0 NN1 NV0 HD0 MB0*/ pp_composite_noise_shallowhighdof, //40
|
|
/* EE0 SD1 HH0 NN1 NV0 HD0 MB1*/ pp_composite_noise_mb_shallowhighdof, //41
|
|
/* EE0 SD1 HH0 NN1 NV0 HD1 MB0*/ pp_composite_noise_shallowhighdof, //42
|
|
/* EE0 SD1 HH0 NN1 NV0 HD1 MB1*/ pp_composite_noise_mb_shallowhighdof, //43
|
|
/* EE0 SD1 HH0 NN1 NV1 HD0 MB0*/ pp_composite_shallowhighdof_nv, //44
|
|
/* EE0 SD1 HH0 NN1 NV1 HD0 MB1*/ pp_composite_mb_shallowhighdof_nv, //45
|
|
/* EE0 SD1 HH0 NN1 NV1 HD1 MB0*/ pp_composite_shallowhighdof_nv, //46
|
|
/* EE0 SD1 HH0 NN1 NV1 HD1 MB1*/ pp_composite_mb_shallowhighdof_nv, //47
|
|
/* EE0 SD1 HH1 NN0 NV0 HD0 MB0*/ pp_composite_shallowhighdof_hh, //48
|
|
/* EE0 SD1 HH1 NN0 NV0 HD0 MB1*/ pp_composite_mb_shallowhighdof_hh, //49
|
|
/* EE0 SD1 HH1 NN0 NV0 HD1 MB0*/ pp_composite_shallowhighdof_hh, //50
|
|
/* EE0 SD1 HH1 NN0 NV0 HD1 MB1*/ pp_composite_mb_shallowhighdof_hh, //51
|
|
/* EE0 SD1 HH1 NN0 NV1 HD0 MB0*/ pp_composite_shallowhighdof_nv_hh, //52
|
|
/* EE0 SD1 HH1 NN0 NV1 HD0 MB1*/ pp_composite_mb_shallowhighdof_nv_hh, //53
|
|
/* EE0 SD1 HH1 NN0 NV1 HD1 MB0*/ pp_composite_shallowhighdof_nv_hh, //54
|
|
/* EE0 SD1 HH1 NN0 NV1 HD1 MB1*/ pp_composite_mb_shallowhighdof_nv_hh, //55
|
|
/* EE0 SD1 HH1 NN1 NV0 HD0 MB0*/ pp_composite_noise_shallowhighdof_hh, //56
|
|
/* EE0 SD1 HH1 NN1 NV0 HD0 MB1*/ pp_composite_noise_mb_shallowhighdof_hh, //57
|
|
/* EE0 SD1 HH1 NN1 NV0 HD1 MB0*/ pp_composite_noise_shallowhighdof_hh, //58
|
|
/* EE0 SD1 HH1 NN1 NV0 HD1 MB1*/ pp_composite_noise_mb_shallowhighdof_hh, //59
|
|
/* EE0 SD1 HH1 NN1 NV1 HD0 MB0*/ pp_composite_shallowhighdof_nv_hh, //60
|
|
/* EE0 SD1 HH1 NN1 NV1 HD0 MB1*/ pp_composite_mb_shallowhighdof_nv_hh, //61
|
|
/* EE0 SD1 HH1 NN1 NV1 HD1 MB0*/ pp_composite_shallowhighdof_nv_hh, //63
|
|
/* EE0 SD1 HH1 NN1 NV1 HD1 MB1*/ pp_composite_mb_shallowhighdof_nv_hh, //63
|
|
/* EE1 SD0 HH0 NN0 NV0 HD0 MB0*/ pp_composite_ee, //64
|
|
/* EE1 SD0 HH0 NN0 NV0 HD0 MB1*/ pp_composite_mb_ee, //65
|
|
/* EE1 SD0 HH0 NN0 NV0 HD1 MB0*/ pp_composite_highdof_ee, //66
|
|
/* EE1 SD0 HH0 NN0 NV0 HD1 MB1*/ pp_composite_mb_highdof_ee, //67
|
|
/* EE1 SD0 HH0 NN0 NV1 HD0 MB0*/ pp_composite_nv, //68
|
|
/* EE1 SD0 HH0 NN0 NV1 HD0 MB1*/ pp_composite_mb_nv, //69
|
|
/* EE1 SD0 HH0 NN0 NV1 HD1 MB0*/ pp_composite_highdof_nv, //70
|
|
/* EE1 SD0 HH0 NN0 NV1 HD1 MB1*/ pp_composite_mb_highdof_nv, //71
|
|
/* EE1 SD0 HH0 NN1 NV0 HD0 MB0*/ pp_composite_ee, //72 Extra effects passes always include noise
|
|
/* EE1 SD0 HH0 NN1 NV0 HD0 MB1*/ pp_composite_mb_ee, //73
|
|
/* EE1 SD0 HH0 NN1 NV0 HD1 MB0*/ pp_composite_highdof_ee, //74
|
|
/* EE1 SD0 HH0 NN1 NV0 HD1 MB1*/ pp_composite_mb_highdof_ee, //75
|
|
/* EE1 SD0 HH0 NN1 NV1 HD0 MB0*/ pp_composite_nv, //76 Nightvision is always noisy...
|
|
/* EE1 SD0 HH0 NN1 NV1 HD0 MB1*/ pp_composite_mb_nv, //77 Nightvision is always noisy...
|
|
/* EE1 SD0 HH0 NN1 NV1 HD1 MB0*/ pp_composite_highdof_nv, //78 Nightvision is always noisy...
|
|
/* EE1 SD0 HH0 NN1 NV1 HD1 MB1*/ pp_composite_mb_highdof_nv, //79 Nightvision is always noisy...
|
|
/* EE1 SD0 HH1 NN0 NV0 HD0 MB0*/ pp_composite_hh_ee, //80
|
|
/* EE1 SD0 HH1 NN0 NV0 HD0 MB1*/ pp_composite_mb_hh_ee, //81
|
|
/* EE1 SD0 HH1 NN0 NV0 HD1 MB0*/ pp_composite_highdof_hh_ee, //82
|
|
/* EE1 SD0 HH1 NN0 NV0 HD1 MB1*/ pp_composite_mb_highdof_hh_ee, //83
|
|
/* EE1 SD0 HH1 NN0 NV1 HD0 MB0*/ pp_composite_nv_hh, //84
|
|
/* EE1 SD0 HH1 NN0 NV1 HD0 MB1*/ pp_composite_mb_nv_hh, //85
|
|
/* EE1 SD0 HH1 NN0 NV1 HD1 MB0*/ pp_composite_highdof_nv_hh, //86
|
|
/* EE1 SD0 HH1 NN0 NV1 HD1 MB1*/ pp_composite_mb_highdof_nv_hh, //87
|
|
/* EE1 SD0 HH1 NN1 NV0 HD0 MB0*/ pp_composite_hh_ee, //88
|
|
/* EE1 SD0 HH1 NN1 NV0 HD0 MB1*/ pp_composite_mb_hh_ee, //89
|
|
/* EE1 SD0 HH1 NN1 NV0 HD1 MB0*/ pp_composite_highdof_hh_ee, //90
|
|
/* EE1 SD0 HH1 NN1 NV0 HD1 MB1*/ pp_composite_mb_highdof_hh_ee, //91
|
|
/* EE1 SD0 HH1 NN1 NV1 HD0 MB0*/ pp_composite_nv_hh, //92 Nightvision is always noisy...
|
|
/* EE1 SD0 HH1 NN1 NV1 HD0 MB1*/ pp_composite_mb_nv_hh, //93 Nightvision is always noisy...
|
|
/* EE1 SD0 HH1 NN1 NV1 HD1 MB0*/ pp_composite_highdof_nv_hh, //94 Nightvision is always noisy...
|
|
/* EE1 SD0 HH1 NN1 NV1 HD1 MB1*/ pp_composite_mb_highdof_nv_hh, //95 Nightvision is always noisy...
|
|
/* EE1 SD1 HH0 NN0 NV0 HD0 MB0*/ pp_composite_shallowhighdof_ee, //96
|
|
/* EE1 SD1 HH0 NN0 NV0 HD0 MB1*/ pp_composite_mb_shallowhighdof_ee, //97
|
|
/* EE1 SD1 HH0 NN0 NV0 HD1 MB0*/ pp_composite_shallowhighdof_nv, //98
|
|
/* EE1 SD1 HH0 NN0 NV0 HD1 MB1*/ pp_composite_mb_shallowhighdof_ee, //99
|
|
/* EE1 SD1 HH0 NN0 NV1 HD0 MB0*/ pp_composite_shallowhighdof_nv, //100
|
|
/* EE1 SD1 HH0 NN0 NV1 HD0 MB1*/ pp_composite_mb_shallowhighdof_nv, //101
|
|
/* EE1 SD1 HH0 NN0 NV1 HD1 MB0*/ pp_composite_shallowhighdof_nv, //102
|
|
/* EE1 SD1 HH0 NN0 NV1 HD1 MB1*/ pp_composite_mb_shallowhighdof_nv, //103
|
|
/* EE1 SD1 HH0 NN1 NV0 HD0 MB0*/ pp_composite_shallowhighdof_ee, //104
|
|
/* EE1 SD1 HH0 NN1 NV0 HD0 MB1*/ pp_composite_mb_shallowhighdof_ee, //105
|
|
/* EE1 SD1 HH0 NN1 NV0 HD1 MB0*/ pp_composite_shallowhighdof_ee, //106
|
|
/* EE1 SD1 HH0 NN1 NV0 HD1 MB1*/ pp_composite_mb_shallowhighdof_ee, //107
|
|
/* EE1 SD1 HH0 NN1 NV1 HD0 MB0*/ pp_composite_shallowhighdof_nv, //108
|
|
/* EE1 SD1 HH0 NN1 NV1 HD0 MB1*/ pp_composite_mb_shallowhighdof_nv, //109
|
|
/* EE1 SD1 HH0 NN1 NV1 HD1 MB0*/ pp_composite_shallowhighdof_nv, //110
|
|
/* EE1 SD1 HH0 NN1 NV1 HD1 MB1*/ pp_composite_mb_shallowhighdof_nv, //111
|
|
/* EE1 SD1 HH1 NN0 NV0 HD0 MB0*/ pp_composite_shallowhighdof_hh_ee, //112
|
|
/* EE1 SD1 HH1 NN0 NV0 HD0 MB1*/ pp_composite_mb_shallowhighdof_hh_ee, //113
|
|
/* EE1 SD1 HH1 NN0 NV0 HD1 MB0*/ pp_composite_shallowhighdof_hh_ee, //114
|
|
/* EE1 SD1 HH1 NN0 NV0 HD1 MB1*/ pp_composite_mb_shallowhighdof_hh_ee, //115
|
|
/* EE1 SD1 HH1 NN0 NV1 HD0 MB0*/ pp_composite_shallowhighdof_nv_hh, //116
|
|
/* EE1 SD1 HH1 NN0 NV1 HD0 MB1*/ pp_composite_mb_shallowhighdof_nv_hh, //117
|
|
/* EE1 SD1 HH1 NN0 NV1 HD1 MB0*/ pp_composite_shallowhighdof_nv_hh, //118
|
|
/* EE1 SD1 HH1 NN0 NV1 HD1 MB1*/ pp_composite_mb_shallowhighdof_nv_hh, //119
|
|
/* EE1 SD1 HH1 NN1 NV0 HD0 MB0*/ pp_composite_shallowhighdof_hh_ee, //120
|
|
/* EE1 SD1 HH1 NN1 NV0 HD0 MB1*/ pp_composite_mb_shallowhighdof_hh_ee, //121
|
|
/* EE1 SD1 HH1 NN1 NV0 HD1 MB0*/ pp_composite_shallowhighdof_hh_ee, //122
|
|
/* EE1 SD1 HH1 NN1 NV0 HD1 MB1*/ pp_composite_mb_shallowhighdof_hh_ee, //123
|
|
/* EE1 SD1 HH1 NN1 NV1 HD0 MB0*/ pp_composite_shallowhighdof_nv_hh, //124
|
|
/* EE1 SD1 HH1 NN1 NV1 HD0 MB1*/ pp_composite_mb_shallowhighdof_nv_hh, //125
|
|
/* EE1 SD1 HH1 NN1 NV1 HD1 MB0*/ pp_composite_shallowhighdof_nv_hh, //126
|
|
/* EE1 SD1 HH1 NN1 NV1 HD1 MB1*/ pp_composite_mb_shallowhighdof_nv_hh, //127
|
|
|
|
};
|
|
|
|
static PostFXPass FXAAPassToUse = pp_AA;
|
|
|
|
static PostFXPass LumDownsamplePass[5];
|
|
|
|
static Matrix44 MotionBlurCurViewProjMat;
|
|
static Matrix44 MotionBlurPrevViewProjMat;
|
|
static Matrix44 MotionBlurPrevViewProjMatrix[2];
|
|
static Matrix44 MotionBlurBufferedPrevViewProjMat;
|
|
static Vec3V MotionBlurPreviousCameraDir;
|
|
static Vector2 NoiseEffectRandomValues;
|
|
|
|
#if __BANK
|
|
static bool NoDOF = false;
|
|
static bool NoMotionBlur = false;
|
|
static bool NoBloom = false;
|
|
|
|
PostFX::PostFXParamBlock::paramBlock editedSettings;
|
|
|
|
|
|
static bkText* toneMapInfo;
|
|
static char toneMapInfoStr[255];
|
|
|
|
static bool g_DebugBulletImpactTrigger = false;
|
|
static bool g_DebugBulletImpactUseCursorPos = false;
|
|
static bool g_DebugBulletImpactUseEnduranceIndicator = false;
|
|
static Vector3 g_DebugBulletImpactPos = Vector3(0.0f, 0.0f, 0.0f);
|
|
#endif // __BANK
|
|
|
|
#if AVG_LUMINANCE_COMPUTE
|
|
static bool AverageLumunianceComputeEnable = true;
|
|
#endif
|
|
|
|
#if BOKEH_SUPPORT
|
|
static bool BokehEnable = true;
|
|
static bool BokehGenerated = false;
|
|
static float BokehBrightnessExposureMin = -3.0f;
|
|
static float BokehBrightnessExposureMax = 3.0f;
|
|
static float BokehBlurThresholdVal = 0.25f;
|
|
static float MaxBokehSizeVar = 20.0f;
|
|
static float bokehSizeMultiplier = 1.5f;
|
|
static float BokehShapeExposureRangeMin = -3.0f;
|
|
static float BokehShapeExposureRangeMax = 3.0f;
|
|
static float BokehGlobalAlpha = 1.0f;
|
|
static float BokehAlphaCutoff = 0.15f;
|
|
#if __BANK
|
|
static int bokehShapeOverride = -1;
|
|
#endif
|
|
#if __BANK
|
|
static char bokehCountString[64];
|
|
static bool BokehDebugOverlay = false;
|
|
#endif
|
|
#endif
|
|
|
|
static int DofKernelSizeVar = 5;
|
|
#if DOF_COMPUTE_GAUSSIAN || DOF_DIFFUSION
|
|
static int DofShallowKernelSizeVar = DOF_MaxSampleRadius;
|
|
#if ADAPTIVE_DOF
|
|
static int DofAdaptiveKernelSizeVar = DOF_MaxSampleRadius;
|
|
#endif
|
|
#if COC_SPREAD
|
|
static int DofCocSpreadKernelRadiusVar = 5;
|
|
#endif
|
|
static float DofSkyWeightModifier = 0.6f;
|
|
static bool DofUsePreAlphaDepth = true;
|
|
|
|
static bool DofLumFilteringEnable = true;
|
|
static float DofLumContrastThreshold = 20.0f;
|
|
static float DofMaxLuminance = 10.0f;
|
|
|
|
#if DOF_COMPUTE_GAUSSIAN
|
|
bool sSetupGaussianWeights = false;
|
|
#endif
|
|
#endif //DOF_COMPUTE_GAUSSIAN
|
|
|
|
// state blocks for ProcessDepthFX
|
|
static grcRasterizerStateHandle exitDepthFXRasterizerState = grcStateBlock::RS_Invalid;
|
|
static grcBlendStateHandle exitDepthFXBlendState = grcStateBlock::BS_Invalid;
|
|
static grcDepthStencilStateHandle exitDepthFXDepthStencilState = grcStateBlock::DSS_Invalid;
|
|
static grcRasterizerStateHandle depthFXRasterizerState = grcStateBlock::RS_Invalid;
|
|
static grcBlendStateHandle depthFXBlendState = grcStateBlock::BS_Invalid;
|
|
static grcDepthStencilStateHandle depthFXDepthStencilState = grcStateBlock::DSS_Invalid;
|
|
|
|
// state blocks for ProcessSubSampleAlpha
|
|
static grcRasterizerStateHandle exitSubSampleAlphaRasterizerState = grcStateBlock::RS_Invalid;
|
|
static grcBlendStateHandle exitSubSampleAlphaBlendState = grcStateBlock::BS_Invalid;
|
|
static grcDepthStencilStateHandle exitSubSampleAlphaDepthStencilState = grcStateBlock::DSS_Invalid;
|
|
static grcRasterizerStateHandle subSampleAlphaRasterizerState = grcStateBlock::RS_Invalid;
|
|
static grcBlendStateHandle subSampleAlphaBlendState = grcStateBlock::BS_Invalid;
|
|
static grcDepthStencilStateHandle subSampleAlphaDSState = grcStateBlock::DSS_Invalid;
|
|
static grcDepthStencilStateHandle subSampleAlphaWithStencilCullDSState = grcStateBlock::DSS_Invalid;
|
|
|
|
// state blocks for ProcessNonDepthFX
|
|
static grcRasterizerStateHandle exitNonDepthFXRasterizerState = grcStateBlock::RS_Invalid;
|
|
static grcBlendStateHandle exitNonDepthFXBlendState = grcStateBlock::BS_Invalid;
|
|
static grcDepthStencilStateHandle exitNonDepthFXDepthStencilState = grcStateBlock::DSS_Invalid;
|
|
static grcRasterizerStateHandle nonDepthFXRasterizerState = grcStateBlock::RS_Invalid;
|
|
static grcBlendStateHandle nonDepthFXBlendState = grcStateBlock::BS_Invalid;
|
|
static grcDepthStencilStateHandle nonDepthFXDepthStencilState = grcStateBlock::DSS_Invalid;
|
|
|
|
#if BOKEH_SUPPORT
|
|
static grcBlendStateHandle bokehBlendState = grcStateBlock::BS_Invalid;
|
|
#endif
|
|
|
|
#if USE_IMAGE_WATERMARKS
|
|
static grcBlendStateHandle imageWatermarkBlendState = grcStateBlock::BS_Invalid;
|
|
#endif
|
|
|
|
// Damage overlay global params exposed in visual settings
|
|
|
|
PostFX::BulletImpactOverlay::Settings PostFX::BulletImpactOverlay::ms_settings[PostFX::BulletImpactOverlay::DOT_COUNT];
|
|
|
|
float PostFX::BulletImpactOverlay::ms_screenSafeZoneLength = 1.0f;
|
|
Vector4 PostFX::BulletImpactOverlay::ms_frozenDamagePosDir[PostFX::BulletImpactOverlay::NUM_ENTRIES];
|
|
float PostFX::BulletImpactOverlay::ms_frozenDamageOffsetMult[PostFX::BulletImpactOverlay::NUM_ENTRIES];
|
|
|
|
void GetPostFXDefaultRenderTargetFormat(grcTextureFormat& format, int& bpp)
|
|
{
|
|
#if __BANK
|
|
if (PARAM_postfxusesFP16.Get())
|
|
{
|
|
bpp = 64;
|
|
format = grctfA16B16G16R16F;
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
bpp = 32;
|
|
format = grctfR11G11B10F;
|
|
}
|
|
}
|
|
|
|
void PostFX::UpdateDefaultMotionBlur()
|
|
{
|
|
|
|
float headingOffset = 0.0f;
|
|
float pitchOffset = 0.0f;
|
|
|
|
const atArray<tRenderedCameraObjectSettings>& renderedCameras = camInterface::GetRenderedCameras();
|
|
|
|
const s32 numRenderedCameras = renderedCameras.GetCount();
|
|
for(s32 i=0; i<numRenderedCameras; i++)
|
|
{
|
|
const camBaseObject* renderedCamera = renderedCameras[i].m_Object;
|
|
if(renderedCamera)
|
|
{
|
|
const camControlHelper* controlHelper = NULL;
|
|
|
|
if(renderedCamera->GetIsClassId(camThirdPersonCamera::GetStaticClassId()))
|
|
{
|
|
controlHelper = static_cast<const camThirdPersonCamera*>(renderedCamera)->GetControlHelper();
|
|
}
|
|
else if(renderedCamera->GetIsClassId(camAimCamera::GetStaticClassId()))
|
|
{
|
|
controlHelper = static_cast<const camAimCamera*>(renderedCamera)->GetControlHelper();
|
|
}
|
|
else if(renderedCamera->GetIsClassId(camCinematicMountedCamera::GetStaticClassId()))
|
|
{
|
|
controlHelper = static_cast<const camCinematicMountedCamera*>(renderedCamera)->GetControlHelper();
|
|
}
|
|
|
|
if(controlHelper)
|
|
{
|
|
const float blendLevel = renderedCameras[i].m_BlendLevel;
|
|
headingOffset += blendLevel * controlHelper->GetLookAroundHeadingOffset();
|
|
pitchOffset += blendLevel * controlHelper->GetLookAroundPitchOffset();
|
|
}
|
|
}
|
|
}
|
|
|
|
const float lookAroundOffset = Sqrtf((headingOffset * headingOffset) + (pitchOffset * pitchOffset));
|
|
const float lookAroundSpeed = lookAroundOffset * fwTimer::GetCamInvTimeStep();
|
|
float lengthScale = WIN32PC_SWITCH(Lerp(CSettingsManager::GetInstance().GetSettings().m_graphics.m_MotionBlurStrength, 1.0f, 4.0f), 1.0f);
|
|
|
|
// Don't go over 1 or the effect breaks
|
|
g_cachedDefaultMotionBlur = Saturate(lookAroundSpeed*g_DefaultMotionBlurStrength*lengthScale);
|
|
|
|
}
|
|
|
|
// Motion Blur Strength. Usually in range: 0.0 ( no blur ), 1.0 ( full blur )
|
|
void PostFX::SetMotionBlur()
|
|
{
|
|
#if __BANK
|
|
if (g_Override==false)
|
|
#endif // __BANK
|
|
{
|
|
const camFrame& frame = gVpMan.GetCurrentGameViewportFrame();
|
|
float motionBlurStrength = frame.GetMotionBlurStrength();
|
|
|
|
const float maxFactor = 10.0f;
|
|
const float powerFactor = 2.0f;
|
|
|
|
// Don't go over 1 or the effect breaks
|
|
float motionBlurLength = Saturate(powf(motionBlurStrength,powerFactor)*maxFactor);
|
|
|
|
// Override with default motion blur if nothing else is driving it already
|
|
if (g_DefaultMotionBlurEnabled && motionBlurLength == 0.0f && !rage::ioHeadTracking::IsMotionTrackingEnabled())
|
|
{
|
|
#if RSG_PC
|
|
if (CSettingsManager::GetInstance().GetSettings().m_graphics.m_PostFX >= CSettings::Medium)
|
|
#endif // RSG_PC
|
|
{
|
|
motionBlurLength = g_cachedDefaultMotionBlur;
|
|
}
|
|
}
|
|
|
|
PostFXParamBlock::GetUpdateThreadParams().m_isForcingMotionBlur = camInterface::IsRenderedCameraForcingMotionBlur();
|
|
PostFXParamBlock::GetUpdateThreadParams().m_directionalBlurLength = Max(motionBlurLength,g_timeCycle.GetMotionBlurLength());
|
|
PostFXParamBlock::GetUpdateThreadParams().m_directionalBlurGhostingFade = 0.2f; // tbr
|
|
PostFXParamBlock::GetUpdateThreadParams().m_directionalBlurMaxVelocityMult = g_motionBlurMaxVelocityMult;
|
|
|
|
}
|
|
}
|
|
|
|
static void PackHiDofParameters(Vector4& hiDofParameters)
|
|
{
|
|
const float nearStartEndRange = hiDofParameters.y - hiDofParameters.x;
|
|
hiDofParameters.y = (nearStartEndRange > 0.0f ? 1.0f/nearStartEndRange : 1.0f);
|
|
|
|
const float farStartEndRange = hiDofParameters.w - hiDofParameters.z;
|
|
hiDofParameters.w = (farStartEndRange > 0.0f ? 1.0f/farStartEndRange : 1.0f);
|
|
}
|
|
|
|
static void InitDepthFXStateBlocks()
|
|
{
|
|
// render state
|
|
grcRasterizerStateDesc rsd;
|
|
rsd.CullMode = grcRSV::CULL_NONE;
|
|
rsd.FillMode = grcRSV::FILL_SOLID;
|
|
depthFXRasterizerState = grcStateBlock::CreateRasterizerState(rsd,"depthFXRasterizerState");
|
|
|
|
grcBlendStateDesc bsd;
|
|
bsd.BlendRTDesc[0].DestBlend = grcRSV::BLEND_INVSRCALPHA;
|
|
bsd.BlendRTDesc[0].SrcBlend = XENON_SWITCH(grcRSV::BLEND_ONE, grcRSV::BLEND_SRCALPHA); // we will premultiply in the shader for significantly reduced banding on 360
|
|
bsd.BlendRTDesc[0].BlendOp = grcRSV::BLENDOP_ADD;
|
|
bsd.BlendRTDesc[0].BlendEnable = 1;
|
|
bsd.BlendRTDesc[0].RenderTargetWriteMask = grcRSV::COLORWRITEENABLE_RGB;
|
|
depthFXBlendState = grcStateBlock::CreateBlendState(bsd, "depthFXBlendState");
|
|
|
|
grcDepthStencilStateDesc dssd;
|
|
dssd.DepthEnable = TRUE;
|
|
dssd.DepthWriteMask = FALSE;
|
|
dssd.DepthFunc = rage::FixupDepthDirection(grcRSV::CMP_LESS);
|
|
|
|
dssd.StencilEnable = TRUE;
|
|
dssd.StencilReadMask = 0x07;
|
|
dssd.StencilWriteMask = 0x00;
|
|
dssd.FrontFace.StencilFunc = grcRSV::CMP_NOTEQUAL;
|
|
dssd.BackFace.StencilFunc = grcRSV::CMP_NOTEQUAL;
|
|
depthFXDepthStencilState = grcStateBlock::CreateDepthStencilState(dssd, "depthFXDepthStencilState");
|
|
|
|
#if MSAA_EDGE_PASS
|
|
dssd.StencilReadMask |= EDGE_FLAG;
|
|
dssd.FrontFace.StencilFunc = dssd.BackFace.StencilFunc = grcRSV::CMP_GREATER;
|
|
edgeMaskDepthEffectFace_DS = grcStateBlock::CreateDepthStencilState(dssd, "edgeMaskDepthEffectFace_DS");
|
|
#endif //MSAA_EDGE_PASS
|
|
|
|
// exit state blocks
|
|
grcRasterizerStateDesc exitRsd;
|
|
exitRsd.CullMode = grcRSV::CULL_NONE;
|
|
exitRsd.FillMode = grcRSV::FILL_SOLID;
|
|
exitDepthFXRasterizerState = grcStateBlock::CreateRasterizerState(exitRsd, "exitDepthFXRasterizerState");
|
|
|
|
grcBlendStateDesc exitBsd;
|
|
exitBsd.BlendRTDesc[0].DestBlend = grcRSV::BLEND_INVSRCALPHA;
|
|
exitBsd.BlendRTDesc[0].SrcBlend = grcRSV::BLEND_SRCALPHA;
|
|
exitBsd.BlendRTDesc[0].BlendOp = grcRSV::BLENDOP_ADD;
|
|
exitBsd.BlendRTDesc[0].BlendEnable = 1;
|
|
exitDepthFXBlendState = grcStateBlock::CreateBlendState(exitBsd, "exitDepthFXBlendState");
|
|
|
|
grcDepthStencilStateDesc exitDssd;
|
|
exitDssd.DepthFunc = rage::FixupDepthDirection(grcRSV::CMP_LESSEQUAL);
|
|
exitDepthFXDepthStencilState = grcStateBlock::CreateDepthStencilState(exitDssd, "exitDepthFXDepthStencilState");
|
|
}
|
|
|
|
static void InitSubSampleAlphaStateBlocks()
|
|
{
|
|
// render state
|
|
grcRasterizerStateDesc rsd;
|
|
rsd.CullMode = grcRSV::CULL_NONE;
|
|
rsd.FillMode = grcRSV::FILL_SOLID;
|
|
#if __XENON
|
|
rsd.HalfPixelOffset = 1;
|
|
#endif
|
|
subSampleAlphaRasterizerState = grcStateBlock::CreateRasterizerState(rsd, "subSampleAlphaRasterizerState");
|
|
|
|
grcBlendStateDesc bsd;
|
|
bsd.BlendRTDesc[0].DestBlend = grcRSV::BLEND_INVSRCALPHA;
|
|
bsd.BlendRTDesc[0].SrcBlend = grcRSV::BLEND_SRCALPHA;
|
|
bsd.BlendRTDesc[0].BlendOp = grcRSV::BLENDOP_ADD;
|
|
bsd.BlendRTDesc[0].BlendEnable = 0;
|
|
subSampleAlphaBlendState = grcStateBlock::CreateBlendState(bsd, "subSampleAlphaBlendState");
|
|
|
|
grcDepthStencilStateDesc dssd;
|
|
dssd.DepthFunc = rage::FixupDepthDirection(grcRSV::CMP_LESSEQUAL);
|
|
dssd.DepthEnable = 0;
|
|
dssd.DepthWriteMask = 0;
|
|
subSampleAlphaDSState = grcStateBlock::CreateDepthStencilState(dssd, "subSampleAlphaDSState");
|
|
|
|
dssd.StencilEnable = 1;
|
|
dssd.StencilReadMask = DEFERRED_MATERIAL_SPECIALBIT;
|
|
dssd.StencilWriteMask = 0x0;
|
|
dssd.FrontFace.StencilDepthFailOp = grcRSV::STENCILOP_KEEP;
|
|
dssd.FrontFace.StencilFailOp = grcRSV::STENCILOP_KEEP;
|
|
dssd.FrontFace.StencilPassOp = grcRSV::STENCILOP_KEEP;
|
|
dssd.FrontFace.StencilFunc = __XENON ? grcRSV::CMP_NOTEQUAL : grcRSV::CMP_EQUAL;
|
|
dssd.BackFace = dssd.FrontFace;
|
|
subSampleAlphaWithStencilCullDSState = grcStateBlock::CreateDepthStencilState(dssd, "subSampleAlphaWithStencilCullDSState");
|
|
|
|
// exit state blocks
|
|
grcRasterizerStateDesc exitRsd;
|
|
exitRsd.CullMode = grcRSV::CULL_NONE;
|
|
exitRsd.FillMode = grcRSV::FILL_SOLID;
|
|
exitSubSampleAlphaRasterizerState = grcStateBlock::CreateRasterizerState(exitRsd, "exitSubSampleAlphaRasterizerState");
|
|
|
|
grcBlendStateDesc exitBsd;
|
|
exitBsd.BlendRTDesc[0].DestBlend = grcRSV::BLEND_INVSRCALPHA;
|
|
exitBsd.BlendRTDesc[0].SrcBlend = grcRSV::BLEND_SRCALPHA;
|
|
exitBsd.BlendRTDesc[0].BlendOp = grcRSV::BLENDOP_ADD;
|
|
//exitBsd.BlendRTDesc[0].BlendEnable = 1;
|
|
exitSubSampleAlphaBlendState = grcStateBlock::CreateBlendState(exitBsd, "exitSubSampleAlphaBlendState");
|
|
|
|
grcDepthStencilStateDesc exitDssd;
|
|
exitDssd.DepthFunc = rage::FixupDepthDirection(grcRSV::CMP_LESSEQUAL);
|
|
exitSubSampleAlphaDepthStencilState = grcStateBlock::CreateDepthStencilState(exitDssd, "exitSubSampleAlphaDepthStencilState");
|
|
}
|
|
|
|
static void InitNonDepthFXStateBlocks()
|
|
{
|
|
// render state
|
|
grcRasterizerStateDesc rsd;
|
|
rsd.CullMode = grcRSV::CULL_NONE;
|
|
rsd.FillMode = grcRSV::FILL_SOLID;
|
|
#if __XENON
|
|
rsd.HalfPixelOffset = 1;
|
|
#endif
|
|
nonDepthFXRasterizerState = grcStateBlock::CreateRasterizerState(rsd, "nonDepthFXRasterizerState");
|
|
|
|
grcBlendStateDesc bsd;
|
|
bsd.BlendRTDesc[0].DestBlend = grcRSV::BLEND_INVSRCALPHA;
|
|
bsd.BlendRTDesc[0].SrcBlend = grcRSV::BLEND_SRCALPHA;
|
|
bsd.BlendRTDesc[0].BlendOp = grcRSV::BLENDOP_ADD;
|
|
bsd.BlendRTDesc[0].BlendEnable = 0;
|
|
nonDepthFXBlendState = grcStateBlock::CreateBlendState(bsd, "nonDepthFXBlendState");
|
|
|
|
grcDepthStencilStateDesc dssd;
|
|
dssd.DepthEnable = 0;
|
|
dssd.DepthFunc = grcRSV::CMP_LESS;
|
|
dssd.DepthWriteMask = 0;
|
|
nonDepthFXDepthStencilState = grcStateBlock::CreateDepthStencilState(dssd, "nonDepthFXDepthStencilState");
|
|
|
|
// exit state blocks
|
|
grcRasterizerStateDesc exitRsd;
|
|
exitRsd.CullMode = grcRSV::CULL_NONE;
|
|
exitRsd.FillMode = grcRSV::FILL_SOLID;
|
|
exitNonDepthFXRasterizerState = grcStateBlock::CreateRasterizerState(exitRsd, "exitNonDepthFXRasterizerState");
|
|
|
|
grcBlendStateDesc exitBsd;
|
|
exitBsd.BlendRTDesc[0].DestBlend = grcRSV::BLEND_INVSRCALPHA;
|
|
exitBsd.BlendRTDesc[0].SrcBlend = grcRSV::BLEND_SRCALPHA;
|
|
exitBsd.BlendRTDesc[0].BlendOp = grcRSV::BLENDOP_ADD;
|
|
exitBsd.BlendRTDesc[0].BlendEnable = 1;
|
|
exitNonDepthFXBlendState = grcStateBlock::CreateBlendState(exitBsd, "exitNonDepthFXBlendState");
|
|
|
|
grcDepthStencilStateDesc exitDssd;
|
|
exitDssd.DepthFunc = rage::FixupDepthDirection(grcRSV::CMP_LESSEQUAL);
|
|
exitNonDepthFXDepthStencilState = grcStateBlock::CreateDepthStencilState(exitDssd, "exitNonDepthFXDepthStencilState");
|
|
|
|
#if BOKEH_SUPPORT
|
|
if( BokehEnable )
|
|
{
|
|
grcBlendStateDesc bokblend;
|
|
bokblend.BlendRTDesc[0].DestBlend = grcRSV::BLEND_INVSRCALPHA;
|
|
bokblend.BlendRTDesc[0].SrcBlend = grcRSV::BLEND_SRCALPHA;
|
|
bokblend.BlendRTDesc[0].SrcBlendAlpha = grcRSV::BLEND_ONE;
|
|
bokblend.BlendRTDesc[0].DestBlendAlpha = grcRSV::BLEND_INVSRCALPHA;
|
|
bokblend.BlendRTDesc[0].BlendOpAlpha = grcRSV::BLENDOP_ADD;
|
|
bokblend.BlendRTDesc[0].BlendEnable = 1;
|
|
|
|
bokehBlendState = grcStateBlock::CreateBlendState(bokblend, "bokehBlendState");
|
|
}
|
|
#endif
|
|
|
|
#if USE_IMAGE_WATERMARKS
|
|
grcBlendStateDesc watermarkBlend;
|
|
watermarkBlend.BlendRTDesc[0].DestBlend = grcRSV::BLEND_INVSRCALPHA;
|
|
watermarkBlend.BlendRTDesc[0].SrcBlend = grcRSV::BLEND_SRCALPHA;
|
|
watermarkBlend.BlendRTDesc[0].BlendOp = grcRSV::BLENDOP_ADD;
|
|
watermarkBlend.BlendRTDesc[0].BlendEnable = 1;
|
|
imageWatermarkBlendState = grcStateBlock::CreateBlendState(watermarkBlend, "watermarkBlendState");
|
|
#endif
|
|
|
|
#if USE_SCREEN_WATERMARK
|
|
grcBlendStateDesc blendStateBlockDesc;
|
|
blendStateBlockDesc.BlendRTDesc[GBUFFER_RT_0].RenderTargetWriteMask = grcRSV::COLORWRITEENABLE_RGB;
|
|
blendStateBlockDesc.BlendRTDesc[GBUFFER_RT_1].RenderTargetWriteMask = grcRSV::COLORWRITEENABLE_NONE;
|
|
blendStateBlockDesc.BlendRTDesc[GBUFFER_RT_2].RenderTargetWriteMask = grcRSV::COLORWRITEENABLE_NONE;
|
|
blendStateBlockDesc.BlendRTDesc[GBUFFER_RT_3].RenderTargetWriteMask = grcRSV::COLORWRITEENABLE_NONE;
|
|
blendStateBlockDesc.BlendRTDesc[GBUFFER_RT_0].BlendEnable = 1;
|
|
blendStateBlockDesc.BlendRTDesc[GBUFFER_RT_0].DestBlend = grcRSV::BLEND_INVSRCALPHA;
|
|
blendStateBlockDesc.BlendRTDesc[GBUFFER_RT_0].SrcBlend = grcRSV::BLEND_SRCALPHA;
|
|
blendStateBlockDesc.BlendRTDesc[GBUFFER_RT_0].BlendOp = grcRSV::BLENDOP_ADD;
|
|
blendStateBlockDesc.IndependentBlendEnable = 1;
|
|
|
|
ms_watermarkBlendState = grcStateBlock::CreateBlendState(blendStateBlockDesc);
|
|
#endif
|
|
}
|
|
|
|
static void InitRenderStateBlocks()
|
|
{
|
|
InitDepthFXStateBlocks();
|
|
InitSubSampleAlphaStateBlocks();
|
|
InitNonDepthFXStateBlocks();
|
|
}
|
|
|
|
|
|
static void SetNonDepthFXStateBlocks()
|
|
{
|
|
grcStateBlock::SetRasterizerState(nonDepthFXRasterizerState);
|
|
grcStateBlock::SetBlendState(nonDepthFXBlendState);
|
|
grcStateBlock::SetDepthStencilState(nonDepthFXDepthStencilState);
|
|
}
|
|
|
|
// helper function to set a texture variable and set the texture size global at the same time
|
|
void SetSrcTextureAndSize(grcEffectVar var, const grcTexture * tex)
|
|
{
|
|
PostFXShader->SetVar(var, tex);
|
|
#if __PPU || __D3D11 || RSG_ORBIS
|
|
PostFXShader->SetVar(TexelSizeId,
|
|
Vector4(1.0f / float(tex->GetWidth()), 1.0f / float(tex->GetHeight()),
|
|
float(tex->GetWidth()), float(tex->GetHeight())));
|
|
#endif
|
|
}
|
|
|
|
#if DOF_DIFFUSION
|
|
|
|
void RecreateDOFDiffusionRenderTargets(grcTextureFactory::CreateParams ¶ms, u32 bpp, u32 width, u32 height)
|
|
{
|
|
for(u32 i = 0; i < 16; i++)
|
|
{
|
|
delete dofDiffusionHorzABC[i]; dofDiffusionHorzABC[i] = NULL;
|
|
delete dofDiffusionHorzX[i]; dofDiffusionHorzX[i] = NULL;
|
|
delete dofDiffusionHorzY[i]; dofDiffusionHorzY[i] = NULL;
|
|
delete dofDiffusionVertABC[i]; dofDiffusionVertABC[i] = NULL;
|
|
delete dofDiffusionVertX[i]; dofDiffusionVertX[i] = NULL;
|
|
delete dofDiffusionVertY[i]; dofDiffusionVertY[i] = NULL;
|
|
}
|
|
|
|
#define DIFFUSION_DOF_ABC_FORMAT grctfA32B32G32R32F //Can probably get away with 16f here
|
|
// #define DIFFUSION_DOF_ABC_VIEW_FORMAT_PACKED DXGI_FORMAT_R32G32B32A32_UINT
|
|
// #define DIFFUSION_DOF_ABC_VIEW_FORMAT_NORMAL DXGI_FORMAT_R32G32B32A32_FLOAT
|
|
#define DIFFUSION_DOF_XY_FORMAT grctfA16B16G16R16F
|
|
|
|
u32 dofWidth = width;
|
|
u32 dofHeight = height;
|
|
char targetName[64];
|
|
grcTextureFormat dstFormat = grctfA16B16G16R16F;
|
|
for( int i = 0; i< 16; ++i )
|
|
{
|
|
dofDiffusionHorzABC[i] = NULL;
|
|
dofDiffusionHorzX[i] = NULL;
|
|
dofDiffusionHorzY[i] = NULL;
|
|
dofWidth = width >> i;
|
|
if( dofWidth > 1 )
|
|
{
|
|
params.Format = DIFFUSION_DOF_ABC_FORMAT;
|
|
if( i > 1 )
|
|
{
|
|
sprintf(targetName, "dofDiffusionHorzABC[%d]", i );
|
|
dofDiffusionHorzABC[i] = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, targetName, grcrtPermanent, dofWidth, dofHeight, bpp, ¶ms, 0 WIN32PC_ONLY(, dofDiffusionHorzABC[i]));
|
|
}
|
|
|
|
if( i != 0 )
|
|
params.Format = DIFFUSION_DOF_XY_FORMAT;
|
|
else
|
|
params.Format = dstFormat;
|
|
|
|
if( i != 1 )
|
|
{
|
|
sprintf(targetName, "dofDiffusionHorzY[%d]", i );
|
|
dofDiffusionHorzY[i] = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, targetName, grcrtPermanent, dofWidth, dofHeight, bpp, ¶ms, 0 WIN32PC_ONLY(, dofDiffusionHorzY[i]));
|
|
}
|
|
|
|
dofWidth >>= 1;
|
|
params.Format = DIFFUSION_DOF_XY_FORMAT;
|
|
|
|
if( dofWidth > 1 && i > 0 )
|
|
{
|
|
sprintf(targetName, "dofDiffusionHorzX[%d]", i );
|
|
dofDiffusionHorzX[i] = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, targetName, grcrtPermanent, dofWidth, dofHeight, bpp, ¶ms, 0 WIN32PC_ONLY(, dofDiffusionHorzX[i]));
|
|
}
|
|
}
|
|
}
|
|
|
|
dofWidth = width;
|
|
dofHeight = height;
|
|
|
|
for( int i = 0; i< 16; ++i )
|
|
{
|
|
dofDiffusionVertABC[i] = NULL;
|
|
dofDiffusionVertX[i] = NULL;
|
|
dofDiffusionVertY[i] = NULL;
|
|
dofHeight = height >> i;
|
|
if( dofHeight > 1 )
|
|
{
|
|
params.Format = DIFFUSION_DOF_ABC_FORMAT;
|
|
if( i > 1 )
|
|
{
|
|
sprintf(targetName, "dofDiffusionVertABC[%d]", i );
|
|
dofDiffusionVertABC[i] = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, targetName, grcrtPermanent, dofWidth, dofHeight, bpp, ¶ms, 0 WIN32PC_ONLY(, dofDiffusionVertABC[i]));
|
|
}
|
|
|
|
params.Format = DIFFUSION_DOF_XY_FORMAT;
|
|
if( i > 1 )
|
|
{
|
|
sprintf(targetName, "dofDiffusionVertY[%d]", i );
|
|
dofDiffusionVertY[i] = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, targetName, grcrtPermanent, dofWidth, dofHeight, bpp, ¶ms, 0 WIN32PC_ONLY(, dofDiffusionVertY[i]));
|
|
}
|
|
|
|
dofHeight >>= 1;
|
|
|
|
if( dofHeight > 1 && i > 0 )
|
|
{
|
|
sprintf(targetName, "dofDiffusionVertX[%d]", i );
|
|
dofDiffusionVertX[i] = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, targetName, grcrtPermanent, dofWidth, dofHeight, bpp, ¶ms, 0 WIN32PC_ONLY(, dofDiffusionVertX[i]));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif //DOF_DIFFUSION
|
|
|
|
void RecreateDOFRenderTargets(grcTextureFactory::CreateParams ¶ms, u32 bpp, u32 width, u32 height)
|
|
{
|
|
PostFX::SetGaussianBlur();
|
|
|
|
int dofTargetWidth = width/4;
|
|
int dofTargetHeight = height/4;
|
|
|
|
#if DOF_COMPUTE_GAUSSIAN || DOF_DIFFUSION
|
|
if( CurrentDOFTechnique == dof_computeGaussian || CurrentDOFTechnique == dof_diffusion)
|
|
{
|
|
dofTargetWidth = width;
|
|
dofTargetHeight = height;
|
|
# if DOF_COMPUTE_GAUSSIAN
|
|
params.UseAsUAV = true;
|
|
# endif
|
|
}
|
|
#endif //DOF_COMPUTE_GAUSSIAN || DOF_DIFFUSION
|
|
|
|
if (!DepthOfField1 || !DepthOfField2 || dofTargetWidth != DepthOfField1->GetWidth() || dofTargetHeight != DepthOfField1->GetHeight())
|
|
{
|
|
// on PC the targets will get re-used
|
|
#if !RSG_PC
|
|
if (DepthOfField1)
|
|
{
|
|
delete DepthOfField1;
|
|
DepthOfField1 = NULL;
|
|
}
|
|
if (DepthOfField2)
|
|
{
|
|
delete DepthOfField2;
|
|
DepthOfField2 = NULL;
|
|
}
|
|
#endif //!RSG_PC
|
|
ASSERT_ONLY(RESOURCE_CACHE_ONLY(bool prevSafeCreate = grcResourceCache::GetInstance().sm_SafeCreate));
|
|
ASSERT_ONLY(RESOURCE_CACHE_ONLY(grcResourceCache::GetInstance().SetSafeResourceCreate(true);))
|
|
DepthOfField1 = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "DOF 1", grcrtPermanent, dofTargetWidth, dofTargetHeight, bpp, ¶ms, 1 WIN32PC_ONLY(, DepthOfField1));
|
|
DepthOfField2 = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "DOF 2", grcrtPermanent, dofTargetWidth, dofTargetHeight, bpp, ¶ms, 1 WIN32PC_ONLY(, DepthOfField2));
|
|
ASSERT_ONLY(RESOURCE_CACHE_ONLY(grcResourceCache::GetInstance().SetSafeResourceCreate(prevSafeCreate);))
|
|
}
|
|
|
|
#if DOF_COMPUTE_GAUSSIAN
|
|
params.UseAsUAV = false;
|
|
#endif
|
|
}
|
|
|
|
#if BOKEH_SUPPORT
|
|
void RecreateBokehRenderTargets(grcTextureFactory::CreateParams ¶ms, int bpp, u32 width, u32 height)
|
|
{
|
|
#if BOKEH_SUPPORT
|
|
BokehEnable = (GRCDEVICE.GetDxFeatureLevel() >= 1100) NOTFINAL_ONLY(&& !PARAM_disableBokeh.Get());
|
|
#if RSG_PC
|
|
BokehEnable &= (CSettingsManager::GetInstance().GetSettings().m_graphics.m_PostFX >= CSettings::High) ? true : false;
|
|
#endif // RSG_PC
|
|
#endif
|
|
|
|
if( BokehEnable )
|
|
{
|
|
// BokehPoints store sprite transparency in alpha channel
|
|
bpp = 64;
|
|
params.Format = grctfA16B16G16R16F;
|
|
params.StereoRTMode = grcDevice::STEREO;
|
|
|
|
BokehPoints = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Bokeh Points", grcrtPermanent, width, height, bpp, ¶ms, 0 WIN32PC_ONLY(, BokehPoints));
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_6;
|
|
#endif
|
|
|
|
// Revert back to whatever the default format is (e.g: FP11 or FP16)
|
|
GetPostFXDefaultRenderTargetFormat(params.Format, bpp);
|
|
|
|
BokehPointsTemp = !RSG_DURANGO ? BloomBuffer : CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Bokeh Points Temp", grcrtPermanent, width/2, height/2, bpp, ¶ms, 0 WIN32PC_ONLY(, BokehPointsTemp));
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = 0;
|
|
#endif
|
|
params.StereoRTMode = grcDevice::AUTO;
|
|
//small texture to use when no bokeh rendering
|
|
|
|
if (BokehNoneRenderedTexture)
|
|
{
|
|
BokehNoneRenderedTexture->Release();
|
|
BokehNoneRenderedTexture = NULL;
|
|
}
|
|
|
|
grcImage* image = grcImage::Create(4, 4, 1, grcImage::DXT1, grcImage::STANDARD, 0, 0);
|
|
DXT::DXT1_BLOCK* block = reinterpret_cast<DXT::DXT1_BLOCK*>(image->GetBits());
|
|
block->SetColour(DXT::ARGB8888(0,0,0,0));
|
|
BokehNoneRenderedTexture = grcTextureFactory::GetInstance().Create(image);
|
|
image->Release();
|
|
|
|
params.Format=grctfG16R16F;
|
|
#if COC_SPREAD
|
|
if( CurrentDOFTechnique == dof_computeGaussian || CurrentDOFTechnique == dof_diffusion)
|
|
params.UseAsUAV = true;
|
|
#endif
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_5 | grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_6;
|
|
params.ESRAMMaxSize = 4 * 1024 * 1024;
|
|
#endif
|
|
BokehDepthBlur = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "BokehDepthBlur", grcrtPermanent, width, height, bpp, ¶ms, 0 WIN32PC_ONLY(, BokehDepthBlur));
|
|
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_6;
|
|
params.ESRAMMaxSize = 0;
|
|
#endif
|
|
BokehDepthBlurHalfRes = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "BokehDepthBlurHalfRes", grcrtPermanent, width/4, height/4, bpp, ¶ms, 0 WIN32PC_ONLY(, BokehDepthBlurHalfRes));
|
|
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = 0;
|
|
#endif
|
|
#if RSG_DURANGO && __BANK
|
|
AltBokehDepthBlur = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "AltBokehDepthBlur", grcrtPermanent, width, height, bpp, ¶ms, 0 WIN32PC_ONLY(, AltBokehDepthBlur));
|
|
#endif
|
|
|
|
#if COC_SPREAD
|
|
if( CurrentDOFTechnique == dof_computeGaussian || CurrentDOFTechnique == dof_diffusion)
|
|
{
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_6;
|
|
#endif
|
|
BokehDepthBlurHalfResTemp = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "BokehDepthBlurHalfResTemp", grcrtPermanent, width/4, height/4, bpp, ¶ms, 0 WIN32PC_ONLY(, BokehDepthBlurHalfResTemp));
|
|
params.UseAsUAV = false;
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = 0;
|
|
#endif
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
if( BokehPoints )
|
|
{
|
|
delete BokehPoints;
|
|
BokehPoints = NULL;
|
|
}
|
|
if( BokehPointsTemp )
|
|
{
|
|
// Shared with Bloom Buffer now
|
|
DURANGO_ONLY(delete BokehPointsTemp;)
|
|
BokehPointsTemp = NULL;
|
|
}
|
|
#if RSG_DURANGO && __BANK
|
|
if( AltBokehDepthBlur )
|
|
{
|
|
delete AltBokehDepthBlur;
|
|
AltBokehDepthBlur = NULL;
|
|
}
|
|
#endif
|
|
if (BokehNoneRenderedTexture)
|
|
{
|
|
BokehNoneRenderedTexture->Release();
|
|
BokehNoneRenderedTexture = NULL;
|
|
}
|
|
|
|
if( BokehDepthBlur )
|
|
{
|
|
delete BokehDepthBlur;
|
|
BokehDepthBlur = NULL;
|
|
#if BOKEH_SUPPORT
|
|
dofComputeShader->SetVar(dofComputeDepthBlurTex, grcTexture::None);
|
|
#endif
|
|
}
|
|
if( BokehDepthBlurHalfRes )
|
|
{
|
|
delete BokehDepthBlurHalfRes;
|
|
BokehDepthBlurHalfRes = NULL;
|
|
}
|
|
#if COC_SPREAD
|
|
if( BokehDepthBlurHalfResTemp )
|
|
{
|
|
delete BokehDepthBlurHalfResTemp;
|
|
BokehDepthBlurHalfResTemp = NULL;
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if __WIN32PC || RSG_DURANGO || RSG_ORBIS
|
|
#if RSG_PC
|
|
static bool targetsInitialized = false;
|
|
#endif
|
|
|
|
static void CreateScreenBasedRenderTargets(int iWidth, int iHeight)
|
|
{
|
|
#if RSG_PC
|
|
targetsInitialized = true;
|
|
#endif
|
|
//Create render targets.
|
|
grcTextureFactory::CreateParams params;
|
|
params.Multisample = 0;
|
|
params.HasParent = true;
|
|
params.Parent = NULL;
|
|
params.UseFloat = true;
|
|
|
|
params.InTiledMemory = true;
|
|
params.IsSwizzled = false;
|
|
params.UseFloat = true;
|
|
params.EnableCompression = false;
|
|
|
|
int bpp = 64;
|
|
|
|
#if !__FINAL && (__D3D11 || RSG_ORBIS)
|
|
if( PARAM_DX11Use8BitTargets.Get() )
|
|
{
|
|
bpp = 32;
|
|
params.Format = grctfA8R8G8B8;
|
|
params.UseFloat = false;
|
|
params.IsSRGB = true;
|
|
}
|
|
else
|
|
#endif // !__FINAL && (__D3D11 || RSG_ORBIS)
|
|
{
|
|
|
|
// Use FP11 unless we're running with postfxusesFP16
|
|
GetPostFXDefaultRenderTargetFormat(params.Format, bpp);
|
|
}
|
|
|
|
#if RSG_PC
|
|
params.StereoRTMode = grcDevice::STEREO;
|
|
#endif
|
|
|
|
HalfScreen0=CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Half Screen 0", grcrtPermanent, iWidth/2, iHeight/2, bpp, ¶ms, 0 WIN32PC_ONLY(, HalfScreen0));
|
|
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_7 | grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_8 |
|
|
grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_9;
|
|
#endif
|
|
|
|
WIN32PC_ONLY(if(CSettingsManager::GetInstance().GetSettings().m_graphics.m_PostFX >= CSettings::Medium))
|
|
BloomBuffer=CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Bloom Buffer", grcrtPermanent, iWidth/2, iHeight/2, bpp, ¶ms, 1 WIN32PC_ONLY(, BloomBuffer));
|
|
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = 0;
|
|
#endif
|
|
WIN32PC_ONLY(if(CSettingsManager::GetInstance().GetSettings().m_graphics.m_PostFX >= CSettings::Medium))
|
|
BloomBufferUnfiltered=CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Bloom Buffer Unfiltered", grcrtPermanent, iWidth/2, iHeight/2, bpp, ¶ms, 1 WIN32PC_ONLY(, BloomBufferUnfiltered));
|
|
|
|
RecreateDOFRenderTargets(params, bpp, iWidth, iHeight);
|
|
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_7 | grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_8;
|
|
BloomBufferHalf0 = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Bloom Buffer Half 0", grcrtPermanent, iWidth/2, iHeight/2, bpp, ¶ms, 1 WIN32PC_ONLY(, BloomBufferHalf0));
|
|
#else
|
|
// Bloom Half 0 shared
|
|
BloomBufferHalf0 = HalfScreen0;
|
|
#endif
|
|
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_7;
|
|
#endif
|
|
BloomBufferHalf1 = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Bloom Buffer Half 1", grcrtPermanent, iWidth/2, iHeight/2, bpp, ¶ms, 1 WIN32PC_ONLY(, BloomBufferHalf1));
|
|
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_4;
|
|
BloomBufferQuarterX = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Bloom Buffer Quarter X", grcrtPermanent, iWidth/4, iHeight/4, bpp, ¶ms, 1 WIN32PC_ONLY(, BloomBufferQuarterX));
|
|
|
|
params.ESRAMPhase = grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_7 | grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_8;
|
|
#endif
|
|
BloomBufferQuarter0 = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Bloom Buffer Quarter 0", grcrtPermanent, iWidth/4, iHeight/4, bpp, ¶ms, 1 WIN32PC_ONLY(, BloomBufferQuarter0));
|
|
|
|
#if (RSG_PC)
|
|
grcTextureFormat DefaultFormat = params.Format;
|
|
#endif
|
|
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_7;
|
|
#endif
|
|
|
|
BloomBufferQuarter1 = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Bloom Buffer Quarter 1", grcrtPermanent, iWidth/4, iHeight/4, bpp, ¶ms, 1 WIN32PC_ONLY(, BloomBufferQuarter1));
|
|
BloomBufferEighth1 = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Bloom Buffer Eighth 1", grcrtPermanent, iWidth/8, iHeight/8, bpp, ¶ms, 1 WIN32PC_ONLY(, BloomBufferEighth1));
|
|
BloomBufferSixteenth1 = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Bloom Buffer Sixteenth 1", grcrtPermanent, iWidth/16, iHeight/16, bpp, ¶ms, 1 WIN32PC_ONLY(, BloomBufferSixteenth1));
|
|
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_7 | grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_8;
|
|
#endif
|
|
|
|
BloomBufferEighth0 = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Bloom Buffer Eighth 0", grcrtPermanent, iWidth/8, iHeight/8, bpp, ¶ms, 1 WIN32PC_ONLY(, BloomBufferEighth0));
|
|
BloomBufferSixteenth0 = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Bloom Buffer Sixteenth 0", grcrtPermanent, iWidth/16, iHeight/16, bpp, ¶ms, 1 WIN32PC_ONLY(, BloomBufferSixteenth0));
|
|
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_3;
|
|
DSBB2 = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "DSBB2" , grcrtPermanent, iWidth/2 , iHeight/2 , bpp, ¶ms, 1 WIN32PC_ONLY(, DSBB2));
|
|
DSBB4 = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "DSBB4" , grcrtPermanent, iWidth/4 , iHeight/4 , bpp, ¶ms, 1 WIN32PC_ONLY(, DSBB4));
|
|
DSBB8 = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "DSBB8" , grcrtPermanent, iWidth/8 , iHeight/8 , bpp, ¶ms, 1 WIN32PC_ONLY(, DSBB8));
|
|
DSBB16 = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "DSBB16", grcrtPermanent, iWidth/16, iHeight/16, bpp, ¶ms, 1 WIN32PC_ONLY(, DSBB16));
|
|
params.ESRAMPhase = 0;
|
|
#endif
|
|
|
|
#if !RSG_DURANGO && LIGHT_VOLUME_USE_LOW_RESOLUTION
|
|
m_volumeOffscreenBuffer = BloomBufferHalf0;
|
|
m_volumeReconstructionBuffer = BloomBufferHalf1;
|
|
#endif
|
|
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_8 | grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_9;
|
|
#endif
|
|
WIN32PC_ONLY(if(LENSARTEFACTSMGR.IsActive()))
|
|
LensArtefactsFinalBuffer = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Lens Artefact Final Buffer", grcrtPermanent, iWidth/2, iHeight/2, bpp, ¶ms, 1 WIN32PC_ONLY(, LensArtefactsFinalBuffer));
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = 0;
|
|
#endif
|
|
WIN32PC_ONLY(if(LENSARTEFACTSMGR.IsActive()))
|
|
{
|
|
LensArtefactsBuffers0[LENSARTEFACT_HALF] = BloomBufferHalf0;
|
|
LensArtefactsBuffers1[LENSARTEFACT_HALF] = BloomBufferHalf1;
|
|
}
|
|
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_8;
|
|
#endif
|
|
|
|
WIN32PC_ONLY(if(LENSARTEFACTSMGR.IsActive()))
|
|
{
|
|
LensArtefactsBuffers0[LENSARTEFACT_QUARTER] = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Lens Artefact 4x Buffer 0", grcrtPermanent, iWidth/4, iHeight/4, bpp, ¶ms, 1 WIN32PC_ONLY(, LensArtefactsBuffers0[LENSARTEFACT_QUARTER]));
|
|
LensArtefactsBuffers1[LENSARTEFACT_QUARTER] = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Lens Artefact 4x Buffer 1", grcrtPermanent, iWidth/4, iHeight/4, bpp, ¶ms, 1 WIN32PC_ONLY(, LensArtefactsBuffers1[LENSARTEFACT_QUARTER]));
|
|
LensArtefactsBuffers0[LENSARTEFACT_EIGHTH] = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Lens Artefact 8x Buffer 0", grcrtPermanent, iWidth/8, iHeight/8, bpp, ¶ms, 1 WIN32PC_ONLY(, LensArtefactsBuffers0[LENSARTEFACT_EIGHTH]));
|
|
LensArtefactsBuffers1[LENSARTEFACT_EIGHTH] = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Lens Artefact 8x Buffer 1", grcrtPermanent, iWidth/8, iHeight/8, bpp, ¶ms, 1 WIN32PC_ONLY(, LensArtefactsBuffers1[LENSARTEFACT_EIGHTH]));
|
|
LensArtefactsBuffers0[LENSARTEFACT_SIXTEENTH] = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Lens Artefact 16x Buffer 0", grcrtPermanent, iWidth/16, iHeight/16, bpp, ¶ms, 1 WIN32PC_ONLY(, LensArtefactsBuffers0[LENSARTEFACT_SIXTEENTH]));
|
|
LensArtefactsBuffers1[LENSARTEFACT_SIXTEENTH] = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Lens Artefact 16x Buffer 1", grcrtPermanent, iWidth/16, iHeight/16, bpp, ¶ms, 1 WIN32PC_ONLY(, LensArtefactsBuffers1[LENSARTEFACT_SIXTEENTH]));
|
|
}
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = 0;
|
|
#endif
|
|
|
|
WIN32PC_ONLY(if(LENSARTEFACTSMGR.IsActive()))
|
|
{
|
|
LensArtefactSrcBuffers[LENSARTEFACT_HALF] = BloomBuffer;
|
|
LensArtefactSrcBuffers[LENSARTEFACT_QUARTER] = BloomBufferQuarter0;
|
|
LensArtefactSrcBuffers[LENSARTEFACT_EIGHTH] = BloomBufferEighth0;
|
|
LensArtefactSrcBuffers[LENSARTEFACT_SIXTEENTH] = BloomBufferSixteenth0;
|
|
}
|
|
|
|
// Set render targets and shader data for lens artefacts system
|
|
LENSARTEFACTSMGR.SetRenderTargets(LensArtefactsFinalBuffer, BloomBufferUnfiltered, LensArtefactSrcBuffers,
|
|
LensArtefactsBuffers0, LensArtefactsBuffers1);
|
|
|
|
DepthOfField0 = BloomBufferHalf1;
|
|
|
|
#if FILM_EFFECT
|
|
PreFilmEffect = !PostFX::g_EnableFilmEffect ? NULL : CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "LensDistortion", grcrtPermanent, iWidth, iHeight, bpp, ¶ms, 0, WIN32PC_ONLY(PreFilmEffect));
|
|
#endif
|
|
|
|
#if BOKEH_SUPPORT
|
|
RecreateBokehRenderTargets(params, bpp, iWidth, iHeight);
|
|
#endif
|
|
|
|
#if DOF_DIFFUSION
|
|
if( CurrentDOFTechnique == dof_diffusion)
|
|
{
|
|
RecreateDOFDiffusionRenderTargets(params, bpp, iWidth, iHeight);
|
|
}
|
|
#endif //DOF_DIFFUSION
|
|
|
|
params.Format=grctfL8;
|
|
HeatHaze0 = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "HeatHaze 1", grcrtPermanent, iWidth/8, iHeight/8, 8, ¶ms, 1 WIN32PC_ONLY(, HeatHaze0));
|
|
HeatHaze1 = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "HeatHaze 2", grcrtPermanent, iWidth/8, iHeight/8, 8, ¶ms, 1 WIN32PC_ONLY(, HeatHaze1));
|
|
|
|
#if __WIN32PC
|
|
params.StereoRTMode = grcDevice::STEREO;
|
|
#endif
|
|
|
|
params.Format = grctfA8R8G8B8;
|
|
params.UseFloat = false;
|
|
SSLRCutout=CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "SSLR Cutout", grcrtPermanent, 256, 256, 8, ¶ms, 1 WIN32PC_ONLY(, SSLRCutout));
|
|
LRIntensity=CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "SSLR Intensity", grcrtPermanent, iWidth/4, iHeight/4, 8, ¶ms, 1 WIN32PC_ONLY(, LRIntensity));
|
|
LRIntensity2=CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "SSLR Intensity2", grcrtPermanent, iWidth/4, iHeight/4, 8, ¶ms, 1 WIN32PC_ONLY(, LRIntensity2));
|
|
|
|
#if __WIN32PC
|
|
params.StereoRTMode = grcDevice::AUTO;
|
|
if(grcEffect::GetShaderQuality() > 0)
|
|
#endif
|
|
{
|
|
params.Format = grctfG16R16F;
|
|
params.UseFloat = true;
|
|
PostFX::FogRayRT=CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Global FogRay", grcrtPermanent, iWidth/2, iHeight/2, 32, ¶ms, 1 WIN32PC_ONLY(, PostFX::FogRayRT));
|
|
PostFX::FogRayRT2=CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Global FogRay 2", grcrtPermanent, iWidth/2, iHeight/2, 32, ¶ms, 1 WIN32PC_ONLY(, PostFX::FogRayRT2));
|
|
}
|
|
|
|
params.Format = grctfR32F;
|
|
params.UseFloat = false;
|
|
params.Lockable = false;
|
|
|
|
PostFX::FogOfWarRT0 = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Fog of War 0", grcrtPermanent, 64, 64, 32, ¶ms, 3 WIN32PC_ONLY(, PostFX::FogOfWarRT0));
|
|
PostFX::FogOfWarRT1 = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Fog of War 1", grcrtPermanent, 16, 16, 32, ¶ms, 3 WIN32PC_ONLY(, PostFX::FogOfWarRT1));
|
|
PostFX::FogOfWarRT2 = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Fog of War 2", grcrtPermanent, 4, 4, 32, ¶ms, 3 WIN32PC_ONLY(, PostFX::FogOfWarRT2));
|
|
|
|
// Depending on the device resolution, we need a different number of passes and filter sizes
|
|
// to correctly downsample the luminance; the code below can only handle 1080, 900 and 720.
|
|
// Any other resolution defaults to the 720 behaviour.
|
|
int deviceHeight = GRCDEVICE.GetHeight();
|
|
|
|
#if RSG_PC
|
|
if (deviceHeight > 1080)
|
|
{
|
|
deviceHeight = 1080;
|
|
}
|
|
else if (deviceHeight > 900)
|
|
{
|
|
deviceHeight = 900;
|
|
}
|
|
else
|
|
{
|
|
deviceHeight = 720;
|
|
}
|
|
#endif
|
|
|
|
int LumDownsampleRTWidth[5];
|
|
int LumDownsampleRTHeight[5];
|
|
|
|
switch (deviceHeight)
|
|
{
|
|
case 1080:
|
|
{
|
|
LumDownsampleRTWidth[0] = 120;
|
|
LumDownsampleRTHeight[0] = 90;
|
|
LumDownsampleRTWidth[1] = 30;
|
|
LumDownsampleRTHeight[1] = 30;
|
|
LumDownsampleRTWidth[2] = 10;
|
|
LumDownsampleRTHeight[2] = 10;
|
|
LumDownsampleRTWidth[3] = 5;
|
|
LumDownsampleRTHeight[3] = 5;
|
|
LumDownsampleRTWidth[4] = 1;
|
|
LumDownsampleRTHeight[4] = 1;
|
|
|
|
LumDownsamplePass[0] = pp_lum_4x3_conversion;
|
|
LumDownsamplePass[1] = pp_lum_4x3;
|
|
LumDownsamplePass[2] = pp_lum_3x3;
|
|
LumDownsamplePass[3] = pp_lum_2x2;
|
|
LumDownsamplePass[4] = pp_lum_5x5;
|
|
PostFX::LumDownsampleRTCount = 5;
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
case 900:
|
|
{
|
|
LumDownsampleRTWidth[0] = 100;
|
|
LumDownsampleRTHeight[0] = 75;
|
|
LumDownsampleRTWidth[1] = 25;
|
|
LumDownsampleRTHeight[1] = 25;
|
|
LumDownsampleRTWidth[2] = 5;
|
|
LumDownsampleRTHeight[2] = 5;
|
|
LumDownsampleRTWidth[3] = 1;
|
|
LumDownsampleRTHeight[3] = 1;
|
|
|
|
LumDownsamplePass[0] = pp_lum_4x3_conversion;
|
|
LumDownsamplePass[1] = pp_lum_4x3;
|
|
LumDownsamplePass[2] = pp_lum_5x5;
|
|
LumDownsamplePass[3] = pp_lum_5x5;
|
|
PostFX::LumDownsampleRTCount = 4;
|
|
|
|
break;
|
|
}
|
|
|
|
case 720:
|
|
default:
|
|
{
|
|
LumDownsampleRTWidth[0] = 80;
|
|
LumDownsampleRTHeight[0] = 60;
|
|
LumDownsampleRTWidth[1] = 20;
|
|
LumDownsampleRTHeight[1] = 20;
|
|
LumDownsampleRTWidth[2] = 10;
|
|
LumDownsampleRTHeight[2] = 10;
|
|
LumDownsampleRTWidth[3] = 5;
|
|
LumDownsampleRTHeight[3] = 5;
|
|
LumDownsampleRTWidth[4] = 1;
|
|
LumDownsampleRTHeight[4] = 1;
|
|
|
|
LumDownsamplePass[0] = pp_lum_4x3_conversion;
|
|
LumDownsamplePass[1] = pp_lum_4x3;
|
|
LumDownsamplePass[2] = pp_lum_2x2;
|
|
LumDownsamplePass[3] = pp_lum_2x2;
|
|
LumDownsamplePass[4] = pp_lum_5x5;
|
|
PostFX::LumDownsampleRTCount = 5;
|
|
|
|
if (deviceHeight != 720)
|
|
{
|
|
Warningf("Resolution not supported for luminance downsample targets (%d)", deviceHeight);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
#if AVG_LUMINANCE_COMPUTE
|
|
if(AverageLumunianceComputeEnable)
|
|
{
|
|
float fdeviceWidth = (float)(iWidth/4);
|
|
float fdeviceHeight = (float)(iHeight/4);
|
|
|
|
float maxSize = rage::Max(fdeviceWidth, fdeviceHeight);
|
|
|
|
PostFX::LumCSDownsampleUAVCount = 0;
|
|
|
|
params.UseAsUAV = true;
|
|
while ( maxSize > 16.0f )
|
|
{
|
|
Assertf(PostFX::LumCSDownsampleUAVCount < 5, "Exceeded maximum number of 5 for UAVs for luminance downsampling.");
|
|
|
|
maxSize = ceilf(maxSize / 16.0f);
|
|
|
|
fdeviceWidth = ceilf(fdeviceWidth / 16.0f);
|
|
fdeviceHeight = ceilf(fdeviceHeight / 16.0f);
|
|
|
|
char szLumDownName[256];
|
|
formatf(szLumDownName, 254, "LumDownsampleUAV %d", PostFX::LumCSDownsampleUAVCount);
|
|
|
|
PostFX::LumCSDownsampleUAV[PostFX::LumCSDownsampleUAVCount]=CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, szLumDownName, grcrtPermanent, (int)fdeviceWidth, (int)fdeviceHeight, 32, ¶ms, 3 WIN32PC_ONLY(, PostFX::LumCSDownsampleUAV[PostFX::LumCSDownsampleUAVCount]) );
|
|
|
|
PostFX::LumCSDownsampleUAVCount++;
|
|
}
|
|
|
|
//1x1
|
|
params.UseFloat = true;
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = 0; // final buffer is tiny and hangs around too long
|
|
#endif
|
|
PostFX::LumCSDownsampleUAV[PostFX::LumCSDownsampleUAVCount]=CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "LumDownsampleUAV Final", grcrtPermanent, 1, 1, 32, ¶ms, 3 WIN32PC_ONLY(, PostFX::LumCSDownsampleUAV[PostFX::LumCSDownsampleUAVCount]) );
|
|
|
|
params.UseAsUAV = false;
|
|
}
|
|
else
|
|
{
|
|
#endif //AVG_LUMINANCE_COMPUTE
|
|
|
|
#if (RSG_PC)
|
|
int iWidth4 = iWidth/4;
|
|
int iHeight4 = iHeight/4;
|
|
|
|
int lumWidth = LumDownsampleRTWidth[0];
|
|
int lumHeight = LumDownsampleRTHeight[0];
|
|
|
|
PostFX::ImLumDownsampleRTCount = 0;
|
|
|
|
params.Format = DefaultFormat;
|
|
|
|
while (iWidth4/4 > lumWidth || iHeight4/4 > lumHeight)
|
|
{
|
|
Assertf(PostFX::ImLumDownsampleRTCount < 5, "Exceeded maximum number of 5 for intermediate textures for luminance downsampling.");
|
|
|
|
iWidth4 /= 4;
|
|
iHeight4 /= 4;
|
|
|
|
int imLumRTWidth = rage::Max(lumWidth*4, iWidth4);
|
|
int imLumRTHeight = rage::Max(lumHeight*3, iHeight4);
|
|
|
|
char szLumDownName[256];
|
|
formatf(szLumDownName, 254, "ImLumDownsample %d", PostFX::ImLumDownsampleRTCount);
|
|
|
|
|
|
PostFX::ImLumDownsampleRT[PostFX::ImLumDownsampleRTCount]=CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, szLumDownName, grcrtPermanent, imLumRTWidth, imLumRTHeight, bpp, ¶ms, 3 WIN32PC_ONLY(, PostFX::ImLumDownsampleRT[PostFX::ImLumDownsampleRTCount]));
|
|
PostFX::ImLumDownsampleRTCount++;
|
|
}
|
|
params.Format = grctfR32F;
|
|
#endif
|
|
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = grcTextureFactory::TextureCreateParams::ESRPHASE_DRAWSCENE_4;
|
|
#endif
|
|
|
|
for (int i = 0; i < PostFX::LumDownsampleRTCount; i++)
|
|
{
|
|
if (i == PostFX::LumDownsampleRTCount - 1)
|
|
{
|
|
params.UseFloat = true;
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = 0; // final buffer is tiny and hangs around too long
|
|
#endif
|
|
}
|
|
char szLumDownName[256];
|
|
formatf(szLumDownName, 254, "LumDownsample %d", i);
|
|
PostFX::LumDownsampleRT[i]=CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, szLumDownName, grcrtPermanent, LumDownsampleRTWidth[i], LumDownsampleRTHeight[i], 32, ¶ms, 3 WIN32PC_ONLY(, PostFX::LumDownsampleRT[i]));
|
|
}
|
|
#if AVG_LUMINANCE_COMPUTE
|
|
}
|
|
|
|
if (AverageLumunianceComputeEnable)
|
|
{
|
|
LumRT = PostFX::LumCSDownsampleUAV[PostFX::LumCSDownsampleUAVCount];
|
|
}
|
|
else
|
|
#endif //AVG_LUMINANCE_COMPUTE
|
|
{
|
|
LumRT = PostFX::LumDownsampleRT[PostFX::LumDownsampleRTCount - 1];
|
|
}
|
|
|
|
params.Format = grctfA32B32G32R32F;
|
|
params.InTiledMemory = false;
|
|
params.IsSwizzled = false;
|
|
params.EnableCompression = false;
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = 0;
|
|
#endif
|
|
|
|
for (u32 i = 0; i < MAX_EXP_TARGETS; i++)
|
|
{
|
|
char szName[256];
|
|
formatf(szName, "Current Exposure %d", i);
|
|
#if __D3D11
|
|
grcTextureFactory::TextureCreateParams TextureParams(
|
|
grcTextureFactory::TextureCreateParams::SYSTEM,
|
|
grcTextureFactory::TextureCreateParams::LINEAR,
|
|
grcsRead|grcsWrite,
|
|
NULL,
|
|
grcTextureFactory::TextureCreateParams::RENDERTARGET,
|
|
grcTextureFactory::TextureCreateParams::MSAA_NONE);
|
|
if (!CurExposureTex[i]) {
|
|
BANK_ONLY(grcTexture::SetCustomLoadName(szName);)
|
|
CurExposureTex[i] = grcTextureFactory::GetInstance().Create( 1, 1, grctfA32B32G32R32F, NULL, 1, &TextureParams );
|
|
BANK_ONLY(grcTexture::SetCustomLoadName(NULL);)
|
|
}
|
|
CurExposureRT[i] = grcTextureFactory::GetInstance().CreateRenderTarget(szName, CurExposureTex[i]->GetTexturePtr() WIN32PC_ONLY(, CurExposureRT[i]));
|
|
#else
|
|
CurExposureRT[i] = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, szName, grcrtPermanent, 1, 1, 128, ¶ms, 3 WIN32PC_ONLY(, CurExposureRT[i]));
|
|
#endif
|
|
}
|
|
|
|
#if RSG_PC
|
|
params.Format = grctfR32F;
|
|
PostFX::CenterReticuleDist = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "Center Reticule Dist", grcrtPermanent, 1, 1, 32, ¶ms, 0 WIN32PC_ONLY(, PostFX::CenterReticuleDist));
|
|
#endif
|
|
|
|
#if ADAPTIVE_DOF
|
|
AdaptiveDepthOfField.CreateRenderTargets();
|
|
#endif
|
|
|
|
grcTextureFactory::CreateParams mb_params;
|
|
mb_params.Multisample = 0;
|
|
mb_params.HasParent = true;
|
|
mb_params.Parent = NULL;
|
|
mb_params.Format = grctfA8R8G8B8;
|
|
#if RSG_DURANGO
|
|
params.ESRAMPhase = grcTextureFactory::TextureCreateParams::ESRPHASE_LIGHTING;
|
|
#endif
|
|
|
|
WIN32PC_ONLY(if(CSettingsManager::GetInstance().GetSettings().m_graphics.m_PostFX >= CSettings::Medium))
|
|
{
|
|
for (int i = 0; i < 2; i++)
|
|
{
|
|
fpvMotionBlurTarget[i] = grcTextureFactory::GetInstance().CreateRenderTarget(
|
|
"FPV Motion Blur Targets", grcrtPermanent, iWidth / 2, iHeight / 2, 32, &mb_params WIN32PC_ONLY(, fpvMotionBlurTarget[i]));
|
|
}
|
|
}
|
|
|
|
#if USE_NV_TXAA
|
|
if( PostFX::g_TXAAEnable )
|
|
{
|
|
grcRenderTarget *src = grcTextureFactory::GetInstance().GetBackBuffer();
|
|
grcTextureFactory::CreateParams params;
|
|
params.Multisample = src->GetMSAA();
|
|
params.Format = static_cast<const grcRenderTargetPC*>(src)->GetFormat();
|
|
|
|
params.StereoRTMode = grcDevice::STEREO;
|
|
|
|
const int w = (VideoResManager::IsSceneScaled()) ? iWidth : src->GetWidth();
|
|
const int h = (VideoResManager::IsSceneScaled()) ? iHeight : src->GetHeight();
|
|
const int bpp = src->GetBitsPerPixel();
|
|
g_TXAAResolve = CRenderTargets::CreateRenderTarget(RTMEMPOOL_NONE, "TXAAResolve", grcrtPermanent, w,h, bpp, ¶ms, 0);
|
|
}
|
|
#endif // USE_NV_TXAA
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
static void CreateRenderTargets(int iWidth, int iHeight)
|
|
{
|
|
RAGE_TRACK(grPostFx);
|
|
RAGE_TRACK(grPostFxRenderTargets);
|
|
USE_MEMBUCKET(MEMBUCKET_RENDER);
|
|
|
|
// set render target descriptions
|
|
grcTextureFactory::CreateParams params;
|
|
params.Multisample = grcDevice::MSAA_None;
|
|
params.HasParent = true;
|
|
params.Parent = NULL;
|
|
params.UseFloat = true;
|
|
|
|
//Initialise targets that can be recreated
|
|
#if BOKEH_SUPPORT
|
|
BokehPoints = NULL;
|
|
BokehNoneRenderedTexture = NULL;
|
|
BokehDepthBlur = NULL;
|
|
BokehDepthBlurHalfRes = NULL;
|
|
BokehPointsTemp = NULL;
|
|
#if COC_SPREAD
|
|
BokehDepthBlurHalfResTemp = NULL;
|
|
#endif
|
|
#endif //BOKEH_SUPPORT
|
|
#if DOF_DIFFUSION
|
|
for(u32 i = 0; i < 16; i++)
|
|
{
|
|
dofDiffusionHorzABC[i] = NULL;
|
|
dofDiffusionHorzX[i] = NULL;
|
|
dofDiffusionHorzY[i] = NULL;
|
|
dofDiffusionVertABC[i] = NULL;
|
|
dofDiffusionVertX[i] = NULL;
|
|
dofDiffusionVertY[i] = NULL;
|
|
}
|
|
#endif //DOF_DIFFUSION
|
|
DepthOfField1 = NULL;
|
|
DepthOfField2 = NULL;
|
|
|
|
CreateScreenBasedRenderTargets(iWidth, iHeight);
|
|
|
|
grcImage* image = grcImage::Create(32, 32, 1, grcImage::L8, grcImage::STANDARD, 0, 0);
|
|
Assert(image);
|
|
|
|
for (u32 y = 0; y < 32; y++)
|
|
for (u32 x = 0; x < 32; x++)
|
|
image->SetPixel(x, y, static_cast<u8>((static_cast<float>(rand()) / static_cast<float>(RAND_MAX)) * 255.0f));
|
|
|
|
grcTextureFactory::TextureCreateParams jitterParams(grcTextureFactory::TextureCreateParams::SYSTEM, grcTextureFactory::TextureCreateParams::LINEAR, grcsRead | grcsWrite);
|
|
BANK_ONLY(grcTexture::SetCustomLoadName("Jitter");)
|
|
JitterTexture = rage::grcTextureFactory::GetInstance().Create(image, &jitterParams);
|
|
BANK_ONLY(grcTexture::SetCustomLoadName(NULL);)
|
|
Assert(JitterTexture);
|
|
|
|
LastSafeRelease(image);
|
|
}
|
|
|
|
#if __WIN32PC || RSG_DURANGO || RSG_ORBIS
|
|
|
|
static void DeleteScreenBasedTextures()
|
|
{
|
|
#if __D3D11
|
|
for (u32 i = 0; i < MAX_EXP_TARGETS; i++)
|
|
{
|
|
SafeRelease(CurExposureTex[i]);
|
|
}
|
|
#endif
|
|
|
|
#if USE_NV_TXAA
|
|
SafeRelease(g_TXAAResolve);
|
|
#endif // USE_NV_TXAA
|
|
|
|
|
|
}
|
|
|
|
static void DeleteScreenBasedRenderTargets()
|
|
{
|
|
RAGE_TRACK(grPostFx);
|
|
RAGE_TRACK(grPostFxRenderTargets);
|
|
USE_MEMBUCKET(MEMBUCKET_RENDER);
|
|
|
|
#if RSG_PC
|
|
delete PostFX::CenterReticuleDist; PostFX::CenterReticuleDist = NULL;
|
|
#endif
|
|
delete HalfScreen0; HalfScreen0 = NULL;
|
|
|
|
DepthOfField0 = NULL;
|
|
delete DepthOfField1; DepthOfField1 = NULL;
|
|
delete DepthOfField2; DepthOfField2 = NULL;
|
|
|
|
SAFE_DELETE(BloomBuffer);
|
|
SAFE_DELETE(BloomBufferUnfiltered);
|
|
DURANGO_ONLY(SAFE_DELETE(BloomBufferHalf0);)
|
|
SAFE_DELETE(BloomBufferHalf1);
|
|
SAFE_DELETE(BloomBufferQuarter0);
|
|
SAFE_DELETE(BloomBufferQuarter1);
|
|
DURANGO_ONLY(SAFE_DELETE(BloomBufferQuarterX);)
|
|
DURANGO_ONLY(SAFE_DELETE(DSBB2);)
|
|
DURANGO_ONLY(SAFE_DELETE(DSBB4);)
|
|
DURANGO_ONLY(SAFE_DELETE(DSBB8);)
|
|
DURANGO_ONLY(SAFE_DELETE(DSBB16);)
|
|
SAFE_DELETE(BloomBufferEighth0);
|
|
SAFE_DELETE(BloomBufferEighth1);
|
|
SAFE_DELETE(BloomBufferSixteenth0);
|
|
SAFE_DELETE(BloomBufferSixteenth1);
|
|
SAFE_DELETE(LensArtefactsFinalBuffer);
|
|
|
|
SAFE_DELETE(LensArtefactsBuffers0[LENSARTEFACT_QUARTER]);
|
|
SAFE_DELETE(LensArtefactsBuffers0[LENSARTEFACT_EIGHTH]);
|
|
SAFE_DELETE(LensArtefactsBuffers0[LENSARTEFACT_SIXTEENTH]);
|
|
SAFE_DELETE(LensArtefactsBuffers1[LENSARTEFACT_QUARTER]);
|
|
SAFE_DELETE(LensArtefactsBuffers1[LENSARTEFACT_EIGHTH]);
|
|
SAFE_DELETE(LensArtefactsBuffers1[LENSARTEFACT_SIXTEENTH]);
|
|
|
|
#if FILM_EFFECT
|
|
delete PreFilmEffect; PreFilmEffect = NULL;
|
|
#endif
|
|
|
|
#if BOKEH_SUPPORT
|
|
if( BokehEnable )
|
|
{
|
|
delete BokehPoints; BokehPoints = NULL;
|
|
DURANGO_ONLY(delete BokehPointsTemp;) // Shared with Bloom Buffer now
|
|
BokehPointsTemp = NULL;
|
|
|
|
if (BokehNoneRenderedTexture) {
|
|
BokehNoneRenderedTexture->Release();
|
|
BokehNoneRenderedTexture = NULL;
|
|
}
|
|
|
|
delete BokehDepthBlur; BokehDepthBlur = NULL;
|
|
#if RSG_DURANGO && __BANK
|
|
delete AltBokehDepthBlur; AltBokehDepthBlur = NULL;
|
|
#endif
|
|
delete BokehDepthBlurHalfRes; BokehDepthBlurHalfRes = NULL;
|
|
#if COC_SPREAD
|
|
delete BokehDepthBlurHalfResTemp; BokehDepthBlurHalfResTemp = NULL;
|
|
#endif
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
#if DOF_DIFFUSION
|
|
for(u32 i = 0; i < 16; i++)
|
|
{
|
|
delete dofDiffusionHorzABC[i]; dofDiffusionHorzABC[i] = NULL;
|
|
delete dofDiffusionHorzX[i]; dofDiffusionHorzX[i] = NULL;
|
|
delete dofDiffusionHorzY[i]; dofDiffusionHorzY[i] = NULL;
|
|
delete dofDiffusionVertABC[i]; dofDiffusionVertABC[i] = NULL;
|
|
delete dofDiffusionVertX[i]; dofDiffusionVertX[i] = NULL;
|
|
delete dofDiffusionVertY[i]; dofDiffusionVertY[i] = NULL;
|
|
}
|
|
#endif
|
|
|
|
delete HeatHaze0; HeatHaze0 = NULL;
|
|
delete HeatHaze1; HeatHaze1 = NULL;
|
|
|
|
delete SSLRCutout; SSLRCutout = NULL;
|
|
delete LRIntensity; LRIntensity = NULL;
|
|
delete LRIntensity2; LRIntensity2 = NULL;
|
|
delete PostFX::FogRayRT; PostFX::FogRayRT = NULL;
|
|
delete PostFX::FogRayRT2; PostFX::FogRayRT2 = NULL;
|
|
|
|
#if AVG_LUMINANCE_COMPUTE
|
|
if (AverageLumunianceComputeEnable)
|
|
{
|
|
for (int i = 0; i <= PostFX::LumCSDownsampleUAVCount; i++)
|
|
{
|
|
SAFE_DELETE(PostFX::LumCSDownsampleUAV[i]);
|
|
}
|
|
}
|
|
#endif //AVG_LUMINANCE_COMPUTE
|
|
for (int i = 0; i < PostFX::LumDownsampleRTCount; i++)
|
|
{
|
|
SAFE_DELETE(PostFX::LumDownsampleRT[i]);
|
|
}
|
|
|
|
#if (RSG_PC)
|
|
if (!AverageLumunianceComputeEnable)
|
|
{
|
|
for (int i = 0; i < PostFX::ImLumDownsampleRTCount; i++)
|
|
{
|
|
SAFE_DELETE(PostFX::ImLumDownsampleRT[i]);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
SAFE_DELETE(PostFX::FogOfWarRT0);
|
|
SAFE_DELETE(PostFX::FogOfWarRT1);
|
|
SAFE_DELETE(PostFX::FogOfWarRT2);
|
|
|
|
for (u32 i = 0; i < MAX_EXP_TARGETS; i++)
|
|
{
|
|
SAFE_DELETE(CurExposureRT[i]);
|
|
}
|
|
|
|
DeleteScreenBasedTextures();
|
|
}
|
|
|
|
#if !RSG_ORBIS // unused
|
|
static void DeleteRenderTargets()
|
|
{
|
|
RAGE_TRACK(grPostFx);
|
|
RAGE_TRACK(grPostFxRenderTargets);
|
|
USE_MEMBUCKET(MEMBUCKET_RENDER);
|
|
|
|
DeleteScreenBasedRenderTargets();
|
|
|
|
SafeRelease(JitterTexture);
|
|
}
|
|
#endif //!RSG_ORBIS
|
|
|
|
#endif // __WIN32PC || RSG_DURANGO || RSG_ORBIS
|
|
|
|
static void RecreateFogVertexBuffer()
|
|
{
|
|
static dev_s32 fogTilesWidth = 8;
|
|
static dev_s32 fogTilesHeight = 5;
|
|
|
|
s32 verts = ((fogTilesWidth + 1)*2 + 2)*fogTilesHeight;
|
|
float *const waterVertices = reinterpret_cast<float*>(alloca(verts * 2 * sizeof(float)));
|
|
|
|
float dX = 2.0f/fogTilesWidth;
|
|
float dY = -2.0f/fogTilesHeight;
|
|
float y = 1.0f;
|
|
s32 index = 0;
|
|
|
|
for(s32 i = 0; i < fogTilesHeight; i++)
|
|
{
|
|
float x = -1.0f;
|
|
|
|
waterVertices[index++] = x;
|
|
waterVertices[index++] = y;
|
|
|
|
float y1 = y + dY;
|
|
|
|
for(s32 j = 0; j < fogTilesWidth + 1; j++)
|
|
{
|
|
waterVertices[index++] = x;
|
|
waterVertices[index++] = y;
|
|
waterVertices[index++] = x;
|
|
waterVertices[index++] = y1;
|
|
x = x + dX;
|
|
}
|
|
|
|
waterVertices[index++] = x - dX;
|
|
waterVertices[index++] = y1;
|
|
|
|
y = y1;
|
|
}
|
|
|
|
Assertf(index == verts*2, "%d == %d", index, verts*2);
|
|
|
|
if (sm_FogVertexBuffer)
|
|
{
|
|
delete sm_FogVertexBuffer;
|
|
}
|
|
|
|
grcFvf fvf;
|
|
fvf.SetPosChannel(true, grcFvf::grcdsFloat2);
|
|
|
|
#if RSG_PC
|
|
sm_FogVertexBuffer = grcVertexBuffer::CreateWithData(verts, fvf, grcsBufferCreate_NeitherReadNorWrite, waterVertices, false);
|
|
#else
|
|
sm_FogVertexBuffer = grcVertexBuffer::CreateWithData(verts, fvf, waterVertices);
|
|
#endif
|
|
|
|
}
|
|
|
|
static void PostFXBlitHelper(grmShader *const shader, grcEffectTechnique technique, u32 pass, const Vector2 &uvOffset = Vector2(0.f,0.f), const Vector2 &uvOffsetEnd = Vector2(1.f,1.f))
|
|
{
|
|
#if POSTFX_UNIT_QUAD
|
|
shader->SetVar(quad::Position, FastQuad::Pack(-1.f,1.f,1.f,-1.f));
|
|
shader->SetVar(quad::TexCoords, FastQuad::Pack(uvOffset.x,uvOffset.y,uvOffsetEnd.x,uvOffsetEnd.y));
|
|
shader->SetVar(quad::Scale, Vector4(1.0f,1.0f,1.0f,1.0f));
|
|
# if USE_IMAGE_WATERMARKS
|
|
shader->SetVar(quad::Alpha, 1.0f);
|
|
# endif
|
|
#endif //POSTFX_UNIT_QUAD
|
|
|
|
AssertVerify(shader->BeginDraw(grmShader::RMC_DRAW,true,technique));
|
|
ShmooHandling::BeginShmoo(PostFxShmoo, shader, (int)pass);
|
|
shader->Bind((int)pass);
|
|
|
|
#if POSTFX_UNIT_QUAD
|
|
FastQuad::Draw(true);
|
|
#else
|
|
grcDrawSingleQuadf(-1.0, 1.0f, 1.0f, -1.0f, 0.0f, uvOffset.x,uvOffset.y,uvOffsetEnd.x,uvOffsetEnd.y, Color32(1.f,1.f,1.f,1.f));
|
|
#endif
|
|
|
|
shader->UnBind();
|
|
ShmooHandling::EndShmoo(PostFxShmoo);
|
|
shader->EndDraw();
|
|
}
|
|
|
|
#if __D3D11
|
|
static void PostFXBlit(grcRenderTarget* target, grcEffectTechnique technique, u32 pass, bool lockDepth=false, bool bClearColour = false, const char** RAGE_TIMEBARS_ONLY(passNameArray) = NULL, bool resolve = true, const Vector2 &uvOffset = Vector2(0.0f,0.0f), const Vector2 &uvOffsetEnd = Vector2(1.0f,1.0f), const grcBufferUAV* UAVs[grcMaxUAVViews] = NULL)
|
|
#else
|
|
#if RSG_ORBIS
|
|
static void PostFXBlit(grcRenderTarget* target, grcEffectTechnique technique, u32 pass, bool lockDepth=false, bool bClearColour = false, const char** RAGE_TIMEBARS_ONLY(passNameArray) = NULL, bool resolve = true, const Vector2 &uvOffset = Vector2(0.0f,0.0f), const Vector2 &uvOffsetEnd = Vector2(1.0f,1.0f), bool bLockSingleTarget = false)
|
|
#else
|
|
static void PostFXBlit(grcRenderTarget* target, grcEffectTechnique technique, u32 pass, bool lockDepth=false, bool bClearColour = false, const char** RAGE_TIMEBARS_ONLY(passNameArray) = NULL, bool resolve = true, const float uvOffsetScalar = 0.0f)
|
|
#endif
|
|
#endif
|
|
{
|
|
#if RAGE_TIMEBARS
|
|
if( passNameArray )
|
|
PF_PUSH_MARKER(passNameArray[pass]);
|
|
else
|
|
PF_PUSH_MARKER(passName[pass]);
|
|
#endif // RAGE_TIMEBARS
|
|
|
|
#if __XENON
|
|
int dstWidth, dstHeight;
|
|
|
|
if (target)
|
|
{
|
|
dstWidth=target->GetWidth();
|
|
dstHeight=target->GetHeight();
|
|
}
|
|
else
|
|
{
|
|
dstWidth=VideoResManager::GetNativeWidth();
|
|
dstHeight=VideoResManager::GetNativeHeight();
|
|
}
|
|
#endif
|
|
|
|
#if __D3D11
|
|
grcTextureFactoryDX11& textureFactory11 = static_cast<grcTextureFactoryDX11&>(grcTextureFactoryDX11::GetInstance());
|
|
if( UAVs )
|
|
{
|
|
const grcRenderTarget* RenderTargets[grcmrtColorCount] = {
|
|
target
|
|
};
|
|
|
|
UINT initialCounts[grcMaxUAVViews] = { 0 };
|
|
if(lockDepth)
|
|
textureFactory11.LockMRTWithUAV(NULL, target, NULL, NULL, UAVs, initialCounts);
|
|
else
|
|
textureFactory11.LockMRTWithUAV(RenderTargets, NULL, NULL, NULL, UAVs, initialCounts);
|
|
}
|
|
else
|
|
#endif
|
|
if (target)
|
|
{
|
|
#if RSG_ORBIS
|
|
if (bLockSingleTarget)
|
|
{
|
|
const grcRenderTargetGNM *const pColor = static_cast<const grcRenderTargetGNM*>(target);
|
|
const sce::Gnm::RenderTarget *const sceColor = pColor->GetColorTarget();
|
|
GRCDEVICE.LockSingleTarget(sceColor);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
if(lockDepth)
|
|
grcTextureFactory::GetInstance().LockRenderTarget(0, NULL, target);
|
|
else
|
|
grcTextureFactory::GetInstance().LockRenderTarget(0, target, NULL);
|
|
}
|
|
}
|
|
|
|
#if !(__D3D11 || RSG_ORBIS)
|
|
const Vector2 uvOffset(uvOffsetScalar, uvOffsetScalar);
|
|
const Vector2 uvOffsetEnd(1.0f + uvOffsetScalar, 1.0f + uvOffsetScalar);
|
|
#endif
|
|
PostFXBlitHelper(PostFXShader, technique, pass, uvOffset, uvOffsetEnd);
|
|
|
|
if (target)
|
|
{
|
|
#if RSG_ORBIS
|
|
if (bLockSingleTarget)
|
|
{
|
|
static_cast<grcTextureFactoryGNM&>( grcTextureFactory::GetInstance() ).RelockRenderTargets();
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
grcResolveFlags resolveFlags;
|
|
resolveFlags.ClearColor = bClearColour;
|
|
#if RSG_SM_50
|
|
(void) resolve;
|
|
#else
|
|
resolveFlags.NeedResolve = resolve;
|
|
#endif //RSG_SM_50
|
|
grcTextureFactory::GetInstance().UnlockMRT();
|
|
}
|
|
}else
|
|
{
|
|
#if RSG_ORBIS && SUPPORT_RENDERTARGET_DUMP
|
|
static_cast<grcTextureFactoryGNM&>(grcTextureFactory::GetInstance()).UnlockBackBuffer();
|
|
#endif //RSG_ORBIS && SUPPORT_RENDERTARGET_DUMP
|
|
}
|
|
|
|
#if RAGE_TIMEBARS
|
|
PF_POP_MARKER();
|
|
#endif // RAGE_TIMEBARS
|
|
}
|
|
|
|
static void PostFXBlit(grcRenderTarget* target, grcEffectTechnique technique, u32 pass, bool lockDepth, bool needToClear, Color32 ClearColor, const Vector3 &ll, const Vector3 &lr, const Vector3 &ur,const Vector3 &ul, const char** RAGE_TIMEBARS_ONLY(passNameArray) = NULL)
|
|
{
|
|
#if RAGE_TIMEBARS
|
|
if( passNameArray )
|
|
PF_PUSH_MARKER(passNameArray[pass]);
|
|
else
|
|
PF_PUSH_MARKER(passName[pass]);
|
|
#endif // RAGE_TIMEBARS
|
|
|
|
Color32 color(1.0f,1.0f,1.0f,1.0f);
|
|
|
|
#if __XENON
|
|
int dstWidth, dstHeight;
|
|
|
|
if (target)
|
|
{
|
|
dstWidth=target->GetWidth();
|
|
dstHeight=target->GetHeight();
|
|
}
|
|
else
|
|
{
|
|
dstWidth=VideoResManager::GetNativeWidth();
|
|
dstHeight=VideoResManager::GetNativeHeight();
|
|
}
|
|
#endif
|
|
|
|
if (target)
|
|
{
|
|
if(lockDepth)
|
|
grcTextureFactory::GetInstance().LockRenderTarget(0, NULL, target);
|
|
else
|
|
grcTextureFactory::GetInstance().LockRenderTarget(0, target, NULL);
|
|
}
|
|
|
|
if (needToClear)
|
|
GRCDEVICE.Clear(true, ClearColor, false, 0.0f, false);
|
|
|
|
AssertVerify(PostFXShader->BeginDraw(grmShader::RMC_DRAW,true,technique));
|
|
ShmooHandling::BeginShmoo(PostFxShmoo, PostFXShader, (int)pass);
|
|
PostFXShader->Bind((int)pass);
|
|
|
|
grcBegin(rage::drawTriStrip, 4);
|
|
grcVertex(ll.x,ll.y,ll.z,0,0,0,color,0.0f,0.0f);
|
|
grcVertex(lr.x,lr.y,lr.z,0,0,0,color,1.0f,0.0f);
|
|
grcVertex(ul.x,ul.y,ul.z,0,0,0,color,0.0f,1.0f);
|
|
grcVertex(ur.x,ur.y,ur.z,0,0,0,color,1.0f,1.0f);
|
|
grcEnd();
|
|
|
|
PostFXShader->UnBind();
|
|
ShmooHandling::EndShmoo(PostFxShmoo);
|
|
PostFXShader->EndDraw();
|
|
|
|
if (target)
|
|
{
|
|
grcTextureFactory::GetInstance().UnlockRenderTarget(0);
|
|
}
|
|
|
|
#if RAGE_TIMEBARS
|
|
PF_POP_MARKER();
|
|
#endif // RAGE_TIMEBARS
|
|
|
|
}
|
|
|
|
void PostFX::SimpleBlitWrapper(grcRenderTarget* pDestTarget, const grcTexture* pSrcTarget, u32 pass)
|
|
{
|
|
SetNonDepthFXStateBlocks();
|
|
|
|
PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/float(pSrcTarget->GetWidth()),1.0f/float(pSrcTarget->GetHeight()),0.0, 0.0f));
|
|
PostFXShader->SetVar(TextureID_0, pSrcTarget);
|
|
PostFXBlit(pDestTarget, PostFXTechnique, pass, false, false);
|
|
}
|
|
|
|
static void PostFXGradientFilter(grcRenderTarget* target, grcEffectTechnique technique, u32 pass, const PostFX::PostFXParamBlock::paramBlock& settings)
|
|
{
|
|
Vec4V vTopColour = RCC_VEC4V(settings.m_lensGradientColTop);
|
|
Vec4V vMidColour = RCC_VEC4V(settings.m_lensGradientColMiddle);
|
|
Vec4V vBotColour = RCC_VEC4V(settings.m_lensGradientColBottom);
|
|
vTopColour.SetW(ScalarV(V_ONE));
|
|
vMidColour.SetW(ScalarV(V_ONE));
|
|
vBotColour.SetW(ScalarV(V_ONE));
|
|
|
|
// Check for colours close to white as the time cycle never quite returns one
|
|
unsigned int bAnyColourCloseToWhite = IsCloseAll(vTopColour, Vec4V(V_ONE), ScalarV(V_FLT_SMALL_2)) &
|
|
IsCloseAll(vMidColour, Vec4V(V_ONE), ScalarV(V_FLT_SMALL_2)) &
|
|
IsCloseAll(vBotColour, Vec4V(V_ONE), ScalarV(V_FLT_SMALL_2));
|
|
|
|
if (bAnyColourCloseToWhite == 0)
|
|
{
|
|
PostFXBlit(target, technique, pass, false, false, NULL, false);
|
|
}
|
|
}
|
|
|
|
|
|
#if BOKEH_SUPPORT
|
|
|
|
static void SortBokehSprites()
|
|
{
|
|
//Generate sorted bucket list
|
|
PIXBegin(0, "bokeh sort");
|
|
PostFXShader->SetVarUAV( BokehSortOffsetsBufferVar, &s_bokehNumAddedToBuckets, 0);
|
|
PostFXShader->SetVarUAV( BokehSortedBufferVar, &s_bokehSortedIndexListBuffer, 0);
|
|
PostFXShader->SetVar(BokehSpritePointBufferVar, &s_BokehAccumBuffer);
|
|
|
|
#if RSG_DURANGO
|
|
g_grcCurrentContext->GpuSendPipelinedEvent(D3D11X_GPU_PIPELINED_EVENT_PS_PARTIAL_FLUSH);
|
|
#endif
|
|
|
|
// Sort the data
|
|
// First sort the rows for the levels <= to the block size
|
|
for( u32 level = 2 ; level <= BOKEH_SORT_BITONIC_BLOCK_SIZE ; level = level * 2 )
|
|
{
|
|
PostFXShader->SetVar(BokehSortLevelVar, (float)level);
|
|
PostFXShader->SetVar(BokehSortLevelMaskVar, (float)level);
|
|
|
|
#if BOKEH_SORT_BITONIC_TRANSPOSE
|
|
u32 groupCountX = s_BokehMaxElements / BOKEH_SORT_BITONIC_BLOCK_SIZE;
|
|
#else
|
|
u32 groupCountX = BOKEH_SORT_NUM_BUCKETS;
|
|
#endif
|
|
u32 groupCountY = 1;
|
|
GRCDEVICE.RunComputation( "Bokeh bitonic sort", *PostFXShader, pp_Bokeh_ComputeBitonicSort, groupCountX, groupCountY, 1);
|
|
# if __D3D11 || RSG_ORBIS
|
|
GRCDEVICE.SynchronizeComputeToCompute();
|
|
# endif
|
|
}
|
|
|
|
#if BOKEH_SORT_BITONIC_TRANSPOSE
|
|
|
|
const u32 transposeMatrixWidth = BOKEH_SORT_BITONIC_BLOCK_SIZE;
|
|
const u32 transposeMatrixHeight = s_BokehMaxElements / BOKEH_SORT_BITONIC_BLOCK_SIZE;
|
|
|
|
// Then sort the rows and columns for the levels > than the block size
|
|
// Transpose. Sort the Columns. Transpose. Sort the Rows.
|
|
for( u32 level = (BOKEH_SORT_BITONIC_BLOCK_SIZE * 2) ; level <= s_BokehMaxElements ; level = level * 2 )
|
|
{
|
|
PostFXShader->SetVar(BokehSortLevelVar, (float)level / (float)BOKEH_SORT_BITONIC_BLOCK_SIZE);
|
|
PostFXShader->SetVar(BokehSortLevelMaskVar, (float)((level & ~s_BokehMaxElements) / BOKEH_SORT_BITONIC_BLOCK_SIZE));
|
|
PostFXShader->SetVar(BokehSortTransposeMatWidthVar, (float)transposeMatrixWidth);
|
|
PostFXShader->SetVar(BokehSortTransposeMatHeightVar, (float)transposeMatrixHeight);
|
|
|
|
// Transpose the data from buffer 1 into buffer 2
|
|
PostFXShader->SetVar( BokehSortedIndexBufferVar, &s_bokehSortedIndexListBuffer);
|
|
PostFXShader->SetVarUAV( BokehSortedBufferVar, &s_bokehSortedIndexListBuffer2, 0);
|
|
|
|
u32 groupCountX = transposeMatrixWidth / BOKEH_SORT_TRANSPOSE_BLOCK_SIZE;
|
|
u32 groupCountY = transposeMatrixHeight / BOKEH_SORT_TRANSPOSE_BLOCK_SIZE;
|
|
GRCDEVICE.RunComputation( "Bokeh bitonic sort transpose", *PostFXShader, pp_Bokeh_ComputeBitonicSortTranspose, groupCountX, groupCountY, 1);
|
|
|
|
# if __D3D11 || RSG_ORBIS
|
|
GRCDEVICE.SynchronizeComputeToCompute();
|
|
# endif
|
|
|
|
// Sort the transposed column data
|
|
groupCountX = s_BokehMaxElements / BOKEH_SORT_BITONIC_BLOCK_SIZE;
|
|
groupCountY = 1;
|
|
GRCDEVICE.RunComputation( "Bokeh bitonic sort", *PostFXShader, pp_Bokeh_ComputeBitonicSort, groupCountX, groupCountY, 1);
|
|
|
|
# if __D3D11 || RSG_ORBIS
|
|
GRCDEVICE.SynchronizeComputeToCompute();
|
|
# endif
|
|
PostFXShader->SetVar(BokehSortLevelVar, (float)BOKEH_SORT_BITONIC_BLOCK_SIZE);
|
|
PostFXShader->SetVar(BokehSortLevelMaskVar, (float)level);
|
|
PostFXShader->SetVar(BokehSortTransposeMatWidthVar, (float)transposeMatrixHeight);
|
|
PostFXShader->SetVar(BokehSortTransposeMatHeightVar, (float)transposeMatrixWidth);
|
|
|
|
// Transpose the data from buffer 2 back into buffer 1
|
|
PostFXShader->SetVar( BokehSortedIndexBufferVar, &s_bokehSortedIndexListBuffer2);
|
|
PostFXShader->SetVarUAV( BokehSortedBufferVar, &s_bokehSortedIndexListBuffer, 0);
|
|
groupCountX = transposeMatrixHeight / BOKEH_SORT_TRANSPOSE_BLOCK_SIZE;
|
|
groupCountY = transposeMatrixWidth / BOKEH_SORT_TRANSPOSE_BLOCK_SIZE;
|
|
GRCDEVICE.RunComputation( "Bokeh bitonic sort transpose", *PostFXShader, pp_Bokeh_ComputeBitonicSortTranspose, groupCountX, groupCountY, 1);
|
|
|
|
# if __D3D11 || RSG_ORBIS
|
|
GRCDEVICE.SynchronizeComputeToCompute();
|
|
# endif
|
|
// Sort the row data
|
|
groupCountX = s_BokehMaxElements / BOKEH_SORT_BITONIC_BLOCK_SIZE;
|
|
groupCountY = 1;
|
|
GRCDEVICE.RunComputation( "Bokeh bitonic sort", *PostFXShader, pp_Bokeh_ComputeBitonicSort, groupCountX, groupCountY, 1);
|
|
|
|
# if __D3D11 || RSG_ORBIS
|
|
GRCDEVICE.SynchronizeComputeToCompute();
|
|
# endif
|
|
}
|
|
|
|
#endif //BOKEH_SORT_BITONIC_TRANSPOSE
|
|
|
|
|
|
# if __D3D11 || RSG_ORBIS
|
|
GRCDEVICE.SynchronizeComputeToGraphics();
|
|
# endif
|
|
|
|
PIXEnd();
|
|
}
|
|
|
|
|
|
static void BokehBlitWithGeometryShader(grcRenderTarget* target, grcEffectTechnique technique, u32 pass, bool lockDepth, bool bClearColour, const char** RAGE_TIMEBARS_ONLY(passNameArray))
|
|
{
|
|
// Copy the count from the bokeh point AppendStructuredBuffer to our indirect arguments buffer.
|
|
// This lets us issue a draw call with number of vertices == the number of points in
|
|
// the buffer, without having to copy anything back to the CPU.
|
|
GRCDEVICE.CopyStructureCount( &s_indirectArgsBuffer, 0, &s_BokehAccumBuffer );
|
|
|
|
#if (RSG_DURANGO || RSG_ORBIS)
|
|
#if RSG_DURANGO
|
|
u32* pBuff = (u32*) s_indirectArgsBuffer.LockAll();
|
|
#else
|
|
u32* pBuff = (u32*) s_indirectArgsBuffer.GetAddress();
|
|
#endif
|
|
u32 bokehRenderCount = *pBuff;
|
|
#if __BANK
|
|
//Check that the we're not trying to generate more bokeh sprites than the size of the structured buffer.
|
|
//If this happens we'll just be missing bokeh sprites.
|
|
//Just do this on consoles as we can directly access the memory and any asserts will apply to all platforms.
|
|
if( bokehRenderCount >= s_BokehMaxElements )
|
|
{
|
|
if( s_BokehRenderCountTimer.GetMsTime() > 4000.0f )
|
|
{
|
|
grcWarningf("Bokeh Render count too high, needs reducing");
|
|
s_BokehRenderCountTimer.Reset();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
s_BokehRenderCountTimer.Reset();
|
|
}
|
|
|
|
sprintf(bokehCountString, "%d", bokehRenderCount);
|
|
#endif
|
|
#endif
|
|
|
|
BokehGenerated = false;
|
|
|
|
#if (RSG_DURANGO || RSG_ORBIS)
|
|
if( bokehRenderCount != 0 )
|
|
#endif
|
|
{
|
|
SortBokehSprites();
|
|
|
|
#if RAGE_TIMEBARS && INCLUDE_DETAIL_TIMEBARS
|
|
PF_PUSH_TIMEBAR_DETAIL(passNameArray[pass]);
|
|
#else
|
|
RAGE_TIMEBARS_ONLY((void)passNameArray;)
|
|
#endif // RAGE_TIMEBARS
|
|
|
|
//Render bokeh with geometry shader
|
|
Color32 color(0.0f,0.0f,0.0f,0.0f);
|
|
|
|
const grcRenderTarget* RenderTargets[grcmrtColorCount] = {
|
|
target
|
|
};
|
|
|
|
#if RSG_ORBIS
|
|
grcTextureFactoryGNM& textureFactory = static_cast<grcTextureFactoryGNM&>(grcTextureFactory::GetInstance());
|
|
#else
|
|
grcTextureFactoryDX11& textureFactory = static_cast<grcTextureFactoryDX11&>(grcTextureFactory::GetInstance());
|
|
#endif
|
|
if (target)
|
|
{
|
|
if(lockDepth)
|
|
textureFactory.LockMRT(NULL, target);
|
|
else
|
|
textureFactory.LockMRT(RenderTargets, NULL);
|
|
}
|
|
|
|
//Could possibly stop previous pass writing out colour so dont need to do this
|
|
GRCDEVICE.Clear( bClearColour, color, false, false, false, false );
|
|
|
|
|
|
PostFXShader->SetVar(BokehSpritePointBufferVar, &s_BokehAccumBuffer);
|
|
PostFXShader->SetVar(BokehSortedIndexBufferVar, &s_bokehSortedIndexListBuffer);
|
|
|
|
|
|
AssertVerify(PostFXShader->BeginDraw(grmShader::RMC_DRAW,true,technique));
|
|
PostFXShader->Bind((int)pass);
|
|
|
|
grcStateBlock::SetBlendState(bokehBlendState);
|
|
|
|
GRCDEVICE.DrawWithGeometryShader( &s_indirectArgsBuffer );
|
|
|
|
PostFXShader->UnBind();
|
|
PostFXShader->EndDraw();
|
|
|
|
if (target)
|
|
{
|
|
grcResolveFlags resolveFlags;
|
|
resolveFlags.ClearColor = true;
|
|
grcTextureFactory::GetInstance().UnlockRenderTarget(0, (bClearColour ? &resolveFlags : NULL));
|
|
}
|
|
|
|
grcStateBlock::SetBlendState(nonDepthFXBlendState);
|
|
|
|
BokehGenerated = true;
|
|
|
|
#if RAGE_TIMEBARS
|
|
PF_POP_TIMEBAR_DETAIL();
|
|
#endif // RAGE_TIMEBARS
|
|
}
|
|
}
|
|
|
|
#endif //BOKEH_SUPPORT
|
|
|
|
|
|
|
|
void GetNormScreenPosFromWorldPos(const Vector3& worldPos, float& x, float& y)
|
|
{
|
|
const grcViewport* pVp = gVpMan.GetRenderGameGrcViewport();
|
|
|
|
if (pVp == NULL)
|
|
{
|
|
// have 2d position culled
|
|
x = -2.0f;
|
|
y = -2.0f;
|
|
return;
|
|
}
|
|
|
|
pVp->Transform((Vec3V&)worldPos, x, y);
|
|
x /= SCREEN_WIDTH;
|
|
y /= SCREEN_HEIGHT;
|
|
|
|
// bring to [-1, 1] range
|
|
x = x*2.0f-1.0f;
|
|
y = y*2.0f-1.0f;
|
|
}
|
|
|
|
void GetNoiseParams(const PostFX::PostFXParamBlock::paramBlock& settings, Vector4& noiseParams)
|
|
{
|
|
const float noisiness = (true == PostFX::g_noiseOverride) ? PostFX::g_noisinessOverride : settings.m_noise;
|
|
float noiseSizeMult = Lerp(settings.m_noiseSize, 16.0f, 2.0f);
|
|
|
|
noiseParams.x = NoiseEffectRandomValues.x;
|
|
noiseParams.y = NoiseEffectRandomValues.y;
|
|
noiseParams.z = noisiness;
|
|
noiseParams.w = noiseSizeMult;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void PostFX::BulletImpactOverlay::Update()
|
|
{
|
|
PostFXParamBlock::paramBlock& settings = PostFXParamBlock::GetUpdateThreadParams();
|
|
|
|
// reset all the entries
|
|
settings.m_damageEnabled[0] = false;
|
|
settings.m_damageEnabled[1] = false;
|
|
settings.m_damageEnabled[2] = false;
|
|
settings.m_damageEnabled[3] = false;
|
|
settings.m_drawDamageOverlayAfterHud = m_drawAfterHud || CNewHud::IsSniperSightActive();
|
|
settings.m_damageEndurance[0] = false;
|
|
settings.m_damageEndurance[1] = false;
|
|
settings.m_damageEndurance[2] = false;
|
|
settings.m_damageEndurance[3] = false;
|
|
|
|
if (IsAnyUpdating() == false || m_disabled || CPhoneMgr::CamGetState())
|
|
{
|
|
return;
|
|
}
|
|
|
|
const PostFX::BulletImpactOverlay::Settings& dmgSettings = settings.m_fpvMotionBlurActive ? g_bulletImpactOverlay.ms_settings[1] : g_bulletImpactOverlay.ms_settings[0];
|
|
|
|
// cache player position
|
|
Vector3 playerPos = CGameWorld::FindLocalPlayerCoors();
|
|
const float playerPosVerticalBias = 0.1f;
|
|
playerPos.z += playerPosVerticalBias;
|
|
settings.m_damagePlayerPos.Set(playerPos);
|
|
|
|
for (int i = 0; i < NUM_ENTRIES; i++)
|
|
{
|
|
Entry* pEntry = &m_entries[i];
|
|
|
|
// update
|
|
UpdateTiming(pEntry, dmgSettings);
|
|
|
|
// skip if it's just finished or if sniper sight is up
|
|
if (pEntry->m_startTime == 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// enable bullet impact
|
|
settings.m_damageFrozen[i] = pEntry->m_bFrozen;
|
|
settings.m_damageEnabled[i] = true;
|
|
settings.m_damageFiringPos[i].Set(pEntry->m_firingWeaponPos);
|
|
settings.m_damageFiringPos[i].w = pEntry->m_fFadeLevel;
|
|
settings.m_damageEndurance[i] = pEntry->m_bIsEnduranceDamage;
|
|
|
|
// Freeze after first update
|
|
pEntry->m_bFrozen = true;
|
|
}
|
|
}
|
|
|
|
static bool PostFXSegmentSegmentIntersection(const Vector2& A0, const Vector2& A1, const Vector2& B0, const Vector2& B1, Vector2& intPt)
|
|
{
|
|
float s, t;
|
|
float num, denom;
|
|
|
|
denom = A0.x*(B1.y-B0.y) + A1.x*(B0.y-B1.y) + B1.x*(A1.y-A0.y) + B0.x*(A0.y-A1.y);
|
|
if (denom == 0.0f)
|
|
return false;
|
|
|
|
num = A0.x*(B1.y-B0.y) + B0.x*(A0.y-B1.y) + B1.x*(B0.y-A0.y);
|
|
s = num/denom;
|
|
|
|
num = -(A0.x * (B0.y-A1.y) + A1.x*(A0.y-B0.y) + B0.x*(A1.y-A0.y));
|
|
t = num / denom;
|
|
|
|
bool bInt = false;
|
|
|
|
if ((0.0 < s) && (s < 1.0) && (0.0 < t) && (t < 1.0))
|
|
bInt = true;
|
|
|
|
intPt.x = A0.x + s*(A1.x-A0.x);
|
|
intPt.y = A0.y + s*(A1.y-A0.y);
|
|
|
|
return bInt;
|
|
}
|
|
|
|
#define POSTFX_DAMAGEOVERLAY_DEBUG (__BANK && 1)
|
|
#if POSTFX_DAMAGEOVERLAY_DEBUG
|
|
static void DamageOverlayDebugRender(Vector2& playerScreenPos, Vector2& firingScreenPos, Vector2& hitScreenDir, Vector2& screenEdgeIntPt, Vector2& screenEdgeTest1, float baseOffscrenBiasMult)
|
|
{
|
|
if (PostFX::g_bulletImpactOverlay.m_bEnableDebugRender)
|
|
{
|
|
Vector2 textPos(0.1f, 0.1f);
|
|
char pName[256];
|
|
|
|
const Color32 intersectionCol = Color32(0xffff0000);
|
|
const Color32 playerPosCol = Color32(0xff00ff00);
|
|
const Color32 firingPosCol = Color32(0xff0000ff);
|
|
|
|
// Print player pos
|
|
sprintf(&pName[0],"PLAYER POS: %2.2f, %2.2f", playerScreenPos.x, playerScreenPos.y);
|
|
grcDebugDraw::Text(textPos, playerPosCol, pName, true);
|
|
textPos.y += 0.02f;
|
|
// Print firing pos
|
|
sprintf(&pName[0],"FIRING POS: %2.2f, %2.2f", firingScreenPos.x, firingScreenPos.y);
|
|
grcDebugDraw::Text(textPos, firingPosCol, pName, true);
|
|
textPos.y += 0.02f;
|
|
// Print intersection point
|
|
sprintf(&pName[0],"INT PT: %2.2f, %2.2f", screenEdgeIntPt.x, screenEdgeIntPt.y);
|
|
grcDebugDraw::Text(textPos, intersectionCol, pName, true);
|
|
textPos.y += 0.02f;
|
|
// Print screenEdgeTest1
|
|
sprintf(&pName[0],"EDGETEST PT: %2.2f, %2.2f", screenEdgeTest1.x, screenEdgeTest1.y);
|
|
grcDebugDraw::Text(textPos, Color32(255,0,0,255), pName, true);
|
|
textPos.y += 0.02f;
|
|
// Print hit direction
|
|
sprintf(&pName[0],"HIT DIR: %2.2f, %2.2f", hitScreenDir.x, hitScreenDir.y);
|
|
grcDebugDraw::Text(textPos, Color32(255,255,255,255), pName, true);
|
|
textPos.y += 0.02f;
|
|
|
|
// Print dot product
|
|
sprintf(&pName[0],"O/S MULT: %2.2f", baseOffscrenBiasMult);
|
|
grcDebugDraw::Text(textPos, Color32(255,255,255,255), pName, true);
|
|
|
|
// Draw intersection point
|
|
grcDebugDraw::Circle(Vector2(screenEdgeIntPt.x*0.5f + 0.5f, (screenEdgeIntPt.y*0.5f + 0.5f)), 0.05f, intersectionCol);
|
|
// Draw player pos
|
|
grcDebugDraw::Circle(Vector2(playerScreenPos.x*0.5f + 0.5f, (playerScreenPos.y*0.5f + 0.5f)), 0.05f, playerPosCol);
|
|
// Draw firing pos
|
|
grcDebugDraw::Circle(Vector2(firingScreenPos.x*0.5f + 0.5f, (firingScreenPos.y*0.5f + 0.5f)), 0.05f, firingPosCol);
|
|
// Draw screenEdgeTest1
|
|
grcDebugDraw::Circle(Vector2(screenEdgeTest1.x*0.5f + 0.5f, (screenEdgeTest1.y*0.5f + 0.5f)), 0.05f, firingPosCol);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
static void PostFXDamageOverlay(grcRenderTarget* target, grcEffectTechnique technique, u32 pass, const PostFX::PostFXParamBlock::paramBlock& settings)
|
|
{
|
|
const PostFX::BulletImpactOverlay::Settings& dmgSettings = settings.m_fpvMotionBlurActive ? PostFX::g_bulletImpactOverlay.ms_settings[1] : PostFX::g_bulletImpactOverlay.ms_settings[0];
|
|
|
|
#if RAGE_TIMEBARS
|
|
PF_PUSH_MARKER(passName[pass]);
|
|
#endif // RAGE_TIMEBARS
|
|
if (PostFX::g_pDamageOverlayTexture == NULL)
|
|
return;
|
|
|
|
if (target)
|
|
{
|
|
grcTextureFactory::GetInstance().LockRenderTarget(0, target, NULL);
|
|
}
|
|
|
|
const float aspectRatio = CHudTools::GetAspectRatio();
|
|
const grcViewport* pPrevVP = grcViewport::GetCurrent();
|
|
grcViewport damageOverlayVP;
|
|
damageOverlayVP.Ortho(-aspectRatio, aspectRatio, 1.0f, -1.0f, 0.0f, 1.0f);
|
|
|
|
#if SUPPORT_MULTI_MONITOR
|
|
if(GRCDEVICE.GetMonitorConfig().isMultihead())
|
|
{
|
|
const GridMonitor &mon = GRCDEVICE.GetMonitorConfig().getLandscapeMonitor();
|
|
damageOverlayVP.SetWindow(mon.uGridPosX * mon.getWidth(), mon.uGridPosY * mon.getHeight(), mon.getWidth(), mon.getHeight());
|
|
}
|
|
#endif // SUPPORT_MULTI_MONITOR
|
|
grcViewport::SetCurrent(&damageOverlayVP);
|
|
|
|
// Set shader constants
|
|
Vector4 damageOverlayMiscParams;
|
|
damageOverlayMiscParams.Zero();
|
|
PostFXShader->SetVar(DamageOverlayMiscId, damageOverlayMiscParams);
|
|
PostFXShader->SetVar(TextureID_1, PostFX::g_pDamageOverlayTexture);
|
|
|
|
// Bind the shader
|
|
// no shmoo for this - not fullscreen
|
|
AssertVerify(PostFXShader->BeginDraw(grmShader::RMC_DRAW,true,technique));
|
|
PostFXShader->Bind((int)pass);
|
|
|
|
GRCDEVICE.SetVertexDeclaration(PostFX::g_damageSliceDecl);
|
|
|
|
const Vector2 L0 = Vector2(-1.0f, -1.0f);
|
|
const Vector2 L1 = Vector2(-1.0f, 1.0f);
|
|
const Vector2 R0 = Vector2(1.0f, -1.0f);
|
|
const Vector2 R1 = Vector2(1.0f, 1.0f);
|
|
const Vector2 T0 = Vector2(-1.0f, -1.0f);
|
|
const Vector2 T1 = Vector2(1.0f, -1.0f);
|
|
const Vector2 B0 = Vector2(-1.0f, 1.0f);
|
|
const Vector2 B1 = Vector2(1.0f, 1.0f);
|
|
|
|
Vector3 playeWorldPos = Vector3(settings.m_damagePlayerPos.x, settings.m_damagePlayerPos.y, settings.m_damagePlayerPos.z);
|
|
|
|
Vector2 playerScreenPos;
|
|
GetNormScreenPosFromWorldPos(playeWorldPos, playerScreenPos.x, playerScreenPos.y);
|
|
|
|
// If player is partially or fully off-screen or outside the predefined "safe zone",
|
|
// fall back to using the head position (should almost always be on screen).
|
|
// If that fails, fall back to using the bottom-centre of the screen (0.0, 0.5).
|
|
const float screenSafeZoneLength = PostFX::BulletImpactOverlay::ms_screenSafeZoneLength;
|
|
if (Abs(playerScreenPos.x) > screenSafeZoneLength || Abs(playerScreenPos.y) > screenSafeZoneLength)
|
|
{
|
|
TUNE_GROUP_BOOL(POST_FX, bEnableDamageOverlayPositionFix, true);
|
|
if (bEnableDamageOverlayPositionFix)
|
|
{
|
|
bool bValidHeadPosition = false;
|
|
if (!camInterface::GetGameplayDirector().GetFirstPersonShooterCamera())
|
|
{
|
|
const CPed* pLocalPlayer = CGameWorld::FindLocalPlayer();
|
|
if (pLocalPlayer)
|
|
{
|
|
Vector3 headPosition = pLocalPlayer->GetBonePositionCached(BONETAG_HEAD);
|
|
Vector2 headScreenPos;
|
|
GetNormScreenPosFromWorldPos(headPosition, headScreenPos.x, headScreenPos.y);
|
|
if (Abs(headScreenPos.x) <= screenSafeZoneLength && Abs(headScreenPos.y) <= screenSafeZoneLength)
|
|
{
|
|
bValidHeadPosition = true;
|
|
playeWorldPos = headPosition;
|
|
playerScreenPos = headScreenPos;
|
|
}
|
|
}
|
|
}
|
|
|
|
TUNE_GROUP_BOOL(POST_FX, bForceUseCameraPositionForDamageOverlay, false);
|
|
if (!bValidHeadPosition || bForceUseCameraPositionForDamageOverlay)
|
|
{
|
|
// Head position is invalid; use the bottom-centre of the screen as the player position.
|
|
// Push camera position forwards slightly to ensure it's "on-screen". Fixes issues with setting firingWorldPos below (assumes player pos is on-screen).
|
|
const grcViewport* pVp = gVpMan.GetRenderGameGrcViewport();
|
|
float fNearClipDist = pVp ? pVp->GetNearClip() : 0.1f;
|
|
Vector3 camPos = camInterface::GetPos() + (camInterface::GetFront() * fNearClipDist);
|
|
playeWorldPos = camPos;
|
|
playerScreenPos.Zero();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Vector3 camPos = camInterface::GetPos();
|
|
playeWorldPos = camPos;
|
|
playerScreenPos.Zero();
|
|
}
|
|
}
|
|
|
|
|
|
static Vector3 ms_colourTop;
|
|
static Vector3 ms_colourBottom;
|
|
|
|
float globalAlphaBottom = dmgSettings.globalAlphaBottom;
|
|
float globalAlphaTop = dmgSettings.globalAlphaTop;
|
|
|
|
if (NetworkInterface::IsGameInProgress())
|
|
{
|
|
globalAlphaBottom += globalAlphaBottom*0.20f;
|
|
globalAlphaTop += globalAlphaTop*0.20f;
|
|
|
|
globalAlphaBottom = Saturate(globalAlphaBottom);
|
|
globalAlphaTop = Saturate(globalAlphaTop);
|
|
}
|
|
|
|
Color32 colBot(0, 0, 0);
|
|
Color32 colTop(0, 0, 0);
|
|
|
|
for (int i = 0; i < PostFX::BulletImpactOverlay::GetNumEntries(); i++)
|
|
{
|
|
if (settings.m_damageEnabled[i] == false)
|
|
continue;
|
|
|
|
if (settings.m_damageEndurance[i] == true)
|
|
{
|
|
colBot = Color32(dmgSettings.colourBottomEndurance.x, dmgSettings.colourBottomEndurance.y, dmgSettings.colourBottomEndurance.z, globalAlphaBottom);
|
|
colTop = Color32(dmgSettings.colourTopEndurance.x, dmgSettings.colourTopEndurance.y, dmgSettings.colourTopEndurance.z, globalAlphaTop);
|
|
}
|
|
else
|
|
{
|
|
colBot = Color32(dmgSettings.colourBottom.x, dmgSettings.colourBottom.y, dmgSettings.colourBottom.z, globalAlphaBottom);
|
|
colTop= Color32(dmgSettings.colourTop.x, dmgSettings.colourTop.y, dmgSettings.colourTop.z, globalAlphaTop);
|
|
}
|
|
|
|
// Take into account current entry's alpha
|
|
colBot.SetAlpha(((u8)(colBot.GetAlphaf()*settings.m_damageFiringPos[i].w*255.0f)));
|
|
colTop.SetAlpha(((u8)(colTop.GetAlphaf()*settings.m_damageFiringPos[i].w*255.0f)));
|
|
|
|
// Adjust firing world position to ensure it's within screen bounds (assuming the player ped is!)
|
|
Vector3 firingWorldPos = Vector3(settings.m_damageFiringPos[i].x, settings.m_damageFiringPos[i].y, settings.m_damageFiringPos[i].z);
|
|
Vector3 hitWorldDir = playeWorldPos-firingWorldPos;
|
|
|
|
if (hitWorldDir.FiniteElements() == false)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
hitWorldDir.NormalizeSafe();
|
|
firingWorldPos = playeWorldPos - hitWorldDir*0.1f;
|
|
|
|
// Get firing position in screen space
|
|
Vector2 firingScreenPos;
|
|
GetNormScreenPosFromWorldPos(firingWorldPos, firingScreenPos.x, firingScreenPos.y);
|
|
|
|
// Compute direction vector in screen space
|
|
Vector2 hitScreenDir = playerScreenPos-firingScreenPos;
|
|
hitScreenDir.NormalizeSafe();
|
|
|
|
// If the firing position is within the screen bounds we won't get an intersection,
|
|
// so always push it further away enough to make sure it's off-screen.
|
|
Vector2 screenEdgeTest0 = playerScreenPos;
|
|
Vector2 screenEdgeTest1 = firingScreenPos - (hitScreenDir*10.0f);
|
|
Vector2 screenEdgeIntPt;
|
|
|
|
bool bIntFound = false;
|
|
bool bVerticalEdge = false;
|
|
|
|
if (!bIntFound)
|
|
{
|
|
bIntFound = PostFXSegmentSegmentIntersection(T0, T1, screenEdgeTest0, screenEdgeTest1, screenEdgeIntPt);
|
|
}
|
|
if (!bIntFound)
|
|
{
|
|
bIntFound = PostFXSegmentSegmentIntersection(B0, B1, screenEdgeTest0, screenEdgeTest1, screenEdgeIntPt);
|
|
}
|
|
if (!bIntFound)
|
|
{
|
|
bIntFound = PostFXSegmentSegmentIntersection(L0, L1, screenEdgeTest0, screenEdgeTest1, screenEdgeIntPt);
|
|
bVerticalEdge = bIntFound;
|
|
}
|
|
if (!bIntFound)
|
|
{
|
|
bIntFound = PostFXSegmentSegmentIntersection(R0, R1, screenEdgeTest0, screenEdgeTest1, screenEdgeIntPt);
|
|
bVerticalEdge = bIntFound;
|
|
}
|
|
|
|
const u32 vertexColTop = colTop.GetDeviceColor();
|
|
const u32 vertexColBot = colBot.GetDeviceColor();
|
|
|
|
// Derive vectors for sprite
|
|
Vector3 spritePos(screenEdgeIntPt.x, -screenEdgeIntPt.y, 0.0f);
|
|
Vector3 spriteForward(-hitScreenDir.x, hitScreenDir.y, 0.0f);
|
|
Vector3 spriteSide;
|
|
Vector3 spriteUp = Vector3(0.0f, 0.0f, -1.0f);
|
|
spriteSide.Cross(spriteUp, spriteForward);
|
|
spriteSide.NormalizeSafe();
|
|
|
|
// Scale to length
|
|
const float spriteLength = dmgSettings.spriteLength;
|
|
const float spriteBaseWidth = dmgSettings.spriteBaseWidth;
|
|
const float spriteTipWidth = dmgSettings.spriteTipWidth;
|
|
spriteForward *= spriteLength;
|
|
|
|
// If current sprite is frozen, used previously cached data
|
|
if (settings.m_damageFrozen[i])
|
|
{
|
|
spritePos.x = PostFX::BulletImpactOverlay::ms_frozenDamagePosDir[i].x;
|
|
spritePos.y = PostFX::BulletImpactOverlay::ms_frozenDamagePosDir[i].y;
|
|
spriteForward.x = PostFX::BulletImpactOverlay::ms_frozenDamagePosDir[i].z;
|
|
spriteForward.y = PostFX::BulletImpactOverlay::ms_frozenDamagePosDir[i].w;
|
|
spriteSide.Cross(spriteUp, spriteForward);
|
|
spriteSide.NormalizeSafe();
|
|
}
|
|
else
|
|
{
|
|
// Cache sprite data for next frames
|
|
PostFX::BulletImpactOverlay::ms_frozenDamagePosDir[i].x = spritePos.x;
|
|
PostFX::BulletImpactOverlay::ms_frozenDamagePosDir[i].y = spritePos.y;
|
|
PostFX::BulletImpactOverlay::ms_frozenDamagePosDir[i].z = spriteForward.x;
|
|
PostFX::BulletImpactOverlay::ms_frozenDamagePosDir[i].w = spriteForward.y;
|
|
}
|
|
|
|
// Compute vertices
|
|
Vector3 verts[6];
|
|
verts[0] = spritePos - (spriteSide*spriteBaseWidth);
|
|
verts[1] = spritePos + (spriteSide*spriteBaseWidth);
|
|
verts[2] = spritePos + (spriteSide*spriteTipWidth) - spriteForward;
|
|
verts[3] = spritePos - (spriteSide*spriteTipWidth) - spriteForward;
|
|
|
|
// verts for extra quad to avoid clipping
|
|
verts[4] = spritePos + (spriteSide*spriteTipWidth) + spriteForward*10.0f;
|
|
verts[5] = spritePos - (spriteSide*spriteTipWidth) + spriteForward*10.0f;
|
|
|
|
// Compute UVs for projective interpolation
|
|
const Vector2 v0 = Vector2(verts[0].x, verts[0].y);
|
|
const Vector2 v1 = Vector2(verts[1].x, verts[1].y);
|
|
const Vector2 v2 = Vector2(verts[2].x, verts[2].y);
|
|
const Vector2 v3 = Vector2(verts[3].x, verts[3].y);
|
|
Vector2 int02_31;
|
|
PostFXSegmentSegmentIntersection(v0, v2, v3, v1, int02_31);
|
|
|
|
float dist[4];
|
|
dist[0] = (int02_31-Vector2(verts[0].x, verts[0].y)).Mag();
|
|
dist[1] = (int02_31-Vector2(verts[1].x, verts[1].y)).Mag();
|
|
dist[2] = (int02_31-Vector2(verts[2].x, verts[2].y)).Mag();
|
|
dist[3] = (int02_31-Vector2(verts[3].x, verts[3].y)).Mag();
|
|
float q[4];
|
|
q[0] = (dist[0]+dist[2])/dist[2];
|
|
q[1] = (dist[1]+dist[3])/dist[3];
|
|
q[2] = (dist[2]+dist[0])/dist[0];
|
|
q[3] = (dist[3]+dist[1])/dist[1];
|
|
|
|
// Force vertices from the sprite base slightly out of screen
|
|
float baseOffscrenBiasMult = dmgSettings.angleScalingMult*Abs(Dot(hitScreenDir, bVerticalEdge ? Vector2(0.0f, 1.0f) : Vector2(1.0f, 0.0f)));
|
|
|
|
if (settings.m_damageFrozen[i])
|
|
baseOffscrenBiasMult = PostFX::BulletImpactOverlay::ms_frozenDamageOffsetMult[i];
|
|
else
|
|
PostFX::BulletImpactOverlay::ms_frozenDamageOffsetMult[i] = baseOffscrenBiasMult;
|
|
|
|
Vector3 dir30 = verts[0]-verts[3];
|
|
Vector3 dir21 = verts[1]-verts[2];
|
|
verts[0] += dir30*baseOffscrenBiasMult;
|
|
verts[1] += dir21*baseOffscrenBiasMult;
|
|
|
|
|
|
grcDrawMode drawMode = drawQuads;
|
|
u32 numVerts = 8;
|
|
#if !API_QUADS_SUPPORT
|
|
drawMode = drawTriStrip;
|
|
numVerts = 10;
|
|
#endif
|
|
PostFX::grcSliceVertex *rVerts = (PostFX::grcSliceVertex*) GRCDEVICE.BeginVertices(drawMode, numVerts, sizeof(PostFX::grcSliceVertex));
|
|
int vertexIndex = 0;
|
|
|
|
Vector3 uv0 = Vector3(0.0f, 0.0f, 1.0f)*q[0];
|
|
Vector3 uv1 = Vector3(1.0f, 0.0f, 1.0f)*q[1];
|
|
Vector3 uv2 = Vector3(1.0f, 1.0f, 1.0f)*q[2];
|
|
Vector3 uv3 = Vector3(0.0f, 1.0f, 1.0f)*q[3];
|
|
|
|
#if API_QUADS_SUPPORT
|
|
rVerts[vertexIndex++].Set(verts[0].x, verts[0].y, 0.0f, vertexColBot, uv0.x, uv0.y, uv0.z); // 0
|
|
rVerts[vertexIndex++].Set(verts[1].x, verts[1].y, 0.0f, vertexColBot, uv1.x, uv1.y, uv1.z); // 1
|
|
|
|
rVerts[vertexIndex++].Set(verts[2].x, verts[2].y, 0.0f, vertexColTop, uv2.x, uv2.y, uv2.z); // 2
|
|
rVerts[vertexIndex++].Set(verts[3].x, verts[3].y, 0.0f, vertexColTop, uv3.x, uv3.y, uv3.z); // 4
|
|
|
|
// avoid clipping
|
|
rVerts[vertexIndex++].Set(verts[0].x, verts[0].y, 0.0f, vertexColBot, uv0.x, uv0.y, uv0.z); // 0
|
|
rVerts[vertexIndex++].Set(verts[1].x, verts[1].y, 0.0f, vertexColBot, uv1.x, uv1.y, uv1.z); // 1
|
|
rVerts[vertexIndex++].Set(verts[4].x, verts[4].y, 0.0f, vertexColBot, uv0.x, uv0.y, uv0.z); // 0
|
|
rVerts[vertexIndex++].Set(verts[5].x, verts[5].y, 0.0f, vertexColBot, uv1.x, uv1.y, uv1.z); // 1
|
|
#else
|
|
rVerts[vertexIndex++].Set(verts[0].x, verts[0].y, 0.0f, vertexColBot, uv0.x, uv0.y, uv0.z); // 0
|
|
rVerts[vertexIndex++].Set(verts[1].x, verts[1].y, 0.0f, vertexColBot, uv1.x, uv1.y, uv1.z); // 1
|
|
|
|
rVerts[vertexIndex++].Set(verts[3].x, verts[3].y, 0.0f, vertexColTop, uv3.x, uv3.y, uv3.z); // 4
|
|
rVerts[vertexIndex++].Set(verts[2].x, verts[2].y, 0.0f, vertexColTop, uv2.x, uv2.y, uv2.z); // 2
|
|
|
|
//degenerates
|
|
rVerts[vertexIndex++].Set(verts[2].x, verts[2].y, 0.0f, vertexColTop, uv2.x, uv2.y, uv2.z); // 2
|
|
rVerts[vertexIndex++].Set(verts[0].x, verts[0].y, 0.0f, vertexColBot, uv0.x, uv0.y, uv0.z); // 0
|
|
|
|
// avoid clipping
|
|
rVerts[vertexIndex++].Set(verts[0].x, verts[0].y, 0.0f, vertexColBot, uv0.x, uv0.y, uv0.z); // 0
|
|
rVerts[vertexIndex++].Set(verts[1].x, verts[1].y, 0.0f, vertexColBot, uv1.x, uv1.y, uv1.z); // 1
|
|
|
|
rVerts[vertexIndex++].Set(verts[5].x, verts[5].y, 0.0f, vertexColBot, uv1.x, uv1.y, uv1.z); // 1
|
|
rVerts[vertexIndex++].Set(verts[4].x, verts[4].y, 0.0f, vertexColBot, uv0.x, uv0.y, uv0.z); // 0
|
|
#endif
|
|
|
|
GRCDEVICE.EndVertices(rVerts+numVerts);
|
|
|
|
#if POSTFX_DAMAGEOVERLAY_DEBUG
|
|
DamageOverlayDebugRender(playerScreenPos, firingScreenPos, hitScreenDir, screenEdgeIntPt, screenEdgeTest1, baseOffscrenBiasMult);
|
|
#endif
|
|
}
|
|
|
|
// unbind
|
|
PostFXShader->UnBind();
|
|
PostFXShader->EndDraw();
|
|
|
|
// unlock, no resolve
|
|
if (target)
|
|
{
|
|
grcResolveFlags resolveFlags;
|
|
resolveFlags.NeedResolve = false;
|
|
resolveFlags.ClearColor = false;
|
|
resolveFlags.ClearDepthStencil = false;
|
|
grcTextureFactory::GetInstance().UnlockRenderTarget(0, &resolveFlags);
|
|
}
|
|
|
|
grcViewport::SetCurrent(pPrevVP);
|
|
|
|
#if RAGE_TIMEBARS
|
|
PF_POP_MARKER();
|
|
#endif // RAGE_TIMEBARS
|
|
}
|
|
|
|
float FilmicTonemap(const float inputValue, const Vector4& srcFilmic0, const Vector4& srcFilmic1)
|
|
{
|
|
float A = srcFilmic0.x;
|
|
float B = srcFilmic0.y;
|
|
float C = srcFilmic0.z;
|
|
float D = srcFilmic0.w;
|
|
float E = srcFilmic1.x;
|
|
float F = srcFilmic1.y;
|
|
|
|
return (((inputValue*(A*inputValue+C*B)+D*E)/(inputValue*(A*inputValue+B)+D*F))-E/F);
|
|
}
|
|
|
|
float PostFX::FilmicTweakedTonemap(const float inputValue)
|
|
{
|
|
const PostFXParamBlock::paramBlock& settings = PostFXParamBlock::GetRenderThreadParams();
|
|
return FilmicTonemap(inputValue, settings.m_filmicParams[0], settings.m_filmicParams[1]);
|
|
}
|
|
|
|
void PostFX::GetFilmicParams(Vector4& filmic0, Vector4& filmic1)
|
|
{
|
|
const PostFXParamBlock::paramBlock& settings = PostFXParamBlock::GetRenderThreadParams();
|
|
|
|
// source terms
|
|
Vector4 srcFilmic0 = settings.m_filmicParams[0];
|
|
Vector4 srcFilmic1 = settings.m_filmicParams[1];
|
|
|
|
// remap filmicId[0]
|
|
Vector4 filmicParams0 = srcFilmic0;
|
|
filmicParams0.z = 1.0f / FilmicTonemap(settings.m_filmicParams[1].GetZ(), settings.m_filmicParams[0], settings.m_filmicParams[1]);
|
|
filmicParams0.w = 1.0f / settings.m_filmicParams[1].GetZ(); // one over white point
|
|
|
|
// remap filmicId[1]
|
|
Vector4 filmicParams1;
|
|
filmicParams1.x = srcFilmic0.z*srcFilmic0.y; // C_mul_B
|
|
filmicParams1.y = srcFilmic0.w*srcFilmic1.x; // D_mul_E
|
|
filmicParams1.z = srcFilmic0.w*srcFilmic1.y; // D_mul_F
|
|
filmicParams1.w = srcFilmic1.x/srcFilmic1.y; // E_div_F
|
|
|
|
filmic0 = filmicParams0;
|
|
filmic1 = filmicParams1;
|
|
}
|
|
|
|
void PostFX::GetDefaultFilmicParams(Vector4& filmic0, Vector4& filmic1)
|
|
{
|
|
// source terms
|
|
const Vector4 srcFilmic0( GetTonemapParam(TONEMAP_FILMIC_A_BRIGHT),
|
|
GetTonemapParam(TONEMAP_FILMIC_B_BRIGHT),
|
|
GetTonemapParam(TONEMAP_FILMIC_C_BRIGHT),
|
|
GetTonemapParam(TONEMAP_FILMIC_D_BRIGHT));
|
|
|
|
const Vector4 srcFilmic1( GetTonemapParam(TONEMAP_FILMIC_E_BRIGHT),
|
|
GetTonemapParam(TONEMAP_FILMIC_F_BRIGHT),
|
|
GetTonemapParam(TONEMAP_FILMIC_W_BRIGHT),
|
|
0.0f );
|
|
|
|
// remap filmicId[0]
|
|
Vector4 filmicParams0 = srcFilmic0;
|
|
filmicParams0.z = 1.0f / FilmicTonemap(srcFilmic1.GetZ(), srcFilmic0, srcFilmic1);
|
|
filmicParams0.w = 1.0f / srcFilmic1.GetZ(); // one over white point
|
|
|
|
// remap filmicId[1]
|
|
Vector4 filmicParams1;
|
|
filmicParams1.x = srcFilmic0.z*srcFilmic0.y; // C_mul_B
|
|
filmicParams1.y = srcFilmic0.w*srcFilmic1.x; // D_mul_E
|
|
filmicParams1.z = srcFilmic0.w*srcFilmic1.y; // D_mul_F
|
|
filmicParams1.w = srcFilmic1.x/srcFilmic1.y; // E_div_F
|
|
|
|
filmic0 = filmicParams0;
|
|
filmic1 = filmicParams1;
|
|
}
|
|
|
|
void PostFX::SetFilmicParams()
|
|
{
|
|
Vector4 filmicParams0, filmicParams1;
|
|
|
|
GetFilmicParams(filmicParams0, filmicParams1);
|
|
|
|
PostFXShader->SetVar(FilmicId[0], filmicParams0);
|
|
PostFXShader->SetVar(FilmicId[1], filmicParams1);
|
|
|
|
const PostFXParamBlock::paramBlock& settings = PostFXParamBlock::GetRenderThreadParams();
|
|
|
|
PostFXShader->SetVar(darkTonemapParams[0], settings.m_darkTonemapParams[0]);
|
|
PostFXShader->SetVar(darkTonemapParams[1], settings.m_darkTonemapParams[1]);
|
|
|
|
PostFXShader->SetVar(brightTonemapParams[0], settings.m_brightTonemapParams[0]);
|
|
PostFXShader->SetVar(brightTonemapParams[1], settings.m_brightTonemapParams[1]);
|
|
|
|
PostFXShader->SetVar(tonemapParams, settings.m_tonemapParams);
|
|
}
|
|
|
|
void PostFX::DrawBulletImpactOverlaysAfterHud()
|
|
{
|
|
GRC_ALLOC_SCOPE_AUTO_PUSH_POP()
|
|
|
|
const PostFXParamBlock::paramBlock& settings = PostFXParamBlock::GetRenderThreadParams();
|
|
|
|
bool bDrawDamageOverlay = settings.m_drawDamageOverlayAfterHud && (settings.m_damageEnabled[0] || settings.m_damageEnabled[1] || settings.m_damageEnabled[2] || settings.m_damageEnabled[3]);
|
|
if (bDrawDamageOverlay)
|
|
{
|
|
grcBlendStateHandle prevBS = grcStateBlock::BS_Active;
|
|
grcDepthStencilStateHandle prevDDS = grcStateBlock::DSS_Active;
|
|
grcRasterizerStateHandle prevRS = grcStateBlock::RS_Active;
|
|
|
|
SetNonDepthFXStateBlocks();
|
|
PostFXDamageOverlay(NULL, PostFXTechnique, pp_DamageOverlay, settings);
|
|
|
|
grcStateBlock::SetStates(prevRS, prevDDS, prevBS);
|
|
}
|
|
}
|
|
|
|
#if __BANK
|
|
void PostFX::SetDebugParams()
|
|
{
|
|
for (int i = 0; i < NUM_DEBUG_PARAMS; i++)
|
|
{
|
|
PostFXShader->SetVar(DebugParamsId[i], DebugParams[i]);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void PostFX::SetBloomParams()
|
|
{
|
|
const PostFXParamBlock::paramBlock& settings = PostFXParamBlock::GetRenderThreadParams();
|
|
|
|
float ooMaxMinusMin = 1.0f;
|
|
float threshold = settings.m_bloomThresholdMax;
|
|
|
|
if (settings.m_bloomThresholdWidth > 0.0f)
|
|
{
|
|
const float maxThreshold = Max<float>(0.0f, settings.m_bloomThresholdMax + (settings.m_bloomThresholdWidth * 0.5f));
|
|
const float minThreshold = Max<float>(0.0f, settings.m_bloomThresholdMax - (settings.m_bloomThresholdWidth * 0.5f));
|
|
|
|
ooMaxMinusMin = 1.0f / (maxThreshold - minThreshold);
|
|
threshold = minThreshold;
|
|
}
|
|
|
|
Vector4 BloomParams = Vector4(
|
|
threshold,
|
|
settings.m_bloomIntensity,
|
|
ooMaxMinusMin,
|
|
0.0f);
|
|
|
|
#if __BANK //for screenshots
|
|
if (NoBloom==true)
|
|
{
|
|
BloomParams.y = 0.0f;
|
|
}
|
|
#endif
|
|
|
|
PostFXShader->SetVar(BloomParamsId, BloomParams);
|
|
}
|
|
|
|
void PostFX::SetExposureParams()
|
|
{
|
|
const float timeStep = fwTimer::GetTimeStep();
|
|
|
|
const PostFXParamBlock::paramBlock& settings = PostFXParamBlock::GetRenderThreadParams();
|
|
|
|
Vector4 e0 = Vector4(settings.m_exposureCurveA, settings.m_exposureCurveB, settings.m_exposureCurveOffset, settings.m_exposureTweak);
|
|
Vector4 e1 = Vector4(settings.m_exposureMin, settings.m_exposureMax, settings.m_exposurePush, timeStep);
|
|
Vector4 e2 = Vector4(0.0f, settings.m_averageExposure, settings.m_averageTimestep, settings.m_adaptionStepMult);
|
|
Vector4 e3 = Vector4(settings.m_adaptionMaxStepSize, settings.m_adaptionThreshold, settings.m_adaptionMinStepSize, BANK_SWITCH(g_overwrittenExposure, 0.0f));
|
|
|
|
PostFXShader->SetVar(TextureID_v0, LumRT);
|
|
PostFXShader->SetVar(TextureID_v1, g_prevExposureRT);
|
|
|
|
PostFXShader->SetVar(ExposureParams0Id, e0);
|
|
PostFXShader->SetVar(ExposureParams1Id, e1);
|
|
PostFXShader->SetVar(ExposureParams2Id, e2);
|
|
PostFXShader->SetVar(ExposureParams3Id, e3);
|
|
}
|
|
|
|
#if RSG_PC
|
|
|
|
void PostFX::DeviceLost()
|
|
{
|
|
}
|
|
|
|
void PostFX::DeviceReset()
|
|
{
|
|
if (targetsInitialized)
|
|
{
|
|
SetGaussianBlur();
|
|
CreateScreenBasedRenderTargets(VideoResManager::GetSceneWidth(), VideoResManager::GetSceneHeight());
|
|
g_resetAdaptedLumCount = NUM_RESET_FRAMES;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void PostFX::ResetMSAAShaders()
|
|
{
|
|
delete PostFXShader;
|
|
InitMSAAShaders();
|
|
}
|
|
|
|
void PostFX::InitMSAAShaders()
|
|
{
|
|
ASSET.PushFolder("common:/shaders");
|
|
|
|
PostFXShader = grmShaderFactory::GetInstance().Create();
|
|
|
|
PostFXShader->Load(
|
|
#if DEVICE_MSAA
|
|
GRCDEVICE.GetMSAA()>1 ? "postfxMS" :
|
|
#endif
|
|
"postfx");
|
|
|
|
GENSHMOO_ONLY(PostFxShmoo = )ShmooHandling::Register("postfx", PostFXShader, true, 0.05f);
|
|
|
|
PostFXTechnique = PostFXShader->LookupTechnique("PostFx");
|
|
CloudDepthTechGroup = grmShader::FindTechniqueGroupId("clouddepth");
|
|
|
|
#if MSAA_EDGE_PASS
|
|
if (DeferredLighting::IsEdgePassEnabled())
|
|
{
|
|
PostFXShaderMS0 = grmShaderFactory::GetInstance().Create();
|
|
PostFXShaderMS0->Load("postfxMS0");
|
|
}
|
|
#endif //MSAA_EDGE_PASS
|
|
|
|
// Get variable handles
|
|
// Miscs
|
|
|
|
// handle for the variable that provides the size of one texel
|
|
TexelSizeId = PostFXShader->LookupVar("TexelSize");
|
|
|
|
GBufferTexture0ParamId = PostFXShader->LookupVar("GBufferTexture0Param");
|
|
|
|
#if __BANK
|
|
for (int i = 0; i < NUM_DEBUG_PARAMS; i++)
|
|
{
|
|
DebugParams[i] = Vector4(0.0, 0.0, 0.0, 0.0);
|
|
|
|
char name[16];
|
|
sprintf(name, "debugParams%d", i);
|
|
DebugParamsId[i] = PostFXShader->LookupVar(name, false);
|
|
}
|
|
#endif
|
|
|
|
// DOF
|
|
DofProjId = PostFXShader->LookupVar("DOF_PROJ");
|
|
DofShearId = PostFXShader->LookupVar("DOF_SHEAR");
|
|
DofParamsId = PostFXShader->LookupVar("DOF_PARAMS");
|
|
HiDofParamsId = PostFXShader->LookupVar("HI_DOF_PARAMS");
|
|
HiDofSmallBlurId = PostFXShader->LookupVar("hiDofUseSmallBlurOnly");
|
|
HiDofMiscParamsId = PostFXShader->LookupVar("hiDofMiscParams");
|
|
|
|
#if BOKEH_SUPPORT
|
|
#if RSG_PC
|
|
if ((GRCDEVICE.GetDxFeatureLevel() >= 1100) NOTFINAL_ONLY(&& !PARAM_disableBokeh.Get()))
|
|
#else
|
|
if( BokehEnable )
|
|
#endif
|
|
{
|
|
PostFXBokehTechnique = PostFXShader->LookupTechnique("PostFx_Bokeh");
|
|
|
|
BokehBrightnessParams = PostFXShader->LookupVar("BokehBrightnessParams");
|
|
BokehParams1 = PostFXShader->LookupVar("BokehParams1");
|
|
BokehParams2 = PostFXShader->LookupVar("BokehParams2");
|
|
|
|
DOFTargetSize = PostFXShader->LookupVar("DOFTargetSize");
|
|
RenderTargetSize = PostFXShader->LookupVar("RenderTargetSize");
|
|
BokehEnableVar = PostFXShader->LookupVar("BokehEnableVar");
|
|
BokehGlobalAlphaVar = PostFXShader->LookupVar("BokehGlobalAlpha");
|
|
BokehAlphaCutoffVar = PostFXShader->LookupVar("BokehAlphaCutoff");
|
|
BokehSpritePointBufferVar = PostFXShader->LookupVar("BokehSpritePointBuffer");
|
|
BokehSortedIndexBufferVar = PostFXShader->LookupVar("BokehSortedIndexBuffer");
|
|
BokehSortOffsetsBufferVar = PostFXShader->LookupVar("BokehNumAddedToBuckets");
|
|
BokehSortedBufferVar = PostFXShader->LookupVar("BokehSortedListBuffer");
|
|
BokehSortLevelVar = PostFXShader->LookupVar("BokehSortLevel");
|
|
BokehSortLevelMaskVar = PostFXShader->LookupVar("BokehSortLevelMask");
|
|
#if BOKEH_SORT_BITONIC_TRANSPOSE
|
|
BokehSortTransposeMatWidthVar = PostFXShader->LookupVar("BokehSortTransposeMatWidth");
|
|
BokehSortTransposeMatHeightVar = PostFXShader->LookupVar("BokehSortTransposeMatHeight");
|
|
#endif
|
|
# if RSG_DURANGO || RSG_ORBIS
|
|
BokehOutputPointBufferVar = PostFXShader->LookupVar("BokehPointBuffer");
|
|
# endif
|
|
PostFXAdaptiveDofEnvBlurParamsVar = PostFXShader->LookupVar("PostFXAdaptiveDofEnvBlurParams");
|
|
PostFXAdaptiveDofCustomPlanesParamsVar = PostFXShader->LookupVar("PostFXAdaptiveDofCustomPlanesParams");
|
|
}
|
|
#endif
|
|
|
|
#if ADAPTIVE_DOF_OUTPUT_UAV
|
|
PostFXAdaptiveDOFParamsBufferVar = PostFXShader->LookupVar("AdaptiveDOFParamsBuffer");
|
|
#endif //ADAPTIVE_DOF_OUTPUT_UAV
|
|
#if DOF_TYPE_CHANGEABLE_IN_RAG
|
|
CurrentDOFTechniqueVar = PostFXShader->LookupVar("currentDOFTechnique");
|
|
#endif
|
|
// HDR
|
|
BloomParamsId = PostFXShader->LookupVar("BloomParams");
|
|
FilmicId[0] = PostFXShader->LookupVar("Filmic0");
|
|
FilmicId[1] = PostFXShader->LookupVar("Filmic1");
|
|
|
|
brightTonemapParams[0] = PostFXShader->LookupVar("BrightTonemapParams0");
|
|
brightTonemapParams[1] = PostFXShader->LookupVar("BrightTonemapParams1");
|
|
|
|
darkTonemapParams[0] = PostFXShader->LookupVar("DarkTonemapParams0");
|
|
darkTonemapParams[1] = PostFXShader->LookupVar("DarkTonemapParams1");
|
|
|
|
tonemapParams = PostFXShader->LookupVar("TonemapParams");
|
|
|
|
// Noise
|
|
NoiseParamsId = PostFXShader->LookupVar("NoiseParams");
|
|
|
|
// Motion Blur
|
|
DirectionalMotionBlurParamsId = PostFXShader->LookupVar( "DirectionalMotionBlurParams" );
|
|
DirectionalMotionBlurIterParamsId = PostFXShader->LookupVar( "DirectionalMotionBlurIterParams" );
|
|
|
|
MBPrevViewProjMatrixXId = PostFXShader->LookupVar("MBPrevViewProjMatrixX");
|
|
MBPrevViewProjMatrixYId = PostFXShader->LookupVar("MBPrevViewProjMatrixY");
|
|
MBPrevViewProjMatrixWId = PostFXShader->LookupVar("MBPrevViewProjMatrixW");
|
|
|
|
// Night Vision
|
|
lowLumId = PostFXShader->LookupVar("lowLum");
|
|
highLumId = PostFXShader->LookupVar("highLum");
|
|
topLumId = PostFXShader->LookupVar("topLum");
|
|
|
|
scalerLumId = PostFXShader->LookupVar("scalerLum");
|
|
|
|
offsetLumId = PostFXShader->LookupVar("offsetLum");
|
|
offsetLowLumId = PostFXShader->LookupVar("offsetLowLum");
|
|
offsetHighLumId = PostFXShader->LookupVar("offsetHighLum");
|
|
|
|
noiseLumId = PostFXShader->LookupVar("noiseLum");
|
|
noiseLowLumId = PostFXShader->LookupVar("noiseLowLum");
|
|
noiseHighLumId = PostFXShader->LookupVar("noiseHighLum");
|
|
|
|
bloomLumId = PostFXShader->LookupVar("bloomLum");
|
|
|
|
colorLumId = PostFXShader->LookupVar("colorLum");
|
|
colorLowLumId = PostFXShader->LookupVar("colorLowLum");
|
|
colorHighLumId = PostFXShader->LookupVar("colorHighLum");
|
|
|
|
#if RSG_PC
|
|
globalFreeAimDirId = PostFXShader->LookupVar("globalFreeAimDir");
|
|
#endif
|
|
//light rays
|
|
globalFograyParamId = PostFXShader->LookupVar("globalFogRayParam");
|
|
globalFograyFadeParamId = PostFXShader->LookupVar("globalFogRayFadeParam");
|
|
lightrayParamsId = PostFXShader->LookupVar("lightrayParams");
|
|
lightrayParams2Id= PostFXShader->LookupVar("lightrayParams2");
|
|
sslrParamsId = PostFXShader->LookupVar("sslrParams");
|
|
sslrCenterId = PostFXShader->LookupVar("sslrCenter");
|
|
SSLRTextureId = PostFXShader->LookupVar("SSLRTex");
|
|
GLRTextureId = PostFXShader->LookupVar("GLRTex");
|
|
|
|
//HeatHaze
|
|
heatHazeParamsId = PostFXShader->LookupVar("HeatHazeParams");
|
|
HeatHazeTex1ParamsId = PostFXShader->LookupVar("HeatHazeTex1Params");
|
|
HeatHazeTex2ParamsId = PostFXShader->LookupVar("HeatHazeTex2Params");
|
|
HeatHazeOffsetParamsId = PostFXShader->LookupVar("HeatHazeOffsetParams");
|
|
|
|
//See Through
|
|
seeThroughParamsId = PostFXShader->LookupVar("seeThroughParams");
|
|
seeThroughColorNearId = PostFXShader->LookupVar("seeThroughColorNear");
|
|
seeThroughColorFarId = PostFXShader->LookupVar("seeThroughColorFar");
|
|
seeThroughColorVisibleBaseId = PostFXShader->LookupVar("seeThroughColorVisibleBase");
|
|
seeThroughColorVisibleWarmId = PostFXShader->LookupVar("seeThroughColorVisibleWarm");
|
|
seeThroughColorVisibleHotId = PostFXShader->LookupVar("seeThroughColorVisibleHot");
|
|
|
|
//Vignetting
|
|
VignettingParamsId = PostFXShader->LookupVar("VignettingParams");
|
|
VignettingColorId = PostFXShader->LookupVar("VignettingColor");
|
|
|
|
//Damage Overlay
|
|
DamageOverlayMiscId = PostFXShader->LookupVar("DamageOverlayMisc");
|
|
DamageOverlayForwardId = PostFXShader->LookupVar("DamageOverlayForward");
|
|
DamageOverlayTangentId = PostFXShader->LookupVar("DamageOverlayTangent");
|
|
DamageOverlayCenterPosId = PostFXShader->LookupVar("DamageOverlayCenterPos");
|
|
|
|
// Gradient
|
|
GradientFilterColTopId = PostFXShader->LookupVar("GradientFilterColTop");
|
|
GradientFilterColMiddleId = PostFXShader->LookupVar("GradientFilterColMiddle");
|
|
GradientFilterColBottomId = PostFXShader->LookupVar("GradientFilterColBottom");
|
|
|
|
// Scanline
|
|
ScanlineFilterParamsId = PostFXShader->LookupVar("ScanlineFilterParams");
|
|
|
|
// AA
|
|
rcpFrameId = PostFXShader->LookupVar("rcpFrame");
|
|
|
|
// Colour correction
|
|
ColorCorrectId = PostFXShader->LookupVar("ColorCorrectHighLum");
|
|
ColorShiftId = PostFXShader->LookupVar("ColorShiftLowLum");
|
|
DesaturateId = PostFXShader->LookupVar("Desaturate");
|
|
GammaId = PostFXShader->LookupVar("Gamma");
|
|
|
|
// Exposure calculation
|
|
ExposureParams0Id = PostFXShader->LookupVar("ExposureParams0");
|
|
ExposureParams1Id = PostFXShader->LookupVar("ExposureParams1");
|
|
ExposureParams2Id = PostFXShader->LookupVar("ExposureParams2");
|
|
ExposureParams3Id = PostFXShader->LookupVar("ExposureParams3");
|
|
|
|
#if FILM_EFFECT
|
|
LensDistortionId = PostFXShader->LookupVar("LensDistortionParams");
|
|
PostFXFilmEffectTechnique = PostFXShader->LookupTechnique("PostFx_FilmEffect");
|
|
#endif
|
|
|
|
// Luminance
|
|
LuminanceDownsampleOOSrcDstSizeId = PostFXShader->LookupVar("LuminanceDownsampleOOSrcDstSize");
|
|
|
|
// Get sampler handles
|
|
// Miscs
|
|
#if USE_FXAA
|
|
FXAABackBuffer = PostFXShader->LookupVar("BackBufferTexture");
|
|
#endif // USE_FXAA
|
|
|
|
#if PTFX_APPLY_DOF_TO_PARTICLES
|
|
PtfxDepthBuffer = PostFXShader->LookupVar("PtfxDepthMapTexture");
|
|
PtfxAlphaBuffer = PostFXShader->LookupVar("PtfxAlphaMapTexture");
|
|
#endif
|
|
GBufferTextureId0 = PostFXShader->LookupVar("gbufferTexture0");
|
|
|
|
#if __XENON
|
|
GBufferTextureId2 = PostFXShader->LookupVar("gbufferTexture2");
|
|
#endif // __XENON
|
|
GBufferTextureIdDepth = PostFXShader->LookupVar("gbufferTextureDepth");
|
|
ResolvedTextureIdDepth = PostFXShader->LookupVar("ResolvedDepthTexture");
|
|
GBufferTextureIdSSAODepth = PostFXShader->LookupVar("gbufferTextureSSAODepth");
|
|
|
|
#if DEVICE_MSAA
|
|
TextureHDR_AA = PostFXShader->LookupVar("HDRTextureAA");
|
|
#endif //DEVICE_MSAA
|
|
|
|
TextureID_0 = PostFXShader->LookupVar("PostFxTexture0");
|
|
#if __PPU
|
|
TextureID_0a = PostFXShader->LookupVar("PostFxTexture0a");
|
|
#endif // __PPU
|
|
TextureID_1 = PostFXShader->LookupVar("PostFxTexture1");
|
|
|
|
TextureID_v0 = PostFXShader->LookupVar("PostFxTextureV0");
|
|
TextureID_v1 = PostFXShader->LookupVar("PostFxTextureV1");
|
|
|
|
PostFxTexture2Id = PostFXShader->LookupVar("PostFxTexture2");
|
|
PostFxTexture3Id = PostFXShader->LookupVar("PostFxTexture3");
|
|
|
|
#if __XENON || __D3D11 || RSG_ORBIS
|
|
StencilCopyTextureId = PostFXShader->LookupVar("StencilCopyTexture");
|
|
TiledDepthTextureId = PostFXShader->LookupVar("PostFxTextureV0");
|
|
#endif // __XENON || __D3D11 || RSG_ORBIS
|
|
|
|
#if !__PS3
|
|
BloomTexelSizeId = PostFXShader->LookupVar("BloomTexelSize");
|
|
#endif
|
|
|
|
// Motion Blur
|
|
PostFxMotionBlurTextureID = PostFXShader->LookupVar("PostFxMotionBlurTexture");
|
|
|
|
// HDR
|
|
BloomTextureID = PostFXShader->LookupVar("BloomTexture");
|
|
BloomTextureGID = PostFXShader->LookupVar("BloomTextureG");
|
|
|
|
// Motion Blur
|
|
JitterTextureId = PostFXShader->LookupVar("JitterTexture");
|
|
MBPerspectiveShearParams0Id = PostFXShader->LookupVar("MBPerspectiveShearParams0");
|
|
MBPerspectiveShearParams1Id = PostFXShader->LookupVar("MBPerspectiveShearParams1");
|
|
MBPerspectiveShearParams2Id = PostFXShader->LookupVar("MBPerspectiveShearParams2");
|
|
|
|
// Heat Haze
|
|
HeatHazeTextureId = PostFXShader->LookupVar("HeatHazeTexture");
|
|
PostFxHHTextureID = PostFXShader->LookupVar("PostFxHHTexture");
|
|
HeatHazeMaskTextureID = PostFXShader->LookupVar("BackBuffer");
|
|
|
|
// Screen Blur Fade
|
|
ScreenBlurFadeID = PostFXShader->LookupVar("ScreenBlurFade");
|
|
|
|
// Lens Distortion
|
|
DistortionParamsID = PostFXShader->LookupVar("DistortionParams");
|
|
|
|
// Lens Artefacts
|
|
LensArtefactParams0ID = PostFXShader->LookupVar("LensArtefactsParams0");
|
|
LensArtefactParams1ID = PostFXShader->LookupVar("LensArtefactsParams1");
|
|
LensArtefactParams2ID = PostFXShader->LookupVar("LensArtefactsParams2");
|
|
LensArtefactTextureID = PostFXShader->LookupVar("LensArtefactsTex");
|
|
|
|
// Light Streaks
|
|
LightStreaksColorShift0ID = PostFXShader->LookupVar("LightStreaksColorShift0");
|
|
LightStreaksBlurColWeightsID = PostFXShader->LookupVar("LightStreaksBlurColWeights");
|
|
LightStreaksBlurDirID = PostFXShader->LookupVar("LightStreaksBlurDir");
|
|
|
|
// Blur Vignette
|
|
BlurVignettingParamsID = PostFXShader->LookupVar("BlurVignettingParams");
|
|
|
|
ASSET.PopFolder();
|
|
|
|
#if POSTFX_UNIT_QUAD
|
|
quad::Position = PostFXShader->LookupVar("QuadPosition");
|
|
quad::TexCoords = PostFXShader->LookupVar("QuadTexCoords");
|
|
quad::Scale = PostFXShader->LookupVar("QuadScale");
|
|
#if USE_IMAGE_WATERMARKS
|
|
quad::Alpha = PostFXShader->LookupVar("QuadAlpha");
|
|
#endif
|
|
#endif
|
|
|
|
// SetShaderData expects the same order and number of passes as the LensArtefactShaderPass enumeration
|
|
u32 lensArtefactShaderPasses[] = { pp_lens_artefacts, pp_BloomComposite, pp_light_streaks_blur_low, pp_light_streaks_blur_med, pp_light_streaks_blur_high, pp_lens_artefacts_combined };
|
|
LENSARTEFACTSMGR.SetShaderData(PostFXShader, &lensArtefactShaderPasses[0]);
|
|
|
|
#if FXAA_CUSTOM_TUNING
|
|
fxaaBlurinessId = PostFXShader->LookupVar("Bluriness");
|
|
fxaaConsoleEdgeSharpnessId = PostFXShader->LookupVar("ConsoleEdgeSharpness");
|
|
fxaaConsoleEdgeThresholdId = PostFXShader->LookupVar("ConsoleEdgeThreshold");
|
|
fxaaConsoleEdgeThresholdMinId = PostFXShader->LookupVar("ConsoleEdgeThresholdMin");
|
|
fxaaQualitySubpixId = PostFXShader->LookupVar("QualitySubpix");
|
|
fxaaEdgeThresholdId = PostFXShader->LookupVar("EdgeThreshold");
|
|
fxaaEdgeThresholdMinId = PostFXShader->LookupVar("EdgeThresholdMin");
|
|
|
|
fxaaBluriness = PS3_SWITCH(0.33f, 0.5f);
|
|
fxaaConsoleEdgeSharpness = 8.0f;
|
|
fxaaConsoleEdgeThreshold = 0.125f;
|
|
fxaaConsoleEdgeThresholdMin = 0.05f;
|
|
fxaaQualitySubpix = 0.317f; // 0.75f;
|
|
fxaaEdgeThreshold = 0.333f; // 0.166f;
|
|
fxaaEdgeThresholdMin = 0.0833f;
|
|
#endif
|
|
|
|
fpvMotionBlurWeightsId = PostFXShader->LookupVar("fpvMotionBlurWeights");
|
|
fpvMotionBlurVelocityId = PostFXShader->LookupVar("fpvMotionBlurVelocity");
|
|
fpvMotionBlurSizeId = PostFXShader->LookupVar("fpvMotionBlurSize");
|
|
fpvMotionBlurVelocity = Vec2V(V_ZERO);
|
|
fpvMotionBlurPrevCameraPos[0] = Vec3V(V_ZERO);
|
|
fpvMotionBlurPrevCameraPos[1] = Vec3V(V_ZERO);
|
|
fpvMotionBlurCurrCameraPos = Vec3V(V_ZERO);
|
|
fpvMotionBlurPrevModelViewMtx = Mat44V(V_IDENTITY);
|
|
|
|
fpvMotionBlurWeights = Vector4(1.0f, 32.0f, 1.0f, 1.0f);
|
|
fpvMotionBlurSize = 1.0f;
|
|
fpvMotionVelocityMaxSize = 32.0f;
|
|
fpvMotionBlurVelocity = Vec2V(0.0f, 0.0f);
|
|
|
|
fpvMotionBlurFirstFrame = true;
|
|
|
|
#if DEVICE_MSAA
|
|
g_UseSubSampledAlpha = CSettingsManager::GetInstance().GetSettings().m_graphics.m_Shader_SSA && (GRCDEVICE.GetMSAA() == grcDevice::MSAA_None);
|
|
#endif
|
|
}
|
|
|
|
void PostFX::SetGaussianBlur()
|
|
{
|
|
#if DOF_COMPUTE_GAUSSIAN || DOF_DIFFUSION
|
|
bool bGaussian = (GRCDEVICE.GetDxFeatureLevel() >=1100) ? true : false;
|
|
#if RSG_PC
|
|
bGaussian &= (((GET_POSTFX_SETTING(CSettingsManager::GetInstance().GetSettings().m_graphics.m_PostFX)) >= CSettings::High) && (GRCDEVICE.IsStereoEnabled() == false)) ? true : false;
|
|
#endif // RSG_PC
|
|
|
|
//default to computeGaussian
|
|
if(bGaussian)
|
|
CurrentDOFTechnique = dof_computeGaussian;
|
|
else
|
|
CurrentDOFTechnique = dof_console;
|
|
|
|
if (bGaussian)
|
|
{
|
|
#if !DOF_TYPE_CHANGEABLE_IN_RAG
|
|
#if DOF_COMPUTE_GAUSSIAN
|
|
CurrentDOFTechnique = dof_computeGaussian;
|
|
#endif
|
|
#if DOF_DIFFUSION
|
|
CurrentDOFTechnique = dof_diffusion;
|
|
#endif
|
|
#endif //!DOF_TYPE_CHANGEABLE_IN_RAG
|
|
}
|
|
#if ADAPTIVE_DOF && DOF_COMPUTE_GAUSSIAN
|
|
if( bGaussian && AdaptiveDepthOfField.IsEnabled())
|
|
CurrentDOFTechnique = dof_computeGaussian;
|
|
#endif //ADAPTIVE_DOF && DOF_COMPUTE_GAUSSIAN
|
|
#endif //DOF_COMPUTE_GAUSSIAN || DOF_DIFFUSION
|
|
}
|
|
|
|
#if RSG_PC
|
|
void PostFX::SetRequireResetDOFRenderTargets(bool request)
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_UPDATE));
|
|
g_RequestResetDOFRenderTargets = request;
|
|
}
|
|
|
|
bool PostFX::GetRequireResetDOFRenderTargets()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_UPDATE));
|
|
return g_RequestResetDOFRenderTargets;
|
|
}
|
|
|
|
void PostFX::ResetDOFRenderTargets()
|
|
{
|
|
u32 width = VideoResManager::GetSceneWidth();
|
|
u32 height = VideoResManager::GetSceneHeight();
|
|
|
|
grcTextureFactory::CreateParams params;
|
|
params.Multisample = 0;
|
|
params.HasParent = true;
|
|
params.Parent = NULL;
|
|
params.UseFloat = true;
|
|
params.InTiledMemory = true;
|
|
params.IsSwizzled = false;
|
|
params.UseFloat = true;
|
|
params.EnableCompression = false;
|
|
|
|
#if RSG_PC
|
|
params.StereoRTMode = grcDevice::STEREO;
|
|
#endif
|
|
|
|
int bpp;
|
|
GetPostFXDefaultRenderTargetFormat(params.Format, bpp);
|
|
|
|
RecreateDOFRenderTargets(params, bpp, width, height);
|
|
}
|
|
#endif
|
|
|
|
void PostFX::Init(unsigned initMode)
|
|
{
|
|
if(initMode == INIT_CORE)
|
|
{
|
|
AnimPostFXManager::ClassInit();
|
|
OverlayTextRenderer::InitializeTextBlendState();
|
|
PhonePhotoEditor::ClassInit();
|
|
LensArtefacts::ClassInit();
|
|
#if USE_SCREEN_WATERMARK
|
|
ms_watermarkParams.Init();
|
|
#endif
|
|
DefaultFlashEffectModName = atHashString("PlayerSwitchNeutralFlash",0x63EC45A2);
|
|
g_defaultFlashEffect.Set(DefaultFlashEffectModName, POSTFX_IN_HOLD_OUT, 0U, 0U, 0U, 0U);
|
|
|
|
#if __BANK
|
|
g_ForceUseSimple = PARAM_simplepfx.Get(); // set this before rag widget, so it will inherit this value as the default
|
|
g_pedKillOverlay.m_disable = false;
|
|
#endif // __BANK
|
|
InitRenderStateBlocks();
|
|
|
|
Displayf("sizeof(paramBlock) = %" SIZETFMT "d",sizeof(PostFXParamBlock::paramBlock));
|
|
|
|
#if __XENON
|
|
grcGPRAllocation::Init();
|
|
#endif
|
|
|
|
RAGE_TRACK(grPostFx);
|
|
|
|
InitMSAAShaders();
|
|
|
|
ASSET.PushFolder("common:/shaders");
|
|
|
|
#if ADAPTIVE_DOF
|
|
AdaptiveDepthOfField.Init();
|
|
#endif
|
|
|
|
SetGaussianBlur();
|
|
|
|
#if RSG_PC
|
|
u32 shaderModelMajor, shaderModelMinor;
|
|
|
|
GRCDEVICE.GetDxShaderModel(shaderModelMajor, shaderModelMinor);
|
|
if(shaderModelMajor == 5)
|
|
{
|
|
FXAAPassToUse = pp_AA_sm50;
|
|
}
|
|
#endif
|
|
|
|
#if DOF_COMPUTE_GAUSSIAN || DOF_DIFFUSION
|
|
dofComputeShader = grmShaderFactory::GetInstance().Create();
|
|
dofComputeShader->Load(
|
|
"dofCompute");
|
|
dofComputeTechnique = dofComputeShader->LookupTechnique("DOF_Compute");
|
|
#endif //DOF_COMPUTE_GAUSSIAN
|
|
#if DOF_DIFFUSION
|
|
dofDiffusionShader = grmShaderFactory::GetInstance().Create();
|
|
dofDiffusionShader->Load(
|
|
"dofDiffusion");
|
|
dofDiffusiontechnique = dofDiffusionShader->LookupTechnique("DOF_Diffusion", RSG_PC ? false : true);
|
|
#endif
|
|
|
|
#if AVG_LUMINANCE_COMPUTE
|
|
AverageLumunianceComputeEnable = (GRCDEVICE.GetDxFeatureLevel() >= 1100);
|
|
|
|
avgLuminanceShader = grmShaderFactory::GetInstance().Create();
|
|
avgLuminanceShader->Load(
|
|
"avgLuminanceCompute");
|
|
avgLuminanceTechnique = avgLuminanceShader->LookupTechnique("AvgLuminanceTechnique", AverageLumunianceComputeEnable);
|
|
#endif
|
|
|
|
#if BOKEH_SUPPORT || WATERMARKED_BUILD
|
|
|
|
g_BokehTxdSlot = vfxUtil::InitTxd("graphics");
|
|
|
|
#if WATERMARKED_BUILD
|
|
g_TxdSlot = vfxUtil::InitTxd("graphics_pc");
|
|
grcTexture *pTexture = g_TxdStore.Get(g_TxdSlot)->Lookup("bokeh_pent");
|
|
if(pTexture)
|
|
pTexture->AddRef();
|
|
|
|
pTexture = g_TxdStore.Get(g_TxdSlot)->Lookup("bokeh_deca");
|
|
if(pTexture)
|
|
pTexture->AddRef();
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#if BOKEH_SUPPORT
|
|
#if RSG_PC
|
|
if ((GRCDEVICE.GetDxFeatureLevel() >= 1100) NOTFINAL_ONLY(&& !PARAM_disableBokeh.Get()))
|
|
#else
|
|
if( BokehEnable )
|
|
#endif
|
|
{
|
|
m_BokehShapeTextureSheet = g_TxdStore.Get(g_BokehTxdSlot)->Lookup("BOKEH_8sided_iris_4x4sheet");
|
|
Assert(m_BokehShapeTextureSheet);
|
|
if(m_BokehShapeTextureSheet)
|
|
m_BokehShapeTextureSheet->AddRef();
|
|
}
|
|
#endif
|
|
|
|
#if DOF_COMPUTE_GAUSSIAN || DOF_DIFFUSION
|
|
DofKernelSize = dofComputeShader->LookupVar("kernelRadius");
|
|
GaussianWeightsBufferVar = dofComputeShader->LookupVar("GaussianWeights");
|
|
DofProjCompute = dofComputeShader->LookupVar("dofProjCompute");
|
|
DofSkyWeightModifierVar = dofComputeShader->LookupVar("dofSkyWeightModifier");
|
|
DofLumFilterParams = dofComputeShader->LookupVar("LumFilterParams");
|
|
DofRenderTargetSizeVar = dofComputeShader->LookupVar("dofRenderTargetSize");
|
|
fourPlaneDofVar = dofComputeShader->LookupVar("fourPlaneDof");
|
|
#if COC_SPREAD
|
|
DofCocSpreadKernelRadius = dofComputeShader->LookupVar("cocSpreadKernelRadius");
|
|
#endif
|
|
#if ADAPTIVE_DOF_OUTPUT_UAV
|
|
DofComputeAdaptiveDOFParamsBufferVar = dofComputeShader->LookupVar("AdaptiveDOFParamsBuffer");
|
|
#endif //ADAPTIVE_DOF_OUTPUT_UAV
|
|
#if __BANK
|
|
g_cocOverlayAlpha = dofComputeShader->LookupVar("cocOverlayAlpha");
|
|
#endif
|
|
#endif //DOF_COMPUTE_GAUSSIAN
|
|
#if DOF_DIFFUSION
|
|
dofDiffusion_lastbufferSizeVar = dofDiffusionShader->LookupVar("LastBufferSize");
|
|
dofDiffusion_DiffusionRadiusVar = dofDiffusionShader->LookupVar("DiffusionRadius");
|
|
dofDiffusion_txABC_ID = dofDiffusionShader->LookupVar("txABC_Texture");
|
|
dofDiffusion_txCOC_ID = dofDiffusionShader->LookupVar("txCOC_Texture");
|
|
dofDiffusion_txX_ID = dofDiffusionShader->LookupVar("txX_Texture");
|
|
dofDiffusion_txY_ID = dofDiffusionShader->LookupVar("txYn_Texture");
|
|
#endif //DOF_DIFFUSION
|
|
|
|
#if DOF_COMPUTE_GAUSSIAN || DOF_DIFFUSION
|
|
dofComputeColorTex = dofComputeShader->LookupVar("ColorTexture");
|
|
dofComputeDepthBlurTex = dofComputeShader->LookupVar("DepthBlurTexture");
|
|
dofComputeOutputTex = dofComputeShader->LookupVar("DOFOutputTexture");
|
|
dofComputeDepthBlurHalfResTex = dofComputeShader->LookupVar("DepthBlurHalfResTexture");
|
|
dofBlendParams = dofComputeShader->LookupVar("DOFBlendParams");
|
|
#if COC_SPREAD
|
|
cocComputeOutputTex = dofComputeShader->LookupVar("COCOutputTexture");
|
|
#endif
|
|
#endif //DOF_COMPUTE_GAUSSIAN
|
|
|
|
#if AVG_LUMINANCE_COMPUTE
|
|
if (AverageLumunianceComputeEnable)
|
|
{
|
|
LumCSDownsampleTexSizeId = avgLuminanceShader->LookupVar("DstTextureSize");
|
|
|
|
LumCSDownsampleSrcId = avgLuminanceShader->LookupVar("AvgLuminanceTexture");
|
|
LumCSDownsampleInitSrcId = avgLuminanceShader->LookupVar("HDRColorTexture");
|
|
LumCSDownsampleDstId = avgLuminanceShader->LookupVar("AverageLuminanceOut");
|
|
}
|
|
#endif
|
|
|
|
ASSET.PopFolder();
|
|
|
|
// Load heat haze textures
|
|
HeatHazeTexture = CShaderLib::LookupTexture("heat_haze");
|
|
Assert(HeatHazeTexture);
|
|
if (HeatHazeTexture)
|
|
{
|
|
HeatHazeTexture->AddRef();
|
|
}
|
|
|
|
#if __PS3
|
|
// Main RT mempool for
|
|
grcRTPoolCreateParams params;
|
|
params.m_Size = 16 * 16 * 16;
|
|
params.m_HeapCount = 1;
|
|
#if __GCM
|
|
params.m_Type = grcrtPermanent;
|
|
params.m_BitDepth = 128;
|
|
params.m_Alignment = gcm::GetSurfaceAlignment(false, false);
|
|
params.m_PhysicalMem = false;
|
|
params.m_Zculled = false;
|
|
params.m_Pitch = gcm::GetSurfaceTiledPitch(1, 128, false);
|
|
params.m_Tiled = false;
|
|
params.m_Swizzled = false;
|
|
params.m_Compression = 0;
|
|
#endif
|
|
g_RTPoolIdPostFX = grcRenderTargetPoolMgr::CreatePool("PostFX Main Pool", params);
|
|
#endif
|
|
CreateRenderTargets(VideoResManager::GetSceneWidth(), VideoResManager::GetSceneHeight());
|
|
|
|
// SetShaderData expects the same order and number of passes as the LensArtefactShaderPass enumeration
|
|
u32 lensArtefactShaderPasses[] = { pp_lens_artefacts, pp_BloomComposite, pp_light_streaks_blur_low, pp_light_streaks_blur_med, pp_light_streaks_blur_high, pp_lens_artefacts_combined };
|
|
LENSARTEFACTSMGR.SetShaderData(PostFXShader, &lensArtefactShaderPasses[0]);
|
|
|
|
LENSARTEFACTSMGR.SetRenderCallback(MakeFunctor(PostFX::SimpleBlitWrapper));
|
|
|
|
#if __BANK
|
|
g_delayFlipWait = !PARAM_dontDelayFlipSwitch.Get();
|
|
#endif
|
|
|
|
g_bulletImpactOverlay.Init();
|
|
|
|
|
|
grcVertexElement elements[] =
|
|
{
|
|
grcVertexElement(0, grcVertexElement::grcvetPosition, 0, 8, grcFvf::grcdsFloat2)
|
|
};
|
|
sm_FogVertexDeclaration = GRCDEVICE.CreateVertexDeclaration(elements, sizeof(elements)/sizeof(grcVertexElement));
|
|
|
|
RecreateFogVertexBuffer();
|
|
|
|
#if ADAPTIVE_DOF_GPU && ADAPTIVE_DOF_OUTPUT_UAV
|
|
WIN32PC_ONLY(if(GRCDEVICE.SupportsFeature(COMPUTE_SHADER_50)))
|
|
AdaptiveDepthOfField.InitiliaseOnRenderThread();
|
|
#endif //ADAPTIVE_DOF_OUTPUT_UAV
|
|
#if BOKEH_SUPPORT || DOF_COMPUTE_GAUSSIAN
|
|
WIN32PC_ONLY(if(GRCDEVICE.SupportsFeature(COMPUTE_SHADER_50)))
|
|
InitBokehDOF();
|
|
#endif // BOKEH_SUPPORT || DOF_COMPUTE_GAUSSIAN
|
|
|
|
#if ENABLE_MLAA
|
|
g_MLAA.Initialize(RSG_ORBIS ? CRenderTargets::GetUIBackBuffer() : NULL);
|
|
#endif
|
|
float fGamma;
|
|
if (PARAM_setGamma.Get(fGamma))
|
|
{
|
|
PostFX::SetGammaFrontEnd(fGamma);
|
|
}
|
|
}
|
|
else if(initMode == INIT_SESSION)
|
|
{
|
|
// Reset all to default state
|
|
ResetAdaptedLuminance();
|
|
g_enableLightRays=false;
|
|
g_enableNightVision=false;
|
|
g_enableSeeThrough=false;
|
|
|
|
#if DEVICE_MSAA
|
|
|
|
#if USE_HQ_ANTIALIASING
|
|
|
|
g_AntiAliasingType = AA_FXAA_DEFAULT;
|
|
g_FXAAEnable = CSettingsManager::GetInstance().GetSettings().m_graphics.m_FXAA_Enabled;
|
|
#if USE_NV_TXAA
|
|
g_TXAAEnable = CSettingsManager::GetInstance().GetSettings().m_graphics.m_TXAA_Enabled;
|
|
#endif // USE_NV_TXAA
|
|
|
|
#if !__FINAL
|
|
u32 fxaaMode = 1;
|
|
if (PARAM_fxaaMode.Get(fxaaMode))
|
|
{
|
|
if (fxaaMode == 0)
|
|
{
|
|
g_AntiAliasingType = AA_FXAA_DEFAULT;
|
|
g_FXAAEnable = false;
|
|
}
|
|
else if (fxaaMode == 1)
|
|
{
|
|
g_AntiAliasingType = AA_FXAA_DEFAULT;
|
|
g_FXAAEnable = true;
|
|
}
|
|
else if (fxaaMode == 2)
|
|
{
|
|
g_AntiAliasingType = AA_FXAA_HQ;
|
|
g_FXAAEnable = true;
|
|
}
|
|
}
|
|
#endif
|
|
#endif // USE_HQ_ANTIALIASING
|
|
|
|
#endif
|
|
|
|
#if FILM_EFFECT
|
|
g_EnableFilmEffect = false;
|
|
g_BaseDistortionCoefficient = -0.028f;
|
|
g_BaseCubeDistortionCoefficient = 1.2f;
|
|
g_ChromaticAberrationOffset = 0.038f;
|
|
g_ChromaticAberrationCubeOffset = 0.720f;
|
|
g_FilmNoise = 0.05f;
|
|
g_FilmVignettingIntensity = 1.0f;
|
|
g_FilmVignettingRadius = 1.5f;
|
|
g_FilmVignettingContrast = 2.0f;
|
|
#endif
|
|
|
|
#if __BANK
|
|
g_Override = false;
|
|
#endif
|
|
|
|
g_noiseOverride = false;
|
|
g_noisinessOverride = 0.0f;
|
|
|
|
if (g_pNoiseTexture == NULL)
|
|
{
|
|
// make sure Lights has been initialised
|
|
g_pNoiseTexture = CShaderLib::LookupTexture("waternoise");
|
|
g_pNoiseTexture->AddRef();
|
|
}
|
|
|
|
if (g_pDamageOverlayTexture == NULL)
|
|
{
|
|
g_pDamageOverlayTexture = CShaderLib::LookupTexture("dmg_overlay_fade");
|
|
if (g_pDamageOverlayTexture)
|
|
g_pDamageOverlayTexture->AddRef();
|
|
}
|
|
|
|
#if USE_HQ_ANTIALIASING
|
|
g_HQAATiledTechnique = CSprite2d::GetShader()->LookupTechnique("HighQualityAA_Tiled");
|
|
g_HQAA_srcMapID = CSprite2d::GetShader()->LookupVar("TransparentSrcMap");
|
|
#endif
|
|
|
|
g_screenBlurFade.Init();
|
|
ANIMPOSTFXMGR.Reset();
|
|
PAUSEMENUPOSTFXMGR.Reset();
|
|
|
|
#if RSG_PC
|
|
if(GRCDEVICE.UsingMultipleGPUs())
|
|
ResetDOFRenderTargets();
|
|
#endif
|
|
}
|
|
|
|
CHighQualityScreenshot::Init(initMode);
|
|
|
|
#if FXAA_CUSTOM_TUNING
|
|
fxaaBlurinessId = PostFXShader->LookupVar("Bluriness");
|
|
fxaaConsoleEdgeSharpnessId = PostFXShader->LookupVar("ConsoleEdgeSharpness");
|
|
fxaaConsoleEdgeThresholdId = PostFXShader->LookupVar("ConsoleEdgeThreshold");
|
|
fxaaConsoleEdgeThresholdMinId = PostFXShader->LookupVar("ConsoleEdgeThresholdMin");
|
|
fxaaQualitySubpixId = PostFXShader->LookupVar("QualitySubpix");
|
|
fxaaEdgeThresholdId = PostFXShader->LookupVar("EdgeThreshold");
|
|
fxaaEdgeThresholdMinId = PostFXShader->LookupVar("EdgeThresholdMin");
|
|
|
|
fxaaBluriness = PS3_SWITCH(0.33f, 0.5f);
|
|
fxaaConsoleEdgeSharpness = 8.0f;
|
|
fxaaConsoleEdgeThreshold = 0.125f;
|
|
fxaaConsoleEdgeThresholdMin = 0.05f;
|
|
fxaaQualitySubpix = 0.317f; // 0.75f;
|
|
fxaaEdgeThreshold = 0.333f; // 0.166f;
|
|
fxaaEdgeThresholdMin = 0.0833f;
|
|
#endif
|
|
|
|
#if USE_NV_TXAA
|
|
#if !__FINAL
|
|
PARAM_txaaDevMode.Get(g_TXAADevMode); // But this one works.
|
|
#endif // !__FINAL
|
|
#endif
|
|
|
|
g_UseSubSampledAlpha = (CSettingsManager::GetInstance().GetSettings().m_graphics.m_Shader_SSA && (GRCDEVICE.GetMSAA() == grcDevice::MSAA_None)) || RSG_DURANGO || RSG_ORBIS;
|
|
}
|
|
|
|
void PostFX::Shutdown(unsigned shutdownMode)
|
|
{
|
|
if(shutdownMode == SHUTDOWN_CORE)
|
|
{
|
|
|
|
AnimPostFXManager::ClassShutdown();
|
|
PhonePhotoEditor::ClassShutdown();
|
|
LensArtefacts::ClassShutdown();
|
|
|
|
#if __WIN32PC || RSG_DURANGO || RSG_ORBIS
|
|
DeleteScreenBasedRenderTargets();
|
|
#endif
|
|
|
|
#if __XENON
|
|
grcGPRAllocation::Terminate();
|
|
#endif // __XENON
|
|
|
|
delete PostFXShader;
|
|
|
|
#if MSAA_EDGE_PASS
|
|
if (PostFXShaderMS0)
|
|
{
|
|
delete PostFXShaderMS0;
|
|
PostFXShaderMS0 = NULL;
|
|
}
|
|
#endif // MSAA_EDGE_PASS
|
|
|
|
if(HeatHazeTexture)
|
|
{
|
|
HeatHazeTexture->Release();
|
|
HeatHazeTexture = 0;
|
|
}
|
|
|
|
if (g_pNoiseTexture)
|
|
{
|
|
g_pNoiseTexture->Release();
|
|
g_pNoiseTexture=NULL;
|
|
}
|
|
|
|
if (g_pDamageOverlayTexture)
|
|
{
|
|
g_pDamageOverlayTexture->Release();
|
|
g_pDamageOverlayTexture = NULL;
|
|
}
|
|
|
|
#if DOF_COMPUTE_GAUSSIAN || DOF_DIFFUSION
|
|
delete dofComputeShader;
|
|
dofComputeShader = NULL;
|
|
#endif
|
|
#if DOF_DIFFUSION
|
|
delete dofDiffusionShader;
|
|
dofDiffusionShader = NULL;
|
|
#endif
|
|
|
|
#if ADAPTIVE_DOF
|
|
AdaptiveDepthOfField.DeleteRenderTargets();
|
|
#endif
|
|
|
|
#if AVG_LUMINANCE_COMPUTE
|
|
delete avgLuminanceShader;
|
|
avgLuminanceShader = NULL;
|
|
#endif
|
|
|
|
#if ENABLE_MLAA
|
|
g_MLAA.Shutdown(!RSG_ORBIS);
|
|
#endif
|
|
|
|
vfxUtil::ShutdownTxd("graphics_pc");
|
|
}
|
|
else if (shutdownMode == SHUTDOWN_SESSION)
|
|
{
|
|
CHighQualityScreenshot::Shutdown(shutdownMode);
|
|
// CLowQualityScreenshot::Shutdown(shutdownMode);
|
|
}
|
|
}
|
|
|
|
#if ADAPTIVE_DOF_CPU
|
|
bool UseAdaptiveDofCPU()
|
|
{
|
|
return (CPhoneMgr::CamGetState() && CPhoneMgr::GetDOFState() == true);
|
|
}
|
|
#endif
|
|
|
|
#if DOF_TYPE_CHANGEABLE_IN_RAG
|
|
void ProcessDOFTechniqueChange()
|
|
{
|
|
ProcessDOFChangeOnRenderThread = true;
|
|
}
|
|
|
|
void ProcessDOFChangeRenderThread()
|
|
{
|
|
u32 width = VideoResManager::GetSceneWidth();
|
|
u32 height = VideoResManager::GetSceneHeight();
|
|
|
|
grcTextureFactory::CreateParams params;
|
|
params.Multisample = 0;
|
|
params.HasParent = true;
|
|
params.Parent = NULL;
|
|
params.UseFloat = true;
|
|
params.InTiledMemory = true;
|
|
params.IsSwizzled = false;
|
|
params.UseFloat = true;
|
|
params.EnableCompression = false;
|
|
|
|
#if RSG_PC
|
|
params.StereoRTMode = grcDevice::STEREO;
|
|
#endif
|
|
|
|
int bpp;
|
|
GetPostFXDefaultRenderTargetFormat(params.Format, bpp);
|
|
|
|
RecreateDOFRenderTargets(params, bpp, width, height);
|
|
#if BOKEH_SUPPORT
|
|
RecreateBokehRenderTargets(params, bpp, width, height);
|
|
#endif
|
|
|
|
switch (CurrentDOFTechnique)
|
|
{
|
|
case dof_console:
|
|
break;
|
|
#if DOF_COMPUTE_GAUSSIAN
|
|
case dof_computeGaussian:
|
|
break;
|
|
#endif
|
|
#if DOF_DIFFUSION
|
|
case dof_diffusion:
|
|
RecreateDOFDiffusionRenderTargets(params, bpp, width, height);
|
|
break;
|
|
#endif
|
|
default:
|
|
break;
|
|
}
|
|
|
|
ProcessDOFChangeOnRenderThread = false;
|
|
}
|
|
#endif
|
|
|
|
#if __BANK
|
|
|
|
static bkButton *ms_addPostFxWidgets = NULL;
|
|
static bkGroup *ms_postFxGroup = NULL;
|
|
|
|
static bool gFrameCapture = false;
|
|
static bool gFrameCaptureSingle = false;
|
|
static char gFrameCapPath[255] = "X:\\framecap\\frame";
|
|
static bool gFrameUseCutsceneNameForPath = false;
|
|
static bool gFrameCapJpeg = true;
|
|
static bool gFrameCaptureOnCutsceneStart = false;
|
|
static float gFrameCaptureFPS = 30.0f;
|
|
static bool gFrameCaptureMBSync = true;
|
|
static bool gFrameCaptureBinkMode = false;
|
|
static bool gFrameCaptureCutsceneMode = false;
|
|
|
|
static bool gTriggerScreenBlurFadeIn = false;
|
|
static bool gTriggerScreenBlurFadeOut = false;
|
|
static bool gDisableScreenBlurFadeOut = false;
|
|
|
|
void PostFX::AddWidgetsOnDemand()
|
|
{
|
|
bkBank &bk = *BANKMGR.FindBank("Renderer");
|
|
|
|
// remove old button:
|
|
if(ms_addPostFxWidgets)
|
|
{
|
|
bk.Remove(*((bkWidget*)ms_addPostFxWidgets));
|
|
ms_addPostFxWidgets = NULL;
|
|
}
|
|
|
|
bk.SetCurrentGroup(*ms_postFxGroup);
|
|
|
|
bk.AddToggle("Delay flip wait",&g_delayFlipWait);
|
|
bk.AddToggle("Override Timecycle", &g_Override);
|
|
#if __PS3
|
|
bk.AddToggle("Use Default Composite Tiled Technique", &g_PS3UseCompositeTiledTechniques);
|
|
#endif
|
|
bk.AddToggle("Use Tile Classification Data", &g_UseTiledTechniques);
|
|
|
|
bk.AddToggle("Enable light rays above water", &g_lightRaysAboveWaterLine);
|
|
|
|
bk.AddSeparator();
|
|
bk.AddToggle("Skip auto exposure", &g_AutoExposureSkip);
|
|
bk.AddSlider("Exposure", &g_overwrittenExposure, -16.0f, 16.0f, 0.01f);
|
|
bk.AddSlider("Current Gamma", &PostFX::g_gammaFrontEnd, 0.0001f, 100.0f, 0.0001f);
|
|
bk.AddToggle("No tone-mapping", &g_JustExposure);
|
|
bk.AddToggle("Force Simple Post Fx", &g_ForceUseSimple);
|
|
bk.AddSlider("Color compression", g_adaptation.GetUpdatePackScalarPtr(),0.0f,256.0f,0.5f);
|
|
bk.AddToggle("Enable auto colour compression", &g_useAutoColourCompression);
|
|
bk.AddSeparator();
|
|
|
|
#if __XENON
|
|
bk.AddToggle("Use Packed 7e3Int Back Buffer", &g_UsePacked7e3IntBackBuffer);
|
|
#endif
|
|
|
|
bk.PushGroup("Continuous Frame Capture", false);
|
|
bk.AddToggle("Continuous Frame Capture", &gFrameCapture);
|
|
bk.AddToggle("Wait for cutscene start", &gFrameCaptureOnCutsceneStart);
|
|
bk.AddToggle("MotionBuilder frame sync", &gFrameCaptureMBSync);
|
|
bk.AddToggle("Single Frame Capture", &gFrameCaptureSingle);
|
|
bk.AddText("Filepath prefix", &gFrameCapPath[0], 255);
|
|
bk.AddToggle("Use cutscene name for path", &gFrameUseCutsceneNameForPath);
|
|
bk.AddToggle("Use JPEG instead of PNG", &gFrameCapJpeg);
|
|
bk.AddSlider("FPS", &gFrameCaptureFPS, 5.0f, 120.0f, 1.0f);
|
|
bk.AddToggle("Bink Mode", &gFrameCaptureBinkMode);
|
|
bk.AddToggle("Cutscene Mode", &gFrameCaptureCutsceneMode);
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("First Person Motion Blur");
|
|
bk.AddToggle("Enabled", &g_fpvMotionBlurEnable);
|
|
bk.AddSlider("Fade Strength", &fpvMotionBlurWeights.x, 0.0f, 1.0f, 0.01f);
|
|
bk.AddSlider("Weight 1", &fpvMotionBlurWeights.y, 0.0f, 1024.0f, 0.01f);
|
|
bk.AddSlider("Velocity Blend", &fpvMotionBlurWeights.z, 0.0f, 1.0f, 0.01f);
|
|
bk.AddSlider("Noisiness", &fpvMotionBlurWeights.w, 0.0f, 1.0f, 0.01f);
|
|
bk.AddVector("Velocity", &fpvMotionBlurVelocity, -1024.0f, 1024.0f, 0.01f);
|
|
bk.AddSlider("Blur Size", &fpvMotionBlurSize, 0.0f, 256.0f, 0.01f);
|
|
bk.AddSlider("Maximum Velocity", &fpvMotionVelocityMaxSize, 0.0f, 256.0f, 0.01f);
|
|
bk.AddToggle("Enable when in vehicle", &g_fpvMotionBlurEnableInVehicle);
|
|
bk.AddToggle("Enable dynamic velocity update", &g_fpvMotionBlurEnableDynamicUpdate);
|
|
bk.AddToggle("Draw velocity/position debug", &g_fpvMotionBlurDrawDebug);
|
|
bk.AddToggle("Override TAG data", &g_fpvMotionBlurOverrideTagData);
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("SSA", false);
|
|
bk.AddToggle("Use Sub Sampled Alpha", &g_UseSubSampledAlpha);
|
|
#if SSA_USES_CONDITIONALRENDER
|
|
bk.AddToggle("Use Conditional Rendering with SSA", &g_UseConditionalSSA);
|
|
#endif
|
|
bk.AddToggle("Use Single Pass SSA",&g_UseSinglePassSSA);
|
|
bk.AddToggle("Use SSA On Foliage", &g_UseSSAOnFoliage);
|
|
bk.PopGroup();
|
|
|
|
const char* pStrAATypes[] =
|
|
{
|
|
"FXAA Default",
|
|
#if USE_HQ_ANTIALIASING
|
|
"FXAA HQ",
|
|
#endif // USE_HQ_ANTIALIASING
|
|
"FXAA UI"
|
|
};
|
|
bk.PushGroup("FXAA", false);
|
|
bk.AddToggle("Enable FXAA Pass", &g_FXAAEnable);
|
|
bk.AddCombo("FXAA Type", (s32*)&g_AntiAliasingType, (s32)(sizeof(pStrAATypes)/sizeof(char*)), pStrAATypes );
|
|
#if USE_HQ_ANTIALIASING
|
|
bk.AddSlider("FXAA Switch Distance ", &g_AntiAliasingSwitchDistance, 0.f, 10000.f, 1.f);
|
|
#endif
|
|
#if FXAA_CUSTOM_TUNING
|
|
bk.PushGroup("FXAA Tuning");
|
|
bk.AddSlider("Bluriness", &fxaaBluriness, 0.33f, 0.5f, 0.01f); // Max=0.5 Min = 0.33 Step=0.01 Default=0.5
|
|
bk.AddSlider("ConsoleEdgeSharpness", &fxaaConsoleEdgeSharpness, 2.0f, 8.0f, 2.0f); // Max=8, Min=2 Step=*2, Default=8
|
|
bk.AddSlider("ConsoleEdgeThreshold", &fxaaConsoleEdgeThreshold, 0.125f, 0.250f, 0.125f); // Max=0.25, Min=0.125 Step=0.125 Default=0.125
|
|
bk.AddSlider("ConsoleEdgeThresholdMin", &fxaaConsoleEdgeThresholdMin, 0.02f, 0.08f, 0.01f); // Max=0.08, Min=0.02 Step=0.01 Default=0.05
|
|
|
|
bk.AddSlider("Quality Sub-pix", &fxaaQualitySubpix, 0.0f, 1.0f, 0.01f); // Max=1.0, Min=0.0 Step=0.01 Default=0.75
|
|
bk.AddSlider("Edge Threshold", &fxaaEdgeThreshold, 0.063f, 1.0f, 0.003f); // Max=0.333, Min=0.063 Step=0.003 Default 0.166
|
|
bk.AddSlider("Edge Threshold Min", &fxaaEdgeThresholdMin, 0.0312f, 0.0833f, 0.001f); // Max=0.0833, Min=0.0312 Step=0.001 Default=0.0833
|
|
bk.PopGroup();
|
|
#endif
|
|
bk.PopGroup();
|
|
|
|
MLAA_ONLY(MLAA::AddWidgets(bk);)
|
|
|
|
#if USE_NV_TXAA
|
|
bk.PushGroup("TXAA", false);
|
|
bk.AddToggle("Enable TXAA", &g_TXAAEnable);
|
|
bk.AddSlider("Mode", &g_TXAADevMode, 0, TXAA_MODE_TOTAL, 1);
|
|
bk.PopGroup();
|
|
#endif
|
|
|
|
bk.PushGroup("Debug", true);
|
|
bk.PushGroup("Vector", true);
|
|
for (int i = 0; i < NUM_DEBUG_PARAMS; i++)
|
|
{
|
|
char name[64];
|
|
sprintf(name, "Vector %d", i);
|
|
bk.AddVector(name, &DebugParams[i], -1024.0f, 1024.0f, 0.01f);
|
|
}
|
|
bk.PopGroup();
|
|
bk.PushGroup("Colour", true);
|
|
for (int i = 0; i < NUM_DEBUG_PARAMS; i++)
|
|
{
|
|
char name[64];
|
|
sprintf(name, "Colour %d", i);
|
|
bk.AddColor(name, &DebugParams[i]);
|
|
}
|
|
bk.PopGroup();
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("Light Rays", false);
|
|
bk.AddToggle("Force Using Underwater Technique", &g_ForceUnderWaterTech);
|
|
bk.AddToggle("Force Using Abovewater Technique", &g_ForceAboveWaterTech);
|
|
bk.AddToggle("Fade if Sun is Off Screen", &g_fadeSSLROffscreen);
|
|
bk.AddSlider("Offscreen Fade Factor", &g_fadeSSLROffscreenValue,0.1f,4.0f,0.01f,NullCB,"Light Ray Fade Factor. 1.0 means fade at edge of the screen. Less than 1.0 fades before the edge.");
|
|
|
|
bk.AddSlider("Light Ray Additive Reducer", &editedSettings.m_sslrParams.x,0.1f,8.0f,0.01f);
|
|
bk.AddSlider("SSLR Blit Size",&editedSettings.m_sslrParams.y,0.1f,20.0f,0.1f);
|
|
bk.AddSlider("SSLR Ray Length",&editedSettings.m_sslrParams.z,0.1f,20.0f,0.1f);
|
|
bk.PopGroup();
|
|
|
|
ANIMPOSTFXMGR.AddWidgets(bk);
|
|
|
|
bk.PushGroup("Fog Ray");
|
|
bk.AddSlider("FogRay Pow", &editedSettings.m_fograyContrast, 1.0f, 10.0f, 0.01f, NullCB, "Global Fogray Pow." );
|
|
bk.AddSlider("FogRay Intensity", &editedSettings.m_fograyIntensity, 0.0f, 1.0f, 0.001f, NullCB, "Global Fogray intensity." );
|
|
bk.AddSlider("FogRay Density", &editedSettings.m_fograyDensity, 0.0f, 20.0f, 0.001f, NullCB, "Global Fogray density." );
|
|
bk.AddSlider("FogRay Jitter Start", &g_fograyJitterStart, 0.0f, 2000.0f, 10.0f, NullCB, "Global Fogray jitter start");
|
|
bk.AddSlider("FogRay Jitter End", &g_fograyJitterEnd, 0.0f, 3000.0f, 10.0f, NullCB, "Global Fogray jitter end");
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("Colour Filters", false);
|
|
if ( bkRemotePacket::IsConnectedToRag() )
|
|
{
|
|
bk.AddColor("Color Correction",reinterpret_cast<Vector3*>(&editedSettings.m_colorCorrect), NullCB, "Global color correction." );
|
|
bk.AddColor("Color Shift",reinterpret_cast<Vector3*>(&editedSettings.m_colorShift), NullCB, "Global color shift." );
|
|
}
|
|
else
|
|
{
|
|
bk.AddSlider("Color Correction Red Channel", &editedSettings.m_colorCorrect.x, 0.0f, 1.0f, 0.01f, NullCB, "Global color correction (Red)." );
|
|
bk.AddSlider("Color Correction Green Channel", &editedSettings.m_colorCorrect.y, 0.0f, 1.0f, 0.01f, NullCB, "Global color correction (Green)." );
|
|
bk.AddSlider("Color Correction Blue Channel", &editedSettings.m_colorCorrect.z, 0.0f, 1.0f, 0.01f, NullCB, "Global color correction (Blue)." );
|
|
|
|
bk.AddSlider("Color Shift Red Channel", &editedSettings.m_colorShift.x, 0.0f, 1.0f, 0.01f, NullCB, "Global color shift (Red)." );
|
|
bk.AddSlider("Color Shift Green Channel", &editedSettings.m_colorShift.y, 0.0f, 1.0f, 0.01f, NullCB, "Global color shift (Green)." );
|
|
bk.AddSlider("Color Shift Blue Channel", &editedSettings.m_colorShift.z, 0.0f, 1.0f, 0.01f, NullCB, "Global color shift (Blue)." );
|
|
}
|
|
bk.AddSlider("Saturation", &editedSettings.m_deSaturate, 0.0f, 1.0f, 0.01f, NullCB, "Color saturation." );
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("Bloom");
|
|
bk.AddToggle("Enable bloom", &g_bloomEnable);
|
|
bk.AddSeparator();
|
|
bk.AddSlider("Bloom Threshold (Width)", &editedSettings.m_bloomThresholdWidth, 0.0f, 10.0f, 0.01f, NullCB);
|
|
bk.AddSlider("Bloom Threshold (Max)", &editedSettings.m_bloomThresholdMax, 0.0f, 3.0f, 0.01f, NullCB);
|
|
bk.AddSlider("Bloom Threshold Power", &g_bloomThresholdPower, -16.0f, 16.0f, 0.01f);
|
|
bk.AddSlider("Bloom Intensity", &editedSettings.m_bloomIntensity, 0.0f, 10.0f, 0.1f, NullCB, "Intensity of blurring." );
|
|
bk.AddSeparator();
|
|
bk.AddSlider("Exposure diff. (Min)", &g_bloomThresholdExposureDiffMin, 0.0f, 64.0f, 0.01f);
|
|
bk.AddSlider("Exposure diff. (Max)", &g_bloomThresholdExposureDiffMax, 0.0f, 64.0f, 0.01f);
|
|
bk.AddSeparator();
|
|
bk.AddSlider("Bloom Large Blur Blend Mult", &g_bloomLargeBlurBlendMult, 0.0f, 5.0f, 0.01f);
|
|
bk.AddSlider("Bloom Medium Blur Blend Mult", &g_bloomMedBlurBlendMult, 0.0f, 5.0f, 0.01f);
|
|
bk.AddSlider("Bloom Small Blur Blend Mult", &g_bloomSmallBlurBlendMult, 0.0f, 5.0f, 0.01f);
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("Tone mapping", false);
|
|
toneMapInfo = bk.AddText("Info", toneMapInfoStr, 128);
|
|
bk.AddText("Current Lum", g_adaptation.GetUpdateLumPtr(), true);
|
|
bk.AddText("Exposure", g_adaptation.GetUpdateExposurePtr(), true);
|
|
bk.AddSlider("Exposure Tweak", &editedSettings.m_exposureTweak, -32.0f, 32.0f, 0.01f, NullCB, "Tweak to exposure from timecycle");
|
|
bk.AddToggle("Exposure Tweak Enabled", &g_enableExposureTweak);
|
|
bk.AddToggle("Force Exposure Readback", &g_forceExposureReadback);
|
|
bk.AddSlider("Exposure Push", &editedSettings.m_exposurePush, -1.0f, 1.0f, 0.01f, NullCB, "Tweak to exposure to pull/push away form 0");
|
|
bk.AddVector("Filmic (A, B, C, D)", &editedSettings.m_filmicParams[0], -16.0f, 16.0f, 0.01f, NullCB, "Filmic parameters" );
|
|
bk.AddVector("Filmic (E, F, W, -)", &editedSettings.m_filmicParams[1], -16.0f, 16.0f, 0.01f, NullCB, "Filmic parameters" );
|
|
bk.AddSlider("Exposure (Scale)", &editedSettings.m_exposureCurveA, -256.0f, 256.0f, 0.001f);
|
|
bk.AddSlider("Exposure (Power)", &editedSettings.m_exposureCurveB, 1e-6f, 256.0f, 0.001f);
|
|
bk.AddSlider("Exposure (Max)", &editedSettings.m_exposureCurveOffset, -256.0f, 256.0f, 0.001f);
|
|
bk.AddSlider("Min exposure", &editedSettings.m_exposureMin, -16.0f, 16.0f, 0.1f);
|
|
bk.AddSlider("Max exposure", &editedSettings.m_exposureMax, -16.0f, 16.0f, 0.1f);
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("Adaption");
|
|
bk.AddTitle("All values in f-stops per second");
|
|
bk.AddSlider("Min step size", &editedSettings.m_adaptionMinStepSize, 0.0f, 150.0f, 0.01f);
|
|
bk.AddSlider("Max step size", &editedSettings.m_adaptionMaxStepSize, 0.0f, 150.0f, 0.01f);
|
|
bk.AddSlider("Step size multiplier", &editedSettings.m_adaptionStepMult, 0.0, 300.0f, 0.01f);
|
|
bk.AddSlider("Threshold", &editedSettings.m_adaptionThreshold, 0.0f, 150.0f, 0.01f);
|
|
bk.AddSlider("Num frames to average", &editedSettings.m_adaptionNumFramesAvg, 1, 32, 1);
|
|
bk.AddToggle("Set exposure to target (no adaption)", &g_setExposureToTarget);
|
|
bk.AddText("Info", adaptionInfoStr, 255, true);
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("Noise", false);
|
|
bk.AddSlider("Noise",&editedSettings.m_noise,0.0f,50.0f,0.01f);
|
|
bk.AddSlider("Noise Size",&editedSettings.m_noiseSize, 0.0f, 1.0f,0.01f);
|
|
|
|
bk.AddSlider("Scanline Intensity", &editedSettings.m_scanlineParams.x, 0.0f, 1.0f, 0.01f);
|
|
bk.AddSlider("Scanline Frequency 1", &editedSettings.m_scanlineParams.y, 0.0f, 4000.0f, 0.01f);
|
|
bk.AddSlider("Scanline Frequency 2", &editedSettings.m_scanlineParams.z, 0.0f, 4000.0f, 0.01f);
|
|
bk.AddSlider("Scanline Speed", &editedSettings.m_scanlineParams.w, 0.0f, 1.0f, 0.01f);
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("Distance Blur (simple DOF)", false);
|
|
bk.AddSlider("Start Distance",&editedSettings.m_dofParameters[0],0.0f,5000.0f,0.5f);
|
|
bk.AddSlider("Blur Strength",&editedSettings.m_dofParameters[2],0.0f,1.0f,0.01f);
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("Environment Blur", false);
|
|
bk.AddSlider("In", &editedSettings.m_EnvironmentalBlurParams[0], -20.0f, g_MaxAdaptiveDofPlaneDistance, 0.01f);
|
|
bk.AddSlider("Out", &editedSettings.m_EnvironmentalBlurParams[1], -20.0f, g_MaxAdaptiveDofPlaneDistance, 0.01f);
|
|
bk.AddSlider("Blur Size", &editedSettings.m_EnvironmentalBlurParams[2], g_MinDofBlurDiskRadius, g_MaxDofBlurDiskRadius+1.0f, 1.0f);
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("Vignetting", false);
|
|
bk.AddSlider("Intensity", &editedSettings.m_vignettingParams[0], 0.0f, 1.0f, 0.01f);
|
|
bk.AddSlider("Radius", &editedSettings.m_vignettingParams[1], 0.0f, 2000.0f, 0.01f);
|
|
bk.AddSlider("Contrast", &editedSettings.m_vignettingParams[2], 0.0f, 1.0f, 0.01f);
|
|
bk.AddColor("Colour", &editedSettings.m_vignettingColour, NullCB, "Vignette Colour", NULL, true);
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("Colour Gradient", false);
|
|
bk.AddColor("Top Colour", reinterpret_cast<Vector3*>(&editedSettings.m_lensGradientColTop), NullCB, "Top Gradient Colour", NULL, true);
|
|
bk.AddColor("Middle Colour", reinterpret_cast<Vector3*>(&editedSettings.m_lensGradientColMiddle), NullCB, "Middle Gradient Colour", NULL, true);
|
|
bk.AddColor("Bottom Colour", reinterpret_cast<Vector3*>(&editedSettings.m_lensGradientColBottom), NullCB, "Bottom Gradient Colour", NULL, true);
|
|
|
|
bk.AddSlider("Top-Middle Gradient Midpoint", &editedSettings.m_lensGradientColTop[3], 0.0f, 1.0f, 0.01f);
|
|
bk.AddSlider("Middle Colour Midpoint", &editedSettings.m_lensGradientColMiddle[3], 0.0f, 1.0f, 0.01f);
|
|
bk.AddSlider("Middle-Bottom Gradient Midpoint", &editedSettings.m_lensGradientColBottom[3], 0.0f, 1.0f, 0.01f);
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("Damage Overlay", false);
|
|
bk.AddToggle("Enable Debug Rendering", &g_bulletImpactOverlay.m_bEnableDebugRender);
|
|
bk.AddToggle("Render After Hud", &g_bulletImpactOverlay.m_drawAfterHud);
|
|
bk.AddToggle("Disable Damage Overlay", &g_bulletImpactOverlay.m_disabled );
|
|
bk.AddToggle("Trigger Bullet Impact", &g_DebugBulletImpactTrigger);
|
|
bk.AddToggle("Use Cursor Position", &g_DebugBulletImpactUseCursorPos);
|
|
bk.AddToggle("Use Endurance Indicator", &g_DebugBulletImpactUseEnduranceIndicator);
|
|
bk.AddVector("Firing Weapon Pos", &g_DebugBulletImpactPos, -4000.0f, 4000.0f, 0.01f);
|
|
bk.AddSlider("Screen Safe Zone Length", &g_bulletImpactOverlay.ms_screenSafeZoneLength, 0.0f, 1.0f, 0.001f);
|
|
bk.AddSeparator();
|
|
|
|
bk.PushGroup("Default Cam Settings");
|
|
bk.AddSlider("Ramp Up Duration", &g_bulletImpactOverlay.ms_settings[0].rampUpDuration, 0, 5000, 1);
|
|
bk.AddSlider("Hold Duration", &g_bulletImpactOverlay.ms_settings[0].holdDuration, 0, 5000, 1);
|
|
bk.AddSlider("Ramp Down Duration", &g_bulletImpactOverlay.ms_settings[0].rampDownDuration, 0, 5000, 1);
|
|
bk.AddSeparator();
|
|
|
|
bk.AddSlider("Sprite Length", &g_bulletImpactOverlay.ms_settings[0].spriteLength, 0.001f, 0.5f, 0.001f);
|
|
bk.AddSlider("Sprite Base Width", &g_bulletImpactOverlay.ms_settings[0].spriteBaseWidth, 0.001f, 0.5f, 0.001f);
|
|
bk.AddSlider("Sprite Tip Width", &g_bulletImpactOverlay.ms_settings[0].spriteTipWidth, 0.001f, 0.5f, 0.001f);
|
|
bk.AddSlider("Angle Scaling Mult", &g_bulletImpactOverlay.ms_settings[0].angleScalingMult, 0.0f, 10.0f, 0.001f);
|
|
bk.AddSeparator();
|
|
|
|
bk.AddColor("Colour Top", reinterpret_cast<Vector3*>(&g_bulletImpactOverlay.ms_settings[0].colourTop), NullCB, "Damage Colour Top", NULL, true);
|
|
bk.AddColor("Colour Bottom", reinterpret_cast<Vector3*>(&g_bulletImpactOverlay.ms_settings[0].colourBottom), NullCB, "Damage Colour Bottom", NULL, true);
|
|
bk.AddColor("Colour Top Endurance", reinterpret_cast<Vector3*>(&g_bulletImpactOverlay.ms_settings[0].colourTopEndurance), NullCB, "Damage Colour Top Endurance", NULL, true);
|
|
bk.AddColor("Colour BottomEndurance ", reinterpret_cast<Vector3*>(&g_bulletImpactOverlay.ms_settings[0].colourBottomEndurance), NullCB, "Damage Colour Bottom Endurance", NULL, true);
|
|
bk.AddSlider("Global Alpha Top", &g_bulletImpactOverlay.ms_settings[0].globalAlphaTop, 0.0f, 1.0f, 0.01f);
|
|
bk.AddSlider("Global Alpha Bottom", &g_bulletImpactOverlay.ms_settings[0].globalAlphaBottom, 0.0f, 1.0f, 0.01f);
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("First Person Cam Settings");
|
|
bk.AddSlider("Ramp Up Duration", &g_bulletImpactOverlay.ms_settings[1].rampUpDuration, 0, 5000, 1);
|
|
bk.AddSlider("Hold Duration", &g_bulletImpactOverlay.ms_settings[1].holdDuration, 0, 5000, 1);
|
|
bk.AddSlider("Ramp Down Duration", &g_bulletImpactOverlay.ms_settings[1].rampDownDuration, 0, 5000, 1);
|
|
bk.AddSeparator();
|
|
|
|
bk.AddSlider("Sprite Length", &g_bulletImpactOverlay.ms_settings[1].spriteLength, 0.001f, 0.5f, 0.001f);
|
|
bk.AddSlider("Sprite Base Width", &g_bulletImpactOverlay.ms_settings[1].spriteBaseWidth, 0.001f, 0.5f, 0.001f);
|
|
bk.AddSlider("Sprite Tip Width", &g_bulletImpactOverlay.ms_settings[1].spriteTipWidth, 0.001f, 0.5f, 0.001f);
|
|
bk.AddSlider("Angle Scaling Mult", &g_bulletImpactOverlay.ms_settings[1].angleScalingMult, 0.0f, 10.0f, 0.001f);
|
|
bk.AddSeparator();
|
|
|
|
bk.AddColor("Colour Top", reinterpret_cast<Vector3*>(&g_bulletImpactOverlay.ms_settings[1].colourTop), NullCB, "Damage Colour Top", NULL, true);
|
|
bk.AddColor("Colour Bottom", reinterpret_cast<Vector3*>(&g_bulletImpactOverlay.ms_settings[1].colourBottom), NullCB, "Damage Colour Bottom", NULL, true);
|
|
bk.AddColor("Colour Top Endurance", reinterpret_cast<Vector3*>(&g_bulletImpactOverlay.ms_settings[1].colourTopEndurance), NullCB, "Damage Colour Top Endurance", NULL, true);
|
|
bk.AddColor("Colour BottomEndurance ", reinterpret_cast<Vector3*>(&g_bulletImpactOverlay.ms_settings[1].colourBottomEndurance), NullCB, "Damage Colour Bottom Endurance", NULL, true);
|
|
bk.AddSlider("Global Alpha Top", &g_bulletImpactOverlay.ms_settings[1].globalAlphaTop, 0.0f, 1.0f, 0.01f);
|
|
bk.AddSlider("Global Alpha Bottom", &g_bulletImpactOverlay.ms_settings[1].globalAlphaBottom, 0.0f, 1.0f, 0.01f);
|
|
bk.PopGroup();
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("Lens Distortion/Chromatic Aberration", false);
|
|
bk.AddSlider("Sniper Scope Override Strength", &g_fSniperScopeOverrideStrength, 0.0f, 1.0f, 0.001f);
|
|
bk.AddSlider("Lens Distortion Coefficient", &editedSettings.m_distortionParams[0], -1.0f, 1.0f, 0.001f);
|
|
bk.AddSlider("Lens Distortion Cube Coefficient", &editedSettings.m_distortionParams[1], -1.0f, 1.0f, 0.001f);
|
|
bk.AddSlider("Colour Aberration Coefficient", &editedSettings.m_distortionParams[2], -1.0f, 1.0f, 0.001f);
|
|
bk.AddSlider("Colour Aberration Cube Coefficient", &editedSettings.m_distortionParams[3], -1.0f, 1.0f, 0.001f);
|
|
bk.AddToggle("Disable On Kill Effect", &g_pedKillOverlay.m_disable);
|
|
bk.AddToggle("Trigger Test Pulse Effect", &g_bDebugTriggerPulseEffect);
|
|
bk.AddVector("Pulse Effect Params", &g_debugPulseEffectParams, -1.0f, 1.0f, 0.001f);
|
|
bk.AddSlider("Pulse Effect Ramp Up Duration", &g_debugPulseEffectRampUpDuration, 0, 10000, 1);
|
|
bk.AddSlider("Pulse Effect Hold Duration", &g_debugPulseEffectHoldDuration, 0, 10000, 1);
|
|
bk.AddSlider("Pulse Effect Ramp Down Duration", &g_debugPulseEffectRampDownDuration, 0, 10000, 1);
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("Blur Vignetting", false);
|
|
bk.AddToggle("Run Tiled", &g_bRunBlurVignettingTiled);
|
|
bk.AddSlider("Intensity", &editedSettings.m_blurVignettingParams[0], 0.0f, 1.0f, 0.01f);
|
|
bk.AddSlider("Radius", &editedSettings.m_blurVignettingParams[1], 0.0f, 2000.0f, 0.01f);
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("Screen Blur Fade", false);
|
|
bk.AddSlider("Time Cycle Driven Fade", &editedSettings.m_screenBlurFade, 0.0f, 1.0f, 0.01f);
|
|
bk.AddSlider("Screen Blur Fade Duration", g_screenBlurFade.GetDurationPtr(), 0.0f, 10000.0f, 0.01f);
|
|
bk.AddToggle("Screen Blur Fade In", &gTriggerScreenBlurFadeIn);
|
|
bk.AddToggle("Screen Blur Fade Out", &gTriggerScreenBlurFadeOut);
|
|
bk.AddToggle("Disable Screen Blur Fade", &gDisableScreenBlurFadeOut);
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("HQ DOF", false);
|
|
#if DOF_TYPE_CHANGEABLE_IN_RAG
|
|
bk.AddCombo ("DOF Type", (int*)&CurrentDOFTechnique, 3, dofTechniqueNames, ProcessDOFTechniqueChange);
|
|
bk.AddSeparator();
|
|
#endif
|
|
bk.AddToggle("Use Hi Dof", &editedSettings.m_HighDof );
|
|
bk.AddToggle("Use Small Blur", &editedSettings.m_HighDofForceSmallBlur);
|
|
bk.AddSlider("Near Start", &editedSettings.m_hiDofParameters[0], 0.0f, 25000.0f, 0.1f);
|
|
bk.AddSlider("Near End", &editedSettings.m_hiDofParameters[1], 0.0f, 25000.0f, 0.1f);
|
|
bk.AddSlider("Far Start", &editedSettings.m_hiDofParameters[2], 0.0f, 25000.0f, 1.0f);
|
|
bk.AddSlider("Far End", &editedSettings.m_hiDofParameters[3], 0.0f, 25000.0f, 1.0f);
|
|
bk.AddToggle("Use Shallow Dof", &editedSettings.m_ShallowDof);
|
|
#if DOF_COMPUTE_GAUSSIAN || DOF_DIFFUSION
|
|
bk.AddSlider("COC Size", &DofKernelSizeVar, 0, DOF_MaxSampleRadius, 1);
|
|
bk.AddSlider("Shallow DOF COC Size", &DofShallowKernelSizeVar, 0, DOF_MaxSampleRadius, 1);
|
|
bk.AddSeparator();
|
|
bk.AddToggle("Draw COC Overlay", &g_DrawCOCOverlay );
|
|
bk.AddSlider("COC Overlay Alpha", &g_cocOverlayAlphaVal, 0.0f, 1.0f, 0.01f);
|
|
bk.AddSeparator();
|
|
bk.AddToggle("Use Pre-Alpha Depth", &DofUsePreAlphaDepth);
|
|
bk.AddSeparator();
|
|
bk.AddSlider("Sky weight modifier", &DofSkyWeightModifier, 0.01f, 1.0f, 0.01f);
|
|
bk.AddSeparator();
|
|
bk.AddToggle("Dof Enable luminance filtering", &DofLumFilteringEnable);
|
|
bk.AddSlider("Dof Luminance contrast threshold", &DofLumContrastThreshold, 0.0f, 100.0f, 1.0f);
|
|
bk.AddSlider("Dof Maximum luminance", &DofMaxLuminance, 0.0f, 100.0f, 0.1f);
|
|
bk.AddSeparator();
|
|
bk.PushGroup("Cutscenes");
|
|
bk.AddSeparator();
|
|
bk.AddToggle("Use Cutscene DOF Override", &editedSettings.m_DOFOverrideEnabled);
|
|
bk.AddSlider("Cutscene DOF Override", &editedSettings.m_DOFOverride, 1.0f, DOF_MaxSampleRadius, 0.01f);
|
|
bk.AddSeparator();
|
|
g_cutsceneDofTODOverride.AddWidgets(bk);
|
|
bk.PopGroup();
|
|
|
|
|
|
//Hard coded this to allow loop unrolling for optimisations.
|
|
//#if COC_SPREAD
|
|
// bk.AddSlider("Near blur COC Size", &DofCocSpreadKernelRadiusVar, 0, DOF_MaxSampleRadiusCOC, 1);
|
|
//#endif
|
|
#endif
|
|
|
|
#if BOKEH_SUPPORT
|
|
if( BokehEnable )
|
|
{
|
|
bk.AddSeparator();
|
|
bk.PushGroup("Bokeh", true);
|
|
bk.AddToggle("Enable", &BokehEnable);
|
|
bk.AddToggle("Debug Overlay", &BokehDebugOverlay);
|
|
bk.AddText("Bokeh count", bokehCountString, 64);
|
|
|
|
bk.AddSlider("Brightness Threshold Min",&editedSettings.m_BokehBrightnessThresholdMin,0.0f,10.0,0.01f);
|
|
bk.AddSlider("Brightness Threshold Max",&editedSettings.m_BokehBrightnessThresholdMax,0.0f,10.0,0.01f);
|
|
bk.AddSlider("Brightness Exposure Range Min",&BokehBrightnessExposureMin,-5.0f,5.0f,0.1f);
|
|
bk.AddSlider("Brightness Exposure Range Max",&BokehBrightnessExposureMax,-5.0f,5.0f,0.1f);
|
|
bk.AddSlider("Brightness Threshold Fade Range Min", &editedSettings.m_BokehBrightnessFadeThresholdMin, 0.0f, 10.0f, 0.01f);
|
|
bk.AddSlider("Brightness Threshold Fade Range Max", &editedSettings.m_BokehBrightnessFadeThresholdMax, 0.0f, 10.0f, 0.01f);
|
|
|
|
bk.AddSeparator();
|
|
bk.AddSlider("Shape override test",&bokehShapeOverride,-1,15,1);
|
|
bk.AddSlider("Shape Exposure Range Min",&BokehShapeExposureRangeMin,-5.0f,5.0f,0.1f);
|
|
bk.AddSlider("Shape Exposure Range Max",&BokehShapeExposureRangeMax,-5.0f,5.0f,0.1f);
|
|
|
|
bk.AddSeparator();
|
|
|
|
bk.AddSlider("COC Threhold",&BokehBlurThresholdVal,0.0f,5.0,0.05f);
|
|
#if !(DOF_COMPUTE_GAUSSIAN || DOF_DIFFUSION)
|
|
bk.AddSlider("Max Size",&MaxBokehSizeVar,0.0f,100.0,1.0f);
|
|
#endif
|
|
bk.AddSlider("Size Multiplier", &bokehSizeMultiplier, 1.0f, 10.0f, 0.01f);
|
|
|
|
bk.AddSlider("Global Alpha", &BokehGlobalAlpha, 0.0f, 1.0f, 0.01f);
|
|
bk.AddSlider("Alpha Cutoff", &BokehAlphaCutoff, 0.0f, 1.0f, 0.15f);
|
|
|
|
bk.PopGroup();
|
|
}
|
|
#endif
|
|
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("Motion Blur", false);
|
|
#if DEBUG_MOTIONBLUR
|
|
bk.AddToggle("Debug Motion Blur", &g_debugPrintMotionBlur);
|
|
#endif
|
|
bk.AddSeparator();
|
|
bk.AddToggle("Default Motion Blur Enabled", &g_DefaultMotionBlurEnabled);
|
|
bk.AddSlider("Default Motion Blur Strength", &g_DefaultMotionBlurStrength, 0.0f, 1.0f, 0.01f, NullCB, "Def Motion Blur Strength" );
|
|
bk.AddSeparator();
|
|
bk.AddSlider("Directional Blur Length", &editedSettings.m_directionalBlurLength, 0.0f, 10.0f, 0.1f, NullCB, "Blurs length." );
|
|
bk.AddSlider("Directional Blur Ghosting Fade", &editedSettings.m_directionalBlurGhostingFade, 0.0f, 1.0f, 0.1f, NullCB, "Ghosting fade." );
|
|
bk.AddSlider("Directional Blur Max. Velocity Multiplier", &editedSettings.m_directionalBlurMaxVelocityMult, 0.0f, 10.0f, 0.1f, NullCB, "Max vel multiplier" );
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("Night Vision", false);
|
|
bk.AddToggle("Enable", &editedSettings.m_nightVision);
|
|
bk.AddToggle("Override", &g_overrideNightVision);
|
|
bk.AddSeparator();
|
|
|
|
bk.AddSlider("Low Lum", &editedSettings.m_lowLum, 0.0f, 2.0f, 0.01f);
|
|
bk.AddSlider("High Lum", &editedSettings.m_highLum, 0.0f, 2.0f, 0.01f);
|
|
bk.AddSlider("Top Lum", &editedSettings.m_topLum, 0.0f, 2.0f, 0.01f);
|
|
|
|
bk.AddSlider("Scaler Lum", &editedSettings.m_scalerLum, 0.0f, 256.0f, 0.01f);
|
|
|
|
bk.AddSlider("Lum Offset", &editedSettings.m_offsetLum, -2.0f, 2.0f, 0.01f);
|
|
bk.AddSlider("Low Lum Offset", &editedSettings.m_offsetLowLum, -2.0f, 2.0f, 0.01f);
|
|
bk.AddSlider("High Lum Offset", &editedSettings.m_offsetHighLum, -2.0f, 2.0f, 0.01f);
|
|
|
|
bk.AddSlider("Noise", &editedSettings.m_noiseLum, 0.0f, 1.0f, 0.01f);
|
|
bk.AddSlider("Low Lum Noise", &editedSettings.m_noiseLowLum, 0.0f, 1.0f, 0.01f);
|
|
bk.AddSlider("High Lum Noise", &editedSettings.m_noiseHighLum, 0.0f, 1.0f, 0.01f);
|
|
|
|
bk.AddSlider("Bloom", &editedSettings.m_bloomLum, 0.0f, 4.0f, 0.01f);
|
|
|
|
bk.AddColor("Color",reinterpret_cast<Vector3*>(&editedSettings.m_colorLum), NullCB );
|
|
bk.AddColor("Low Lum Color",reinterpret_cast<Vector3*>(&editedSettings.m_colorLowLum), NullCB );
|
|
bk.AddColor("High Lum Color",reinterpret_cast<Vector3*>(&editedSettings.m_colorHighLum), NullCB );
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("Heat Haze", false);
|
|
bk.AddSlider("Start range",&editedSettings.m_HeatHazeParams.x,0.0f,5000.0f,0.1f);
|
|
bk.AddSlider("Far range",&editedSettings.m_HeatHazeParams.y,0.0f,5000.0f,0.1f);
|
|
bk.AddSlider("Min Intensity", &editedSettings.m_HeatHazeParams.z, 0.0f, 2.0f, 0.01f);
|
|
bk.AddSlider("Max Intensity", &editedSettings.m_HeatHazeParams.w, 0.0f, 2.0f, 0.01f);
|
|
|
|
bk.AddSlider("Displacement Scale U", &editedSettings.m_HeatHazeOffsetParams.x, -128.0f, 128.0f, 0.01f);
|
|
bk.AddSlider("Displacement Scale V", &editedSettings.m_HeatHazeOffsetParams.y, -128.0f, 128.0f, 0.01f);
|
|
|
|
bk.AddSlider("Tex1 U scale", &editedSettings.m_HeatHazeTex1Params.x, -128.0f, 128.0f, 0.01f);
|
|
bk.AddSlider("Tex1 V scale", &editedSettings.m_HeatHazeTex1Params.y, -128.0f, 128.0f, 0.01f);
|
|
bk.AddSlider("Tex1 U offset", &editedSettings.m_HeatHazeTex1Params.z, -128.0f, 128.0f, 0.01f);
|
|
bk.AddSlider("Tex1 V offset", &editedSettings.m_HeatHazeTex1Params.w, -128.0f, 128.0f, 0.01f);
|
|
bk.AddSlider("Tex2 U scale", &editedSettings.m_HeatHazeTex2Params.x, -128.0f, 128.0f, 0.01f);
|
|
bk.AddSlider("Tex2 V scale", &editedSettings.m_HeatHazeTex2Params.y, -128.0f, 128.0f, 0.01f);
|
|
bk.AddSlider("Tex2 U offset", &editedSettings.m_HeatHazeTex2Params.z, -128.0f, 128.0f, 0.01f);
|
|
bk.AddSlider("Tex2 V offset", &editedSettings.m_HeatHazeTex2Params.w, -128.0f, 128.0f, 0.01f);
|
|
|
|
bk.AddSlider("Tex1 U Frequency offset", &editedSettings.m_HeatHazeTex1Anim.x,-10.0f * PI, +10.0f * PI, PI/10.0f);
|
|
bk.AddSlider("Tex1 U Frequency", &editedSettings.m_HeatHazeTex1Anim.y,-10.0f * PI, +10.0f * PI, PI/10.0f);
|
|
bk.AddSlider("Tex1 U Amplitude", &editedSettings.m_HeatHazeTex1Anim.z,-64.0f,64.0f,0.1f);
|
|
bk.AddSlider("Tex1 V Scrolling speed", &editedSettings.m_HeatHazeTex1Anim.w,-64.0f,64.0f,0.1f);
|
|
|
|
bk.AddSlider("Tex2 U Frequency offset", &editedSettings.m_HeatHazeTex2Anim.x,-10.0f * PI, +10.0f * PI, PI/10.0f);
|
|
bk.AddSlider("Tex2 U Frequency", &editedSettings.m_HeatHazeTex2Anim.y,-10.0f * PI, +10.0f * PI, PI/10.0f);
|
|
bk.AddSlider("Tex2 U Amplitude", &editedSettings.m_HeatHazeTex2Anim.z,-64.0f,64.0f,0.1f);
|
|
bk.AddSlider("Tex2 V Scrolling speed", &editedSettings.m_HeatHazeTex2Anim.w,-64.0f,64.0f,0.1f);
|
|
|
|
bk.AddSlider("extra Z", &editedSettings.m_HeatHazeOffsetParams.z, -128.0f, 128.0f, 0.01f);
|
|
bk.AddSlider("extra W", &editedSettings.m_HeatHazeOffsetParams.w, -128.0f, 128.0f, 0.01f);
|
|
bk.PopGroup();
|
|
|
|
bk.PushGroup("SeeThrough", false);
|
|
bk.AddToggle("Enable", &editedSettings.m_seeThrough);
|
|
bk.AddSeparator();
|
|
bk.AddSlider("Depth Start", &editedSettings.m_SeeThroughDepthParams.x, 0.0f, 6000.0f,0.1f);
|
|
bk.AddSlider("Depth End", &editedSettings.m_SeeThroughDepthParams.y, 0.0f, 6000.0f,0.1f);
|
|
bk.AddSlider("Thickness", &editedSettings.m_SeeThroughDepthParams.z, 1.0f, 10000.0f,0.1f);
|
|
bk.AddSlider("Min Noise", &editedSettings.m_SeeThroughParams.x, 0.0f, 2.0f,0.1f);
|
|
bk.AddSlider("Max Noise", &editedSettings.m_SeeThroughParams.y, 0.0f, 2.0f,0.1f);
|
|
bk.AddSlider("HiLight Intensity", &editedSettings.m_SeeThroughParams.z, 0.0f, 10.0f,0.1f);
|
|
bk.AddSlider("HiLight Noise", &editedSettings.m_SeeThroughParams.w, 0.0f, 2.0f,0.1f);
|
|
bk.AddColor("Near Color",&editedSettings.m_SeeThroughColorNear);
|
|
bk.AddColor("Far Color",&editedSettings.m_SeeThroughColorFar);
|
|
bk.AddColor("Visible Color Base",&editedSettings.m_SeeThroughColorVisibleBase);
|
|
bk.AddColor("Visible Color Warm",&editedSettings.m_SeeThroughColorVisibleWarm);
|
|
bk.AddColor("Visible Color Hot",&editedSettings.m_SeeThroughColorVisibleHot);
|
|
bk.PopGroup();
|
|
|
|
#if FILM_EFFECT
|
|
bk.PushGroup("Film Effect", false);
|
|
bk.AddToggle("Enabled", &g_EnableFilmEffect);
|
|
bk.AddSlider("Base Distortion Coefficient", &g_BaseDistortionCoefficient, -2.0f, 2.0f, 0.01f);
|
|
bk.AddSlider("Base Cube Distortion Coefficient", &g_BaseCubeDistortionCoefficient, -2.0f, 2.0f, 0.01f);
|
|
bk.AddSlider("Chromatic Aberration Offset", &g_ChromaticAberrationOffset, -0.1f, 0.1f, 0.01f);
|
|
bk.AddSlider("Chromatic Aberration Cube Offset", &g_ChromaticAberrationCubeOffset, -2.0f, 2.0f, 0.01f);
|
|
bk.AddSlider("Film Noise", &g_FilmNoise, 0.0f, 0.2f, 0.01f);
|
|
bk.AddSlider("Film Vignetting Intensity", &g_FilmVignettingIntensity, 0.0f, 2.0f, 0.01f);
|
|
bk.AddSlider("Film Vignetting Radius", &g_FilmVignettingRadius, 0.0f, 40.0f, 0.01f);
|
|
bk.AddSlider("Film Vignetting Contrast", &g_FilmVignettingContrast, 0.0f, 2.0f, 0.01f);
|
|
bk.PopGroup();
|
|
#endif
|
|
|
|
#if ADAPTIVE_DOF
|
|
AdaptiveDepthOfField.AddWidgets(bk, editedSettings);
|
|
#endif
|
|
|
|
#if USE_SCREEN_WATERMARK
|
|
bk.PushGroup("Screen Watermark");
|
|
bk.AddToggle("Enable", &ms_watermarkParams.bForceWatermark);
|
|
bk.AddSeparator();
|
|
bk.AddSlider("Day Alpha", &ms_watermarkParams.alphaDay, 0.01f, 1.0f, 0.001f);
|
|
bk.AddSlider("Night Alpha", &ms_watermarkParams.alphaNight, 0.01f, 1.0f, 0.001f);
|
|
bk.AddSeparator();
|
|
bk.AddColor("Text Color", &ms_watermarkParams.textColor);
|
|
bk.AddVector("Text Pos", &ms_watermarkParams.textPos, 0.0f, 2000.0f, 0.001f);
|
|
bk.AddSlider("Text Size", &ms_watermarkParams.textSize, 0.1f, 200.0f, 0.001f);
|
|
bk.AddToggle("Use Outline", &ms_watermarkParams.useOutline);
|
|
|
|
#if DISPLAY_NETWORK_INFO
|
|
bk.AddColor("Net Info Text Color", &ms_watermarkParams.netTextColor);
|
|
bk.AddVector("Net Info Text Pos", &ms_watermarkParams.netTextPos, 0.0f, 2000.0f, 0.001f);
|
|
bk.AddSlider("Net Info Text Size", &ms_watermarkParams.netTextSize, 0.1f, 200.0f, 0.001f);
|
|
#endif
|
|
|
|
bk.AddSeparator();
|
|
bk.AddToggle("Use Debug String", &ms_watermarkParams.bUseDebugText);
|
|
bk.AddText("Debug String", &ms_watermarkParams.debugText[0], 16);
|
|
|
|
bk.PopGroup();
|
|
#endif
|
|
|
|
PHONEPHOTOEDITOR.AddWidgets(bk);
|
|
|
|
LENSARTEFACTSMGR.AddWidgets(bk);
|
|
bk.UnSetCurrentGroup(*ms_postFxGroup);
|
|
}
|
|
|
|
void PostFX::AddWidgets(bkBank &bk)
|
|
{
|
|
ms_postFxGroup = bk.PushGroup("Post FX", false);
|
|
ms_addPostFxWidgets = bk.AddButton("Create PostFX widgets", CFA1(PostFX::AddWidgetsOnDemand));
|
|
bk.PopGroup();
|
|
|
|
//for screen shots
|
|
bkBank *pBank = BANKMGR.FindBank("Optimization");
|
|
pBank->AddToggle("turn off depth of field",&NoDOF );
|
|
pBank->AddToggle("turn off motion blur",&NoMotionBlur );
|
|
pBank->AddToggle("turn off bloom", &NoBloom);
|
|
}
|
|
|
|
bool& PostFX::GetSimplePfxRef()
|
|
{
|
|
return g_ForceUseSimple;
|
|
}
|
|
#endif //BANK
|
|
|
|
void PostFX::SetFograyParams(bool bShadowActive)
|
|
{
|
|
PostFXParamBlock::paramBlock& settings = PostFXParamBlock::GetUpdateThreadParams();
|
|
#if __BANK
|
|
if (g_Override==false)
|
|
#endif // __BANK
|
|
{
|
|
const tcKeyframeUncompressed& currKeyframe = (!sysThreadType::IsRenderThread() ? g_timeCycle.GetCurrUpdateKeyframe() : g_timeCycle.GetCurrRenderKeyframe());
|
|
|
|
settings.m_fograyContrast = currKeyframe.GetVar(TCVAR_FOG_FOGRAY_CONTRAST);
|
|
settings.m_fograyIntensity = currKeyframe.GetVar(TCVAR_FOG_FOGRAY_INTENSITY);
|
|
settings.m_fograyDensity = currKeyframe.GetVar(TCVAR_FOG_FOGRAY_DENSITY);
|
|
}
|
|
settings.m_bShadowActive = bShadowActive;
|
|
CRenderPhaseCascadeShadows::ComputeFograyFadeRange(settings.m_fograyFadeStart, settings.m_fograyFadeEnd);
|
|
|
|
settings.m_bFogRayMiniShadowMapGenerated = (settings.m_fograyIntensity > 0.0f) && settings.m_bShadowActive;
|
|
}
|
|
|
|
void PostFX::LockAdaptiveDofDistance(bool lock)
|
|
{
|
|
#if ADAPTIVE_DOF
|
|
AdaptiveDepthOfField.SetLockFocusDistance(lock);
|
|
#else
|
|
(void)lock;
|
|
#endif
|
|
}
|
|
|
|
// DOF parameters
|
|
void PostFX::SetDofParams()
|
|
{
|
|
|
|
#if __BANK
|
|
if (g_Override==false)
|
|
#endif // __BANK
|
|
{
|
|
PostFXParamBlock::paramBlock& settings = PostFXParamBlock::GetUpdateThreadParams();
|
|
|
|
// sniper sight first
|
|
if (settings.m_sniperSightActive)
|
|
{
|
|
settings.m_HighDof = true;
|
|
settings.m_ShallowDof = true;
|
|
settings.m_hiDofParameters = settings.m_sniperSightDOFParams;
|
|
|
|
return;
|
|
}
|
|
|
|
const tcKeyframeUncompressed& currKeyframe = (!sysThreadType::IsRenderThread() ? g_timeCycle.GetCurrUpdateKeyframe() : g_timeCycle.GetCurrRenderKeyframe());
|
|
const camFrame& frame = gVpMan.GetCurrentGameViewportFrame();
|
|
|
|
// TBR: might want to define a new interface to set high dof
|
|
settings.m_AdaptiveDofCustomPlanesBlendLevel = frame.GetDofPlanesBlendLevel();
|
|
if( settings.m_screenBlurFade > 0.0 )
|
|
settings.m_AdaptiveDofCustomPlanesBlendLevel = settings.m_screenBlurFade;
|
|
|
|
const bool camHiDof = settings.m_AdaptiveDofCustomPlanesBlendLevel >= (1.0f - SMALL_FLOAT);
|
|
const bool tcHiDof = currKeyframe.GetVar(TCVAR_DOF_ENABLE_HQDOF) > 0.5f;
|
|
|
|
settings.m_AdaptiveDof = false;
|
|
settings.m_HighDof = camHiDof || tcHiDof;
|
|
|
|
settings.m_EnvironmentalBlurParams.x = currKeyframe.GetVar(TCVAR_ENV_BLUR_IN);
|
|
settings.m_EnvironmentalBlurParams.y = currKeyframe.GetVar(TCVAR_ENV_BLUR_OUT);
|
|
settings.m_EnvironmentalBlurParams.z = currKeyframe.GetVar(TCVAR_ENV_BLUR_SIZE);
|
|
|
|
#if GTA_REPLAY
|
|
// TBR: This logic should be in the camera code, and here we just do what camera flags say.
|
|
// If replay's active and the DOF mode has been changed to anything other than default, then
|
|
// let DOF have priority over environmental blur (which is probably being used by one of the filters).
|
|
const bool bReplayActive = CReplayMgr::IsPlaying() || CReplayMgr::IsEditModeActive();
|
|
if (bReplayActive)
|
|
{
|
|
bool bHasDofChanged = false;
|
|
const IReplayMarkerStorage* pMarkerStorage = CReplayMarkerContext::GetMarkerStorage();
|
|
const sReplayMarkerInfo* pMarkerInfo = (pMarkerStorage ? pMarkerStorage->TryGetMarker(camReplayDirector::GetCurrentMarkerIndex()) : NULL);
|
|
if (pMarkerInfo)
|
|
{
|
|
bHasDofChanged = (pMarkerInfo->GetFocusMode() != DEFAULT_MARKER_DOF_FOCUS || pMarkerInfo->GetDofMode() != DEFAULT_MARKER_DOF_MODE);
|
|
}
|
|
if (bHasDofChanged)
|
|
{
|
|
settings.m_EnvironmentalBlurParams.x = 10000.000f;
|
|
settings.m_EnvironmentalBlurParams.y = 10000.000f;
|
|
settings.m_EnvironmentalBlurParams.z = 1.0f;
|
|
}
|
|
}
|
|
#endif //GTA_REPLAY
|
|
|
|
settings.m_AdaptiveDofBlurDiskRadiusPowerFactorNear = frame.GetDofBlurDiskRadiusPowerFactorNear();
|
|
|
|
const bool scriptHiDof = settings.m_HighDofScriptOverrideToggle;
|
|
|
|
settings.m_DOFOverride = 1.0f;
|
|
settings.m_DOFOverrideEnabled = false;
|
|
|
|
if ( scriptHiDof )
|
|
{
|
|
settings.m_HighDof = settings.m_HighDofScriptOverrideEnableDOF;
|
|
settings.m_ShallowDof = false;
|
|
settings.m_HighDofForceSmallBlur = false;
|
|
}
|
|
else if (frame.GetFlags().IsFlagSet(camFrame::Flag_ShouldOverrideDofBlurDiskRadius))
|
|
{
|
|
settings.m_DOFOverride = frame.GetDofBlurDiskRadius();
|
|
settings.m_DOFOverrideEnabled = true;
|
|
}
|
|
|
|
settings.m_HighDof = settings.m_HighDof;
|
|
|
|
#if RSG_PC
|
|
if(CReplayMgr::IsEditModeActive() && !PostFX::UseDOFInReplay())
|
|
{
|
|
settings.m_HighDof = false;
|
|
}
|
|
#endif
|
|
|
|
if(settings.m_HighDof)
|
|
{
|
|
if ( scriptHiDof )
|
|
{
|
|
settings.m_hiDofParameters = settings.m_hiDofScriptParameters;
|
|
}
|
|
else if( camHiDof )
|
|
{
|
|
//Use a high-quality four-plane DOF effect.
|
|
frame.ComputeDofPlanes(settings.m_hiDofParameters);
|
|
|
|
settings.m_HighDofForceSmallBlur = frame.GetFlags().IsFlagSet(camFrame::Flag_ShouldUseLightDof);
|
|
|
|
// light dof version excludes the shallow mode
|
|
settings.m_ShallowDof = (settings.m_HighDofForceSmallBlur == false && frame.GetFlags().IsFlagSet(camFrame::Flag_ShouldUseShallowDof));
|
|
}
|
|
else if( tcHiDof )
|
|
{
|
|
settings.m_hiDofParameters[0] = currKeyframe.GetVar(TCVAR_DOF_HQDOF_NEARPLANE_OUT);
|
|
settings.m_hiDofParameters[1] = currKeyframe.GetVar(TCVAR_DOF_HQDOF_NEARPLANE_IN);
|
|
settings.m_hiDofParameters[2] = currKeyframe.GetVar(TCVAR_DOF_HQDOF_FARPLANE_OUT);
|
|
settings.m_hiDofParameters[3] = currKeyframe.GetVar(TCVAR_DOF_HQDOF_FARPLANE_IN);
|
|
|
|
settings.m_HighDofForceSmallBlur = currKeyframe.GetVar(TCVAR_DOF_HQDOF_SMALLBLUR) > 0.5f;
|
|
settings.m_ShallowDof = currKeyframe.GetVar(TCVAR_DOF_HQDOF_SHALLOWDOF) > 0.5f;
|
|
}
|
|
else
|
|
{
|
|
Assertf(settings.m_HighDof == false,"HiDof is on, but no one turned it on");
|
|
}
|
|
}
|
|
#if ADAPTIVE_DOF
|
|
else if(AdaptiveDepthOfField.IsEnabled())
|
|
{
|
|
//Use a high-quality four-plane DOF effect.
|
|
frame.ComputeDofPlanes(settings.m_hiDofParameters);
|
|
|
|
// light dof version excludes the shallow mode
|
|
settings.m_ShallowDof = (settings.m_HighDofForceSmallBlur == false && frame.GetFlags().IsFlagSet(camFrame::Flag_ShouldUseShallowDof));
|
|
|
|
#if ADAPTIVE_DOF_CPU
|
|
bool bGaussian = (GRCDEVICE.GetDxFeatureLevel() >=1100) ? true : false;
|
|
#if RSG_PC
|
|
bGaussian &= ((GET_POSTFX_SETTING(CSettingsManager::GetInstance().GetSettings().m_graphics.m_PostFX) >= CSettings::High) && (GRCDEVICE.IsStereoEnabled() == false)) ? true : false;
|
|
#endif // RSG_PC
|
|
if (!bGaussian && UseAdaptiveDofCPU())
|
|
{
|
|
AdaptiveDepthOfField.CalculateCPUParams(settings.m_hiDofParameters, settings.m_DOFOverride);
|
|
settings.m_ShallowDof = (settings.m_HighDofForceSmallBlur == false && CPhoneMgr::CamGetShallowDofModeState());
|
|
}
|
|
#endif
|
|
|
|
settings.m_AdaptiveDof = true;
|
|
|
|
#if RSG_PC
|
|
if(CReplayMgr::IsEditModeActive() && !PostFX::UseDOFInReplay())
|
|
{
|
|
settings.m_AdaptiveDof = false;
|
|
}
|
|
else
|
|
{
|
|
if (GET_POSTFX_SETTING(CSettingsManager::GetInstance().GetSettings().m_graphics.m_PostFX) < CSettings::High)
|
|
{
|
|
if (!UseAdaptiveDofCPU())
|
|
{
|
|
settings.m_AdaptiveDof = false;
|
|
}
|
|
}
|
|
}
|
|
#endif // RSG_PC
|
|
}
|
|
#endif
|
|
else
|
|
{
|
|
settings.m_SimpleDof = frame.GetFlags().IsFlagSet(camFrame::Flag_ShouldUseSimpleDof);
|
|
|
|
// Let timecycle drive simple DOF settings unless the camera frame
|
|
// says otherwise
|
|
if (settings.m_SimpleDof == false)
|
|
{
|
|
//Use a simple DOF effect; just a blur based upon the far DOF plane.
|
|
const float timeCycleDofStrength = currKeyframe.GetVar(TCVAR_DOF_BLUR_FAR);
|
|
const float timeCycleFarDof = currKeyframe.GetVar(TCVAR_DOF_FAR);
|
|
float farDof = timeCycleFarDof;
|
|
|
|
farDof = rage::Max(farDof, 0.1f);
|
|
|
|
const float ooLength = 1.0f/(farDof+farDof*0.5f);
|
|
settings.m_dofParameters.Set(farDof, ooLength, timeCycleDofStrength, 0.0f);
|
|
}
|
|
else
|
|
{
|
|
// TODO: grab these values from camera frame
|
|
|
|
//const float farFarPlane = 1.0f;
|
|
const float blurStrength = 1.0f;
|
|
|
|
Vector4 DofPlanes;
|
|
|
|
frame.ComputeDofPlanes(DofPlanes);
|
|
|
|
const float oofarFarPlane = 1.0f/(DofPlanes.w);
|
|
const float farNearPlane = DofPlanes.z;
|
|
|
|
settings.m_dofParameters.Set(farNearPlane, oofarFarPlane, blurStrength, 0.0f);
|
|
}
|
|
|
|
settings.m_ShallowDof = false;
|
|
settings.m_HighDofForceSmallBlur = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
void RunGaussianBlur9x9(grcRenderTarget* pDestTarget, grcRenderTarget* pDestTargetScratch, int numPasses)
|
|
{
|
|
for (int i = 0; i < numPasses; i++)
|
|
{
|
|
// 9x9 Gaussian blur (horizontal)
|
|
PostFXShader->SetVar(BloomTexelSizeId,Vector4(1.0f/float(pDestTarget->GetWidth()),1.0f/float(pDestTarget->GetHeight()),0.0, 0.0f));
|
|
PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/float(pDestTarget->GetWidth()),1.0f/float(pDestTarget->GetHeight()),0.0, 0.0f));
|
|
PostFXShader->SetVar(TextureID_0, pDestTarget);
|
|
PostFXBlit(pDestTargetScratch, PostFXTechnique, pp_GaussBlur_Hor, false, true);
|
|
|
|
// 9x9 Gaussian blur (vertical)
|
|
PostFXShader->SetVar(TextureID_0, pDestTargetScratch);
|
|
PostFXBlit(pDestTarget, PostFXTechnique, pp_GaussBlur_Ver, false, true);
|
|
}
|
|
}
|
|
|
|
void ProcessBloomBuffer(grcRenderTarget* pDestTarget, const grcTexture* pSrcTarget, PostFXPass pass)
|
|
{
|
|
PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/float(pSrcTarget->GetWidth()),1.0f/float(pSrcTarget->GetHeight()),0.0, 0.0f));
|
|
PostFXShader->SetVar(TextureID_0, pSrcTarget);
|
|
PostFXBlit(pDestTarget, PostFXTechnique, pass, false, false);
|
|
}
|
|
|
|
void ProcessBlurVignetting(grcRenderTarget* pDestTarget, const PostFX::PostFXParamBlock::paramBlock& settings)
|
|
{
|
|
PF_PUSH_MARKER("ProcessBlurVignetting");
|
|
|
|
grcRenderTarget* pFinalTarget = pDestTarget;
|
|
grcRenderTarget* pBlurTarget = HalfScreen0;
|
|
grcRenderTarget* pBlurScratchTarget = BloomBufferHalf1;
|
|
|
|
// Downsample
|
|
ProcessBloomBuffer(pBlurTarget, pDestTarget, pp_DownSampleBloom);
|
|
|
|
// Blur Vignetting
|
|
const int numPasses = 2;
|
|
const float blurVignettingBias = 1.0f-settings.m_blurVignettingParams.x;
|
|
const float blurVignettingRadius = settings.m_blurVignettingParams.y;
|
|
PostFXShader->SetVar(BlurVignettingParamsID, Vector4(blurVignettingBias, blurVignettingRadius, 1.0f, 0.0f));
|
|
|
|
#if POSTFX_TILED_LIGHTING_ENABLED
|
|
if (g_bRunBlurVignettingTiled && BANK_SWITCH(PostFX::g_UseTiledTechniques == true, CTiledLighting::IsEnabled()))
|
|
{
|
|
const char* pPassNameHor = NULL;
|
|
const char* pPassNameVer = NULL;
|
|
const char* pPassNameFinal = NULL;
|
|
#if RAGE_TIMEBARS
|
|
pPassNameHor = passName[pp_blur_vignetting_blur_hor_tiled];
|
|
pPassNameVer = passName[pp_blur_vignetting_blur_ver_tiled];
|
|
pPassNameFinal = passName[pp_blur_vignetting_tiled];
|
|
#endif
|
|
|
|
for (int i = 0; i < numPasses; i++)
|
|
{
|
|
// 9x9 Gaussian blur (horizontal)
|
|
PostFXShader->SetVar(BloomTexelSizeId,Vector4(1.0f/float(pBlurTarget->GetWidth()),1.0f/float(pBlurTarget->GetHeight()),0.0, 0.0f));
|
|
PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/float(pBlurTarget->GetWidth()),1.0f/float(pBlurTarget->GetHeight()),0.0, 0.0f));
|
|
PostFXShader->SetVar(TextureID_0, pBlurTarget);
|
|
#if __D3D11 || RSG_ORBIS
|
|
PostFXShader->SetVar(TiledDepthTextureId, CTiledLighting::GetClassificationTexture());
|
|
#endif // __D3D11 || RSG_ORBIS
|
|
PostFXShader->SetVar(BlurVignettingParamsID, Vector4(blurVignettingBias, blurVignettingRadius, 1.0f, 0.0f));
|
|
|
|
CTiledLighting::RenderTiles(pBlurScratchTarget, PostFXShader, PostFXTechnique, pp_blur_vignetting_blur_hor_tiled, pPassNameHor, false);
|
|
|
|
// 9x9 Gaussian blur (vertical)
|
|
PostFXShader->SetVar(TextureID_0, pBlurScratchTarget);
|
|
CTiledLighting::RenderTiles(pBlurTarget, PostFXShader, PostFXTechnique, pp_blur_vignetting_blur_ver_tiled, pPassNameVer, false);
|
|
}
|
|
|
|
PostFXShader->SetVar(PostFxTexture3Id, pBlurTarget);
|
|
PostFXShader->SetVar(BlurVignettingParamsID, Vector4(blurVignettingBias, blurVignettingRadius, 1.0f, 0.0f));
|
|
CTiledLighting::RenderTiles(pFinalTarget, PostFXShader, PostFXTechnique, pp_blur_vignetting_tiled, pPassNameFinal, false);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
RunGaussianBlur9x9(pBlurTarget, pBlurScratchTarget, numPasses);
|
|
|
|
PostFXShader->SetVar(PostFxTexture3Id, pBlurTarget);
|
|
PostFXBlit(pFinalTarget, PostFXTechnique, pp_blur_vignetting, false, false);
|
|
}
|
|
|
|
|
|
|
|
|
|
PF_POP_MARKER();
|
|
}
|
|
|
|
void BlurBloomBuffer(grcRenderTarget* BloomBufferDst, bool bSeeThroughPass = false)
|
|
{
|
|
PF_PUSH_MARKER("BlurBloomBuffer");
|
|
|
|
SetNonDepthFXStateBlocks();
|
|
|
|
static int numBlurPasses2x = 1;
|
|
static int numBlurPasses4x = 1;
|
|
static int numBlurPasses8x = 2;
|
|
static int numBlurPasses16x = 2;
|
|
|
|
PostFXPass upsamplePass = (bSeeThroughPass ? pp_BloomComposite_SeeThrough : pp_BloomComposite);
|
|
PostFXPass downsamplePass = pp_DownSampleBloom;
|
|
|
|
// Downsample 2x
|
|
ProcessBloomBuffer(BloomBufferHalf0, BloomBufferDst, downsamplePass);
|
|
// Blur 2x
|
|
RunGaussianBlur9x9(BloomBufferHalf0, BloomBufferHalf1, numBlurPasses2x);
|
|
|
|
// Downsample 2x to 4x
|
|
ProcessBloomBuffer(BloomBufferQuarter0, BloomBufferHalf0, downsamplePass);
|
|
// Blur 4x
|
|
RunGaussianBlur9x9(BloomBufferQuarter0, BloomBufferQuarter1, numBlurPasses4x);
|
|
|
|
// Downsample 4x to 8x
|
|
ProcessBloomBuffer(BloomBufferEighth0, BloomBufferQuarter0, downsamplePass);
|
|
// Blur 8x
|
|
RunGaussianBlur9x9(BloomBufferEighth0, BloomBufferEighth1, numBlurPasses8x);
|
|
|
|
// Downsample 8x to 16x
|
|
ProcessBloomBuffer(BloomBufferSixteenth0, BloomBufferEighth0, downsamplePass);
|
|
// Blur 16x
|
|
RunGaussianBlur9x9(BloomBufferSixteenth0, BloomBufferSixteenth1, numBlurPasses16x);
|
|
|
|
Vector4 BloomParams;
|
|
BloomParams.Zero();
|
|
|
|
// Upsample and composite 16x into 8x
|
|
BloomParams.w = PostFX::g_bloomLargeBlurBlendMult;
|
|
PostFXShader->SetVar(BloomParamsId, BloomParams);
|
|
ProcessBloomBuffer(BloomBufferEighth0, BloomBufferSixteenth0, upsamplePass);
|
|
// Upsample and composite 8x into 4x
|
|
BloomParams.w = PostFX::g_bloomMedBlurBlendMult;
|
|
PostFXShader->SetVar(BloomParamsId, BloomParams);
|
|
ProcessBloomBuffer(BloomBufferQuarter0, BloomBufferEighth0, upsamplePass);
|
|
// Upsample and composite 4x into 2x
|
|
BloomParams.w = PostFX::g_bloomSmallBlurBlendMult;
|
|
PostFXShader->SetVar(BloomParamsId, BloomParams);
|
|
ProcessBloomBuffer(BloomBufferHalf0, BloomBufferQuarter0, upsamplePass);
|
|
|
|
// Blur 2x again
|
|
RunGaussianBlur9x9(BloomBufferHalf0, BloomBufferHalf1, numBlurPasses2x);
|
|
|
|
// Upsample and composite 2x into BloomBufferDst
|
|
ProcessBloomBuffer(BloomBufferDst, BloomBufferHalf0, upsamplePass);
|
|
|
|
|
|
PF_POP_MARKER();
|
|
}
|
|
|
|
#if DOF_COMPUTE_GAUSSIAN
|
|
float CalculateGaussianWeight(int sampleDist, int kernel)
|
|
{
|
|
float sigma = kernel / 3.0f;
|
|
float g = 1.0f / sqrt(2.0f * PI * sigma * sigma);
|
|
return (g * exp(-(sampleDist * sampleDist) / (2 * sigma * sigma)));
|
|
}
|
|
|
|
//weightOffset used to provide a stronger blur with less samples, without it you typically get values very small towards the edge of the blur which add very little contribution, this eliminates them.
|
|
void SetupGaussianWeights(grcBufferUAV& pWeightsBuffer, u32 weightOffset)
|
|
{
|
|
int uMaxGaussianElements = DOF_MaxSampleRadius;
|
|
for( u32 i = 0; i <= DOF_MaxSampleRadius; i++)
|
|
uMaxGaussianElements += i+1;
|
|
|
|
float pWeights[(DOF_MaxSampleRadius*DOF_MaxSampleRadius)+DOF_MaxSampleRadius];
|
|
float* pWeightsDest = pWeights;
|
|
u32 size = 0;
|
|
//Store the offsets in the first DOF_MaxSampleRadius slots;
|
|
u32 kernel = 1;
|
|
for( kernel = 1; kernel <= DOF_MaxSampleRadius; kernel++)
|
|
{
|
|
int offset = DOF_MaxSampleRadius;
|
|
for( int i = 1; i < kernel; i++)
|
|
offset += (i+1);
|
|
|
|
*pWeightsDest = (float)offset;
|
|
pWeightsDest++;
|
|
size++;
|
|
}
|
|
|
|
u32 kernelSize = 1;
|
|
for( u32 i = kernelSize; i <= DOF_MaxSampleRadius; i++)
|
|
{
|
|
for( u32 j = 0; j <= i; j++)
|
|
{
|
|
*pWeightsDest = CalculateGaussianWeight(j, i + weightOffset);
|
|
pWeightsDest++;
|
|
size++;
|
|
}
|
|
}
|
|
|
|
# if RSG_ORBIS
|
|
const sce::Gnm::SizeAlign weightsSizeAlign = { uMaxGaussianElements * sizeof(float), 16 };
|
|
pWeightsBuffer.Allocate( weightsSizeAlign, true, pWeights, sizeof(float) );
|
|
# elif RSG_DURANGO
|
|
pWeightsBuffer.Initialise( uMaxGaussianElements, sizeof(float), grcBindShaderResource|grcBindUnorderedAccess, NULL, grcBufferMisc_BufferStructured);
|
|
float *pDest = (float *)pWeightsBuffer.Lock(grcsWrite, 0, uMaxGaussianElements, NULL);
|
|
memcpy(pDest, pWeights, sizeof(float)*uMaxGaussianElements);
|
|
pWeightsBuffer.Unlock(grcsWrite);
|
|
# else // RSG_P C
|
|
pWeightsBuffer.Initialise( uMaxGaussianElements, sizeof(float), grcBindShaderResource|grcBindUnorderedAccess, grcsBufferCreate_ReadWrite, grcsBufferSync_None, pWeights, false, grcBufferMisc_BufferStructured );
|
|
# endif
|
|
}
|
|
#endif //DOF_COMPUTE_GAUSSIAN
|
|
|
|
#if BOKEH_SUPPORT || DOF_COMPUTE_GAUSSIAN
|
|
void InitBokehDOF()
|
|
{
|
|
#if BOKEH_SORT_BITONIC_TRANSPOSE
|
|
s_BokehMaxElements = BOKEH_SORT_TRANSPOSE_BLOCK_SIZE * BOKEH_SORT_BITONIC_BLOCK_SIZE;
|
|
#else
|
|
s_BokehMaxElements = BOKEH_SORT_NUM_BUCKETS * BOKEH_SORT_BITONIC_BLOCK_SIZE;
|
|
#endif
|
|
const u32 uMaxElements = s_BokehMaxElements;
|
|
const u32 uBufferSize = uMaxElements * s_BokehBufferStride;
|
|
if( s_BokehAllocatedSize != uBufferSize )
|
|
{
|
|
static ALIGNAS(16) u32 bufferInit[4] = {0,1,0,0};
|
|
# if RSG_ORBIS
|
|
const sce::Gnm::SizeAlign accumSizeAlign = { uBufferSize, 16 };
|
|
s_BokehAccumBuffer.Allocate( accumSizeAlign, true, NULL, s_BokehBufferStride );
|
|
const sce::Gnm::SizeAlign indirectSizeAlign = { 16, sce::Gnm::kAlignmentOfIndirectArgsInBytes };
|
|
s_indirectArgsBuffer.Allocate( indirectSizeAlign, true, bufferInit );
|
|
|
|
const sce::Gnm::SizeAlign IndexSizeAlign = { uMaxElements * s_BokehIndexListBufferStride, 16 };
|
|
s_BokehIndexListBuffer.Allocate( IndexSizeAlign, true, NULL, s_BokehIndexListBufferStride );
|
|
s_bokehSortedIndexListBuffer.Allocate( IndexSizeAlign, true, NULL, s_BokehIndexListBufferStride );
|
|
#if BOKEH_SORT_BITONIC_TRANSPOSE
|
|
s_bokehSortedIndexListBuffer2.Allocate( IndexSizeAlign, true, NULL, s_BokehIndexListBufferStride );
|
|
#endif //BOKEH_SORT_BITONIC_TRANSPOSE
|
|
const sce::Gnm::SizeAlign bucketsSizeAlign = { BOKEH_SORT_NUM_BUCKETS * s_BokehBucketsNumAddedBufferStride, 16 };
|
|
s_bokehNumAddedToBuckets.Allocate( bucketsSizeAlign, true, NULL, s_BokehBucketsNumAddedBufferStride );
|
|
|
|
# elif RSG_DURANGO
|
|
s_BokehAccumBuffer.Initialise( uMaxElements, s_BokehBufferStride, grcBindShaderResource|grcBindUnorderedAccess, NULL, grcBufferMisc_BufferStructured, grcBuffer_UAV_FLAG_COUNTER);
|
|
s_BokehIndexListBuffer.Initialise( uMaxElements, s_BokehIndexListBufferStride, grcBindShaderResource|grcBindUnorderedAccess, NULL, grcBufferMisc_BufferStructured, 0);
|
|
s_bokehSortedIndexListBuffer.Initialise( uMaxElements, s_BokehIndexListBufferStride, grcBindShaderResource|grcBindUnorderedAccess, NULL, grcBufferMisc_BufferStructured, 0);
|
|
#if BOKEH_SORT_BITONIC_TRANSPOSE
|
|
s_bokehSortedIndexListBuffer2.Initialise( uMaxElements, s_BokehIndexListBufferStride, grcBindShaderResource|grcBindUnorderedAccess, NULL, grcBufferMisc_BufferStructured, 0);
|
|
#endif //BOKEH_SORT_BITONIC_TRANSPOSE
|
|
s_bokehNumAddedToBuckets.Initialise( BOKEH_SORT_NUM_BUCKETS, s_BokehBucketsNumAddedBufferStride, grcBindShaderResource|grcBindUnorderedAccess, NULL, grcBufferMisc_BufferStructured, 0);
|
|
|
|
s_indirectArgsBuffer.Initialise( sizeof(int) * 4, sizeof(int), grcBindShaderResource, NULL, grcBufferMisc_DrawIndirectArgs);
|
|
u32 *pDest = (u32 *)s_indirectArgsBuffer.Lock(grcsWrite, 0, 0, NULL);
|
|
memcpy(pDest, bufferInit, sizeof(bufferInit));
|
|
s_indirectArgsBuffer.Unlock(grcsWrite);
|
|
# else // RSG_P C
|
|
s_BokehAccumBuffer.Initialise( uMaxElements, s_BokehBufferStride, grcBindShaderResource|grcBindUnorderedAccess, grcsBufferCreate_ReadWrite, grcsBufferSync_None, NULL, false, grcBufferMisc_BufferStructured, grcBuffer_UAV_FLAG_COUNTER );
|
|
s_indirectArgsBuffer.Initialise( 1, 16, grcBindNone, grcsBufferCreate_ReadWrite, grcsBufferSync_None, bufferInit, false, grcBufferMisc_DrawIndirectArgs );
|
|
|
|
s_BokehIndexListBuffer.Initialise( uMaxElements, s_BokehIndexListBufferStride, grcBindShaderResource|grcBindUnorderedAccess, grcsBufferCreate_ReadWrite, grcsBufferSync_None, NULL, false, grcBufferMisc_BufferStructured, 0 );
|
|
#if BOKEH_SORT_BITONIC_TRANSPOSE
|
|
s_bokehSortedIndexListBuffer2.Initialise( uMaxElements, s_BokehIndexListBufferStride, grcBindShaderResource|grcBindUnorderedAccess, grcsBufferCreate_ReadWrite, grcsBufferSync_None, NULL, false, grcBufferMisc_BufferStructured, 0 );
|
|
#endif //BOKEH_SORT_BITONIC_TRANSPOSE
|
|
s_bokehNumAddedToBuckets.Initialise( BOKEH_SORT_NUM_BUCKETS, s_BokehBucketsNumAddedBufferStride, grcBindShaderResource|grcBindUnorderedAccess, grcsBufferCreate_ReadWrite, grcsBufferSync_None, NULL, false, grcBufferMisc_BufferStructured, 0 );
|
|
s_bokehSortedIndexListBuffer.Initialise( uMaxElements, s_BokehIndexListBufferStride, grcBindShaderResource|grcBindUnorderedAccess, grcsBufferCreate_ReadWrite, grcsBufferSync_None, NULL, false, grcBufferMisc_BufferStructured, 0 );
|
|
# endif
|
|
s_BokehAllocatedSize = uBufferSize;
|
|
}
|
|
|
|
#if DOF_COMPUTE_GAUSSIAN
|
|
if( !sSetupGaussianWeights )
|
|
{
|
|
SetupGaussianWeights(s_GaussianWeightsBuffer, 0);
|
|
SetupGaussianWeights(s_GaussianWeightsCOCBuffer, 4);
|
|
sSetupGaussianWeights = true;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void ProcessBokehPreDOF(const PostFX::PostFXParamBlock::paramBlock &settings, float screenBlurFadeLevel)
|
|
{
|
|
const u32 width = VideoResManager::GetSceneWidth();
|
|
const u32 height = VideoResManager::GetSceneHeight();
|
|
|
|
Vec2V DOFTargetSizeVar = Vec2V((float)width,(float)height);
|
|
Vec2V RenderTargetSizeVar = Vec2V((float)width,(float)height);
|
|
|
|
#if BOKEH_SORT_BITONIC_TRANSPOSE
|
|
s_BokehMaxElements = BOKEH_SORT_TRANSPOSE_BLOCK_SIZE * BOKEH_SORT_BITONIC_BLOCK_SIZE;
|
|
#else
|
|
s_BokehMaxElements = BOKEH_SORT_NUM_BUCKETS * BOKEH_SORT_BITONIC_BLOCK_SIZE;
|
|
#endif
|
|
ASSERT_ONLY(const u32 uMaxElements = s_BokehMaxElements;)
|
|
ASSERT_ONLY(const u32 uBufferSize = uMaxElements * s_BokehBufferStride;)
|
|
Assertf(( s_BokehAllocatedSize == uBufferSize ), "InitBokehDOF");
|
|
|
|
//Setup shader constants
|
|
const Vector4 exposureParams(BokehBrightnessExposureMax, BokehBrightnessExposureMin, settings.m_BokehBrightnessThresholdMax, settings.m_BokehBrightnessThresholdMin);
|
|
PostFXShader->SetVar(BokehBrightnessParams, exposureParams);
|
|
PostFXShader->SetVar(DOFTargetSize, DOFTargetSizeVar);
|
|
|
|
#if DOF_COMPUTE_GAUSSIAN || DOF_DIFFUSION
|
|
//Set the max bokeh size to the kernel size we then scale this by the coc in the shader
|
|
if( CurrentDOFTechnique == dof_computeGaussian || CurrentDOFTechnique == dof_diffusion)
|
|
{
|
|
float kernelSize = (float)DofKernelSizeVar;
|
|
if( settings.m_DOFOverrideEnabled )
|
|
kernelSize = settings.m_DOFOverride;
|
|
else if( settings.m_ShallowDof )
|
|
kernelSize = (float)DofShallowKernelSizeVar;
|
|
else if( settings.m_AdaptiveDof )
|
|
kernelSize = (float)DofAdaptiveKernelSizeVar;
|
|
|
|
if(PostFX::ExtraEffectsRequireBlur())
|
|
kernelSize = Lerp(screenBlurFadeLevel, kernelSize, (float)DOF_MaxSampleRadius);
|
|
|
|
if (settings.m_AdaptiveDof)
|
|
{
|
|
MaxBokehSizeVar = bokehSizeMultiplier;
|
|
}
|
|
else
|
|
{
|
|
MaxBokehSizeVar = kernelSize * bokehSizeMultiplier;
|
|
}
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
float kernelSize = (float)DofKernelSizeVar;
|
|
|
|
if( settings.m_DOFOverrideEnabled )
|
|
kernelSize = settings.m_DOFOverride;
|
|
|
|
if (settings.m_AdaptiveDof)
|
|
{
|
|
MaxBokehSizeVar = bokehSizeMultiplier;
|
|
}
|
|
else
|
|
{
|
|
MaxBokehSizeVar = kernelSize * bokehSizeMultiplier;
|
|
}
|
|
}
|
|
const Vector4 bokehParams(settings.m_BokehBrightnessFadeThresholdMin, settings.m_BokehBrightnessFadeThresholdMax, BokehBlurThresholdVal, MaxBokehSizeVar);
|
|
PostFXShader->SetVar(BokehParams1, bokehParams);
|
|
|
|
float bokehShapeOverrideVal = -1.0f;
|
|
float debugOverlay = 0.0f;
|
|
#if __BANK
|
|
bokehShapeOverrideVal = (float)bokehShapeOverride;
|
|
debugOverlay = BokehDebugOverlay ? 1.0f : 0.0f;
|
|
#endif
|
|
const Vector4 bokehParams2(BokehShapeExposureRangeMax, BokehShapeExposureRangeMin, bokehShapeOverrideVal, debugOverlay);
|
|
PostFXShader->SetVar(BokehParams2, bokehParams2);
|
|
|
|
PostFXShader->SetVar(BokehAlphaCutoffVar, BokehAlphaCutoff);
|
|
PostFXShader->SetVar(BokehGlobalAlphaVar, BokehGlobalAlpha);
|
|
|
|
PostFXShader->SetVar(RenderTargetSize, RenderTargetSizeVar);
|
|
|
|
//render depth blur pass
|
|
const grcTexture *backBuffer = CRenderTargets::GetBackBuffer();
|
|
#if DEVICE_MSAA
|
|
if( GRCDEVICE.GetMSAA()>1 )
|
|
{
|
|
backBuffer = CRenderTargets::GetBackBufferCopy(false);
|
|
}
|
|
#endif //DEVICE_MSAA
|
|
PostFXShader->SetVar(TextureID_0, backBuffer); //linear sampling
|
|
PostFXShader->SetVar(JitterTextureId, backBuffer ); //points sampling
|
|
|
|
grcRenderTarget* pDepth = CRenderTargets::GetDepthResolved();
|
|
if( DofUsePreAlphaDepth )
|
|
pDepth = CRenderTargets::GetDepthBuffer_PreAlpha();
|
|
|
|
PostFXShader->SetVar(PostFxTexture2Id, pDepth);
|
|
|
|
#if PTFX_APPLY_DOF_TO_PARTICLES
|
|
if (CPtFxManager::UseParticleDOF())
|
|
{
|
|
PostFXShader->SetVar(PtfxDepthBuffer, g_ptFxManager.GetPtfxDepthTexture() );
|
|
PostFXShader->SetVar(PtfxAlphaBuffer, g_ptFxManager.GetPtfxAlphaTexture() );
|
|
}
|
|
#endif //PTFX_APPLY_DOF_TO_PARTICLES
|
|
|
|
u32 pass = pp_Bokeh_DepthBlur;
|
|
#if ADAPTIVE_DOF_GPU
|
|
|
|
if(settings.m_AdaptiveDof)
|
|
{
|
|
#if ADAPTIVE_DOF_OUTPUT_UAV
|
|
PostFXShader->SetVar(PostFXAdaptiveDOFParamsBufferVar, AdaptiveDepthOfField.GetParamsRT());
|
|
#else
|
|
PostFXShader->SetVar(TextureID_v0, AdaptiveDepthOfField.GetParamsRT());
|
|
#endif //ADAPTIVE_DOF_OUTPUT_UAV
|
|
|
|
Vector4 adaptiveDofEnvBlurParams(settings.m_EnvironmentalBlurParams);
|
|
adaptiveDofEnvBlurParams.SetW(screenBlurFadeLevel);
|
|
PostFXShader->SetVar(PostFXAdaptiveDofEnvBlurParamsVar, adaptiveDofEnvBlurParams);
|
|
|
|
//Compute the blur radius required for any custom DOF planes.
|
|
//NOTE: This is ugly, but necessary, due to the way animated cutscenes, scripts and the time-cycle system override the DOF planes.
|
|
float customPlanesBlurDiskRadius = (float)DofKernelSizeVar;
|
|
if(settings.m_DOFOverrideEnabled)
|
|
{
|
|
customPlanesBlurDiskRadius = settings.m_DOFOverride;
|
|
}
|
|
else if(settings.m_ShallowDof)
|
|
{
|
|
customPlanesBlurDiskRadius = (float)DofShallowKernelSizeVar;
|
|
}
|
|
|
|
Vector4 adaptiveDofCustomPlanesParams(settings.m_AdaptiveDofCustomPlanesBlendLevel, customPlanesBlurDiskRadius, settings.m_AdaptiveDofBlurDiskRadiusPowerFactorNear, 0.0f);
|
|
PostFXShader->SetVar(PostFXAdaptiveDofCustomPlanesParamsVar, adaptiveDofCustomPlanesParams);
|
|
|
|
pass = pp_Bokeh_DepthBlurAdaptive;
|
|
}
|
|
#endif
|
|
|
|
PostFXBlit(BokehDepthBlur, PostFXBokehTechnique, pass, false, false,
|
|
#if RAGE_TIMEBARS
|
|
(bokehPassName)
|
|
#else
|
|
NULL
|
|
#endif
|
|
);
|
|
|
|
PostFXShader->SetVar(FXAABackBuffer, BokehDepthBlur );
|
|
pass = pp_Bokeh_DepthBlurDownsample;
|
|
PostFXBlit(BokehDepthBlurHalfRes, PostFXBokehTechnique, pass, false, false,
|
|
#if RAGE_TIMEBARS
|
|
(bokehPassName)
|
|
#else
|
|
NULL
|
|
#endif
|
|
);
|
|
}
|
|
|
|
void ProcessBokehPostDOF(const PostFX::PostFXParamBlock::paramBlock &settings)
|
|
{
|
|
GRCDEVICE.ClearUAV(false, &s_bokehNumAddedToBuckets);
|
|
GRCDEVICE.ClearUAV(false, &s_bokehSortedIndexListBuffer);
|
|
|
|
//Generate Bokeh sprites in UAV for use in geometry shader
|
|
PostFXShader->SetVar(GBufferTextureIdSSAODepth, BokehDepthBlur);
|
|
#if __D3D11
|
|
const grcBufferUAV* UAVs[grcMaxUAVViews] = {
|
|
&s_BokehAccumBuffer,
|
|
&s_bokehSortedIndexListBuffer,
|
|
&s_bokehNumAddedToBuckets
|
|
};
|
|
#endif
|
|
#if RSG_DURANGO || RSG_ORBIS
|
|
PostFXShader->SetVarUAV(BokehOutputPointBufferVar, &s_BokehAccumBuffer, 0);
|
|
PostFXShader->SetVarUAV(BokehSortedBufferVar, &s_bokehSortedIndexListBuffer, 0);
|
|
PostFXShader->SetVarUAV(BokehSortOffsetsBufferVar, &s_bokehNumAddedToBuckets, 0);
|
|
#endif //platforms
|
|
|
|
//render depth blur pass
|
|
const grcTexture *backBuffer = CRenderTargets::GetBackBuffer();
|
|
#if DEVICE_MSAA
|
|
if( GRCDEVICE.GetMSAA()>1 )
|
|
{
|
|
backBuffer = CRenderTargets::GetBackBufferCopy(false);
|
|
}
|
|
#endif //DEVICE_MSAA
|
|
|
|
PostFXShader->SetVar(TextureID_0, backBuffer); //linear sampling
|
|
PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/float(backBuffer->GetWidth()),1.0f/float(backBuffer->GetHeight()),0.0, 0.0f));
|
|
PostFXBlit(BokehPointsTemp, PostFXBokehTechnique, pp_Bokeh_Downsample, false, false,
|
|
#if RAGE_TIMEBARS
|
|
(bokehPassName)
|
|
#else
|
|
NULL
|
|
#endif
|
|
,false
|
|
);
|
|
|
|
PostFXShader->SetVar(TextureID_0, BokehPointsTemp); //linear sampling
|
|
PostFXShader->SetVar(JitterTextureId, BokehPointsTemp ); //points sampling
|
|
if (BokehPointsTemp != NULL)
|
|
PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/float(BokehPointsTemp->GetWidth()),1.0f/float(BokehPointsTemp->GetHeight()),0.0, 0.0f));
|
|
|
|
PostFXShader->SetVar(TextureID_v0, PostFX::g_currentExposureRT);
|
|
grcStateBlock::SetBlendState(grcStateBlock::BS_Default_WriteMaskNone);
|
|
|
|
//HalfScreen0 not actually written to here as colour writes disabled - we still need its contents. Just re-using the target as its the correct size.
|
|
#if RSG_PC
|
|
CShaderLib::SetStereoTexture();
|
|
#endif
|
|
PostFXBlit(HalfScreen0, PostFXBokehTechnique, pp_Bokeh_Generation, false, false,
|
|
#if RAGE_TIMEBARS
|
|
(bokehPassName)
|
|
#else
|
|
|
|
NULL
|
|
#endif
|
|
,false, Vector2(0.0f,0.0f), Vector2(1.0f,1.0f)
|
|
#if __D3D11
|
|
,UAVs
|
|
#endif
|
|
);
|
|
|
|
|
|
grcStateBlock::SetBlendState(nonDepthFXBlendState);
|
|
|
|
//Render Bokeh sprites with geometry shader
|
|
PostFXShader->SetVar(HeatHazeTextureId, m_BokehShapeTextureSheet);
|
|
PostFXShader->SetVar(TextureID_0, BokehDepthBlur);
|
|
|
|
u32 bokehSpritePass = pp_Bokeh_Sprites;
|
|
#if ADAPTIVE_DOF_OUTPUT_UAV
|
|
if( settings.m_AdaptiveDof)
|
|
bokehSpritePass = pp_Bokeh_Sprites_Adaptive;
|
|
#endif //ADAPTIVE_DOF_OUTPUT_UAV
|
|
|
|
#if RSG_PC
|
|
CShaderLib::SetStereoTexture();
|
|
#endif
|
|
BokehBlitWithGeometryShader(BokehPoints, PostFXBokehTechnique, bokehSpritePass, false, true,
|
|
#if RAGE_TIMEBARS
|
|
(bokehPassName)
|
|
#else
|
|
NULL
|
|
#endif
|
|
);
|
|
#if RSG_DURANGO && __BANK
|
|
if (PostFX::g_DrawCOCOverlay && AltBokehDepthBlur)
|
|
{
|
|
ESRAMManager::ESRAMCopyOut(AltBokehDepthBlur, BokehDepthBlur);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#endif //BOKEH_SUPPORT
|
|
|
|
|
|
#if DOF_DIFFUSION
|
|
|
|
void DiffusionDOFDraw(u32 shaderPass)
|
|
{
|
|
// #if POSTFX_UNIT_QUAD
|
|
// dofDiffusionShader->SetVar(quad::Position, FastQuad::Pack(-1.f,1.f,1.f,-1.f));
|
|
// dofDiffusionShader->SetVar(quad::TexCoords, FastQuad::Pack(0.f,0.f,1.f,1.f));
|
|
// dofDiffusionShader->SetVar(quad::Scale, Vector4(1.0f,1.0f,1.0f,1.0f));
|
|
// #endif
|
|
AssertVerify(dofDiffusionShader->BeginDraw(grmShader::RMC_DRAW,true,dofDiffusiontechnique)); // MIGRATE_FIXME
|
|
dofDiffusionShader->Bind((int)shaderPass);
|
|
// #if POSTFX_UNIT_QUAD
|
|
// FastQuad::Draw(true);
|
|
// #else
|
|
Color32 color(1.0f,1.0f,1.0f,1.0f);
|
|
grcDrawSingleQuadf(-1.0, 1.0f, 1.0f, -1.0f, 0.0f, 0.0, 0.0, 1.0f, 1.0f,color);
|
|
//#endif
|
|
dofDiffusionShader->UnBind();
|
|
dofDiffusionShader->EndDraw();
|
|
}
|
|
void ProcessDiffusionDOFCS( grcRenderTarget* pOutputImage)
|
|
{
|
|
grcTextureFactory& textureFactory = grcTextureFactory::GetInstance();
|
|
|
|
PIXBegin(0, "Diffusion DOF");
|
|
|
|
u32 screenWidth = GRCDEVICE.GetWidth();
|
|
u32 screenHeight = GRCDEVICE.GetHeight();
|
|
//bool bPacked = false;
|
|
u32 shaderPass = 0;
|
|
s32 i = 0;
|
|
|
|
dofDiffusionShader->SetVar( dofDiffusion_DiffusionRadiusVar, (float)DofKernelSizeVar);
|
|
|
|
grcRenderTarget* pSourceImage = CRenderTargets::GetBackBuffer();
|
|
|
|
PIXBegin(0, "Vertical Phase");
|
|
// VERTICAL phase
|
|
// iterate until system is small enough
|
|
for( i = 1; ; ++i )
|
|
{
|
|
if( ( screenHeight >> i ) < 2 )
|
|
break;
|
|
|
|
float lastBufferSize = float(( screenHeight >> (i-1) ));
|
|
dofDiffusionShader->SetVar( dofDiffusion_lastbufferSizeVar, lastBufferSize);
|
|
|
|
if( i == 2 )
|
|
continue;
|
|
|
|
if( i == 1 )
|
|
{
|
|
shaderPass = /*bPacked? g_pPackedInitialReduceVert4PS :*/ pp_DOF_Diffusion_InitialReduceVert4;
|
|
}
|
|
else //if( i == 2 )
|
|
{
|
|
shaderPass = /*bPacked? g_pPackedReduceVertPS :*/ pp_DOF_Diffusion_ReduceVert;
|
|
}
|
|
|
|
if( i > 1 )
|
|
{
|
|
/*if( bPacked )
|
|
{
|
|
const grcRenderTarget* RenderTargets[grcmrtColorCount] = {
|
|
g_pVertABCXRTV[i]
|
|
};
|
|
textureFactory.LockMRT(RenderTargets, NULL);
|
|
}
|
|
else*/
|
|
{
|
|
const grcRenderTarget* RenderTargets[grcmrtColorCount] = {
|
|
dofDiffusionVertABC[i],
|
|
dofDiffusionVertX[i-1]
|
|
};
|
|
textureFactory.LockMRT(RenderTargets, NULL);
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/*if( bPacked )
|
|
{
|
|
const grcRenderTarget* RenderTargets[grcmrtColorCount] = {
|
|
g_pVertABCXRTV[i+1]
|
|
};
|
|
textureFactory11.LockMRT(RenderTargets, NULL);
|
|
}
|
|
else*/
|
|
{
|
|
const grcRenderTarget* RenderTargets[grcmrtColorCount] = {
|
|
dofDiffusionVertABC[i+1],
|
|
dofDiffusionVertX[i]
|
|
};
|
|
textureFactory.LockMRT(RenderTargets, NULL);
|
|
}
|
|
}
|
|
|
|
if( (i-1) == 0 )
|
|
{
|
|
dofDiffusionShader->SetVar( dofDiffusion_txABC_ID, dofDiffusionHorzABC[0]);
|
|
//bPacked ? g_pHorzABCXSRV[0]:g_pHorzABCSRV[0];
|
|
}
|
|
else
|
|
{
|
|
dofDiffusionShader->SetVar( dofDiffusion_txABC_ID, dofDiffusionVertABC[i-1]);
|
|
//bPacked ? g_pVertABCXSRV[i-1]:g_pVertABCSRV[i-1];
|
|
}
|
|
#if BOKEH_SUPPORT
|
|
dofDiffusionShader->SetVar( dofDiffusion_txCOC_ID, BokehDepthBlur);
|
|
#endif
|
|
//pSRV[1] = DepthStencilTextureSRV; //Already calculated coc so use that instead.
|
|
if( i == 1 )
|
|
dofDiffusionShader->SetVar( dofDiffusion_txX_ID, pSourceImage);
|
|
else
|
|
{
|
|
dofDiffusionShader->SetVar( dofDiffusion_txX_ID, dofDiffusionVertX[i-2]);
|
|
}
|
|
|
|
DiffusionDOFDraw(shaderPass);
|
|
|
|
textureFactory.UnlockMRT();
|
|
}
|
|
|
|
PIXEnd(); // Vertical phase
|
|
|
|
--i;
|
|
|
|
PIXBegin(0, "Vertical - solve final small system");
|
|
|
|
// solve final small system
|
|
{
|
|
const grcRenderTarget* RenderTargets[grcmrtColorCount] = {
|
|
dofDiffusionVertY[i]
|
|
};
|
|
textureFactory.LockMRT(RenderTargets, NULL);
|
|
|
|
dofDiffusionShader->SetVar( dofDiffusion_txABC_ID, dofDiffusionVertABC[i]); ///*bPacked ? g_pVertABCXSRV[i]:*/g_pVertABCSRV[i];
|
|
dofDiffusionShader->SetVar( dofDiffusion_txX_ID, dofDiffusionVertX[i-1]);
|
|
|
|
if( ( screenHeight >> ( i ) ) == 2 )
|
|
{
|
|
shaderPass = /*bPacked?g_pPackedReduceFinalVert2PS:*/ pp_DOF_Diffusion_ReduceFinalVert2;
|
|
}
|
|
else
|
|
{
|
|
shaderPass = /*bPacked?g_pPackedReduceFinalVert3PS:*/ pp_DOF_Diffusion_ReduceFinalVert3;
|
|
}
|
|
|
|
DiffusionDOFDraw(shaderPass);
|
|
|
|
textureFactory.UnlockMRT();
|
|
}
|
|
|
|
|
|
PIXEnd();
|
|
|
|
PIXBegin(0, "Vertical - Expand Solutions");
|
|
// expand solutions
|
|
|
|
shaderPass = /*bPacked?g_pPackedSolveVertPS:*/ pp_DOF_Diffusion_SolveVert;
|
|
|
|
for(i-=1; i >=0; --i )
|
|
{
|
|
if( i == 0 )
|
|
continue;
|
|
|
|
if( i == 1 )
|
|
{
|
|
const grcRenderTarget* RenderTargets[grcmrtColorCount] = {
|
|
dofDiffusionHorzY[i-1]
|
|
};
|
|
textureFactory.LockMRT(RenderTargets, NULL);
|
|
}
|
|
else
|
|
{
|
|
if( i != 0 )
|
|
{
|
|
const grcRenderTarget* RenderTargets[grcmrtColorCount] = {
|
|
dofDiffusionVertY[i]
|
|
};
|
|
textureFactory.LockMRT(RenderTargets, NULL);
|
|
}
|
|
else
|
|
{
|
|
const grcRenderTarget* RenderTargets[grcmrtColorCount] = {
|
|
dofDiffusionHorzY[i-1]
|
|
};
|
|
textureFactory.LockMRT(RenderTargets, NULL);
|
|
}
|
|
}
|
|
|
|
if( i == 1 )
|
|
shaderPass = pp_DOF_FinalSolveVert4;
|
|
|
|
if( i == 0 )
|
|
{
|
|
///*bPacked ? g_pHorzABCXSRV[0]:*/g_pHorzABCSRV[0];
|
|
dofDiffusionShader->SetVar( dofDiffusion_txABC_ID, dofDiffusionHorzABC[0]);
|
|
}
|
|
else
|
|
{
|
|
//*bPacked ? g_pVertABCXSRV[i]:*/g_pVertABCSRV[i];
|
|
dofDiffusionShader->SetVar( dofDiffusion_txABC_ID, dofDiffusionVertABC[i]);
|
|
}
|
|
//pSRV[1] = DepthStencilTextureSRV;
|
|
if( i > 1 )
|
|
{
|
|
//pSRV[2] = g_pVertXSRV[i-1];
|
|
dofDiffusionShader->SetVar( dofDiffusion_txX_ID, dofDiffusionVertX[i-1]);
|
|
}
|
|
else
|
|
{
|
|
//pSRV[2] = SourceImageSRV;
|
|
//pSRV[4] = g_pVertXSRV[i-2];
|
|
dofDiffusionShader->SetVar( dofDiffusion_txX_ID, pSourceImage);
|
|
//dofDiffusionShader->SetVar( dofDiffusion_txX_ID, CRenderTargets::GetBackBuffer());
|
|
|
|
}
|
|
dofDiffusionShader->SetVar( dofDiffusion_txY_ID, dofDiffusionVertY[i+1]);
|
|
|
|
DiffusionDOFDraw(shaderPass);
|
|
|
|
textureFactory.UnlockMRT();
|
|
}
|
|
|
|
PIXEnd();
|
|
|
|
PIXBegin(0, "Horizontal Phase");
|
|
// HORIZONTAL PHASE of Diffusion DOF
|
|
// iterate until system is small enough
|
|
for( i = 1; ; ++i )
|
|
{
|
|
if( ( screenWidth >> i ) < 2 )
|
|
break;
|
|
|
|
float lastBufferSize = float(( screenWidth >> (i-1) ));
|
|
dofDiffusionShader->SetVar( dofDiffusion_lastbufferSizeVar, lastBufferSize);
|
|
|
|
// skip second pass as we have alreadz reduced by a factor of 4
|
|
if( i == 2 )
|
|
continue;
|
|
|
|
if( i == 1 )
|
|
{
|
|
shaderPass = /*bPacked?g_pPackedInitialReduceHorz4PS:*/ pp_DOF_Diffusion_InitialReduceHorz4;
|
|
}
|
|
else
|
|
{
|
|
shaderPass = /*bPacked?g_pPackedReduceHorzPS:*/pp_DOF_Diffusion_ReduceHorz;
|
|
}
|
|
|
|
if( i > 1 )
|
|
{
|
|
/*if( bPacked )
|
|
{
|
|
pRTV[0] = g_pHorzABCXRTV[i];
|
|
pRTV[1] = 0;
|
|
pd3dImmediateContext->OMSetRenderTargets(2, pRTV, NULL );
|
|
}
|
|
else*/
|
|
{
|
|
|
|
const grcRenderTarget* RenderTargets[grcmrtColorCount] = {
|
|
dofDiffusionHorzABC[i],
|
|
dofDiffusionHorzX[i-1]
|
|
};
|
|
textureFactory.LockMRT(RenderTargets, NULL);
|
|
}
|
|
}
|
|
else // first pass => reduce factor 4
|
|
{
|
|
/*if( bPacked )
|
|
{
|
|
pRTV[0] = g_pHorzABCXRTV[i+1];
|
|
pRTV[1] = 0;
|
|
pd3dImmediateContext->OMSetRenderTargets(2, pRTV, NULL );
|
|
}
|
|
else*/
|
|
{
|
|
const grcRenderTarget* RenderTargets[grcmrtColorCount] = {
|
|
dofDiffusionHorzABC[i+1],
|
|
dofDiffusionHorzX[i]
|
|
};
|
|
textureFactory.LockMRT(RenderTargets, NULL);
|
|
}
|
|
}
|
|
|
|
dofDiffusionShader->SetVar( dofDiffusion_txABC_ID, dofDiffusionHorzABC[i-1]);
|
|
//pSRV[1] = DepthStencilTextureSRV;
|
|
if( i == 1 )
|
|
dofDiffusionShader->SetVar( dofDiffusion_txX_ID, dofDiffusionHorzY[0]);
|
|
else
|
|
{
|
|
dofDiffusionShader->SetVar( dofDiffusion_txX_ID, dofDiffusionHorzX[i-2]);
|
|
}
|
|
|
|
DiffusionDOFDraw(shaderPass);
|
|
|
|
textureFactory.UnlockMRT();
|
|
}
|
|
|
|
--i;
|
|
|
|
PIXEnd();
|
|
|
|
PIXBegin(0, "Horizontal - solve final small system");
|
|
|
|
// solve final small system
|
|
{
|
|
const grcRenderTarget* RenderTargets[grcmrtColorCount] = {
|
|
dofDiffusionHorzY[i]
|
|
};
|
|
textureFactory.LockMRT(RenderTargets, NULL);
|
|
|
|
dofDiffusionShader->SetVar( dofDiffusion_txABC_ID, dofDiffusionHorzABC[i]);
|
|
//pSRV[1] = DepthStencilTextureSRV;
|
|
dofDiffusionShader->SetVar( dofDiffusion_txX_ID, dofDiffusionHorzX[i-1]);
|
|
|
|
if( ( screenWidth >> ( i ) ) == 2 )
|
|
{
|
|
shaderPass = /*bPacked ? g_pPackedReduceFinalHorz2PS:*/ pp_DOF_Diffusion_ReduceFinalHorz2;
|
|
}
|
|
else
|
|
{
|
|
shaderPass = /*bPacked ? g_pPackedReduceFinalHorz3PS:*/ pp_DOF_Diffusion_ReduceFinalHorz3;
|
|
}
|
|
|
|
DiffusionDOFDraw(shaderPass);
|
|
|
|
textureFactory.UnlockMRT();
|
|
}
|
|
|
|
PIXEnd();
|
|
|
|
PIXBegin(0, "Horizontal - expand solutions");
|
|
|
|
// expand solutions
|
|
shaderPass = /*bPacked?g_pPackedSolveHorzPS:*/pp_DOF_Diffusion_SolveHorz;
|
|
|
|
|
|
for(i-=1; i >=0; --i )
|
|
{
|
|
if( i == 0 )
|
|
continue;
|
|
|
|
if( i == 1 )
|
|
{
|
|
const grcRenderTarget* RenderTargets[grcmrtColorCount] = {
|
|
pOutputImage
|
|
};
|
|
textureFactory.LockMRT(RenderTargets, NULL);
|
|
}
|
|
else
|
|
{
|
|
const grcRenderTarget* RenderTargets[grcmrtColorCount] = {
|
|
dofDiffusionHorzY[i]
|
|
};
|
|
textureFactory.LockMRT(RenderTargets, NULL);
|
|
}
|
|
|
|
if( i == 1 )
|
|
shaderPass = pp_DOF_FinalSolveHorz4;
|
|
|
|
|
|
dofDiffusionShader->SetVar( dofDiffusion_txABC_ID, dofDiffusionHorzABC[i]); // /*bPacked ? g_pHorzABCXSRV[i]:*/g_pHorzABCSRV[i];
|
|
//pSRV[1] = DepthStencilTextureSRV;
|
|
if( i > 1 )
|
|
{
|
|
dofDiffusionShader->SetVar( dofDiffusion_txX_ID, dofDiffusionHorzX[i-1]);
|
|
}
|
|
else
|
|
{
|
|
dofDiffusionShader->SetVar( dofDiffusion_txX_ID, dofDiffusionHorzY[0]);
|
|
// pSRV[4] = g_pHorzABCSRV[i+1];
|
|
// pSRV[5] = g_pHorzXSRV[i];
|
|
}
|
|
dofDiffusionShader->SetVar( dofDiffusion_txY_ID, dofDiffusionHorzY[i+1]);
|
|
|
|
DiffusionDOFDraw(shaderPass);
|
|
|
|
textureFactory.UnlockMRT();
|
|
}
|
|
|
|
PIXEnd();
|
|
|
|
PIXEnd();
|
|
|
|
}
|
|
#endif //DOF_DIFFUSION
|
|
|
|
#if DOF_COMPUTE_GAUSSIAN
|
|
|
|
void ProcessComputeGaussianDOF(const PostFX::PostFXParamBlock::paramBlock &settings, float screenBlurFadeLevel)
|
|
{
|
|
PIXBegin(0, "DOF Compute Gaussian");
|
|
|
|
u32 GridSize = DOF_ComputeGridSize;
|
|
|
|
/*DOF*/
|
|
float kernelSize = (float)DofKernelSizeVar;
|
|
if( settings.m_DOFOverrideEnabled )
|
|
kernelSize = settings.m_DOFOverride;
|
|
else if( settings.m_ShallowDof )
|
|
kernelSize = (float)DofShallowKernelSizeVar;
|
|
else if( settings.m_AdaptiveDof )
|
|
kernelSize = (float)DofAdaptiveKernelSizeVar;
|
|
|
|
if(PostFX::ExtraEffectsRequireBlur())
|
|
kernelSize = Lerp(screenBlurFadeLevel, kernelSize, (float)DOF_MaxSampleRadius);
|
|
|
|
const Vector4 projParams = ShaderUtil::CalculateProjectionParams();
|
|
dofComputeShader->SetVar(DofProjCompute, projParams);
|
|
dofComputeShader->SetVar(DofLumFilterParams, Vector2(DofLumContrastThreshold, DofMaxLuminance));
|
|
dofComputeShader->SetVar(DofSkyWeightModifierVar, DofSkyWeightModifier);
|
|
dofComputeShader->SetVar(DofRenderTargetSizeVar, Vector4((float)DepthOfField1->GetWidth(), (float)DepthOfField1->GetHeight(), 1.0f/(float)DepthOfField1->GetWidth(), 1.0f/(float)DepthOfField1->GetHeight()));
|
|
|
|
float fourPlaneDof = 1.0f;
|
|
if( settings.m_AdaptiveDof )
|
|
fourPlaneDof = 0.0f;
|
|
dofComputeShader->SetVar(fourPlaneDofVar, fourPlaneDof);
|
|
|
|
dofComputeShader->SetVar( DofKernelSize, (float)kernelSize);
|
|
#if ADAPTIVE_DOF_OUTPUT_UAV
|
|
dofComputeShader->SetVar( DofComputeAdaptiveDOFParamsBufferVar, AdaptiveDepthOfField.GetParamsRT());
|
|
#endif //ADAPTIVE_DOF_OUTPUT_UAV
|
|
|
|
grcRenderTarget* backBuffer = CRenderTargets::GetBackBuffer();
|
|
if( GRCDEVICE.GetMSAA()>1)
|
|
{
|
|
backBuffer = CRenderTargets::GetBackBufferCopy(false);
|
|
}
|
|
|
|
// Horizontal pass
|
|
dofComputeShader->SetVar(dofComputeColorTex, backBuffer);
|
|
# if BOKEH_SUPPORT
|
|
dofComputeShader->SetVar(dofComputeDepthBlurTex, BokehEnable ? BokehDepthBlur : grcTexture::NoneBlack);
|
|
dofComputeShader->SetVar(dofComputeDepthBlurHalfResTex, BokehEnable ? BokehDepthBlurHalfRes : grcTexture::NoneBlack);
|
|
# endif
|
|
|
|
dofComputeShader->SetVarUAV( dofComputeOutputTex, static_cast<grcTextureUAV*>( DepthOfField1 ) );
|
|
|
|
u32 groupCountX = (u32)((DepthOfField1->GetWidth() / (float)GridSize) + 0.5f);
|
|
groupCountX += (DepthOfField1->GetHeight() % GridSize) > 0 ? 1 : 0;
|
|
u32 groupCountY = DepthOfField1->GetHeight();
|
|
|
|
u32 horzPass = pp_DOF_ComputeGaussian_Blur_H;
|
|
if(DofLumFilteringEnable)
|
|
horzPass = pp_DOF_ComputeGaussian_Blur_H_LumFilter;
|
|
#if ADAPTIVE_DOF_OUTPUT_UAV
|
|
if( settings.m_AdaptiveDof )
|
|
{
|
|
horzPass = pp_DOF_ComputeGaussian_Blur_H_Adaptive;
|
|
|
|
if(DofLumFilteringEnable)
|
|
horzPass = pp_DOF_ComputeGaussian_Blur_H_Adaptive_LumFilter;
|
|
}
|
|
#endif //ADAPTIVE_DOF_OUTPUT_UAV
|
|
|
|
GRCDEVICE.RunComputation( "DOF Compute - H", *dofComputeShader, horzPass, groupCountX, groupCountY, 1);
|
|
|
|
# if SUPPORT_RENDERTARGET_DUMP
|
|
static_cast<grcRenderTargetDefault*>(DepthOfField1)->SaveTarget();
|
|
# endif
|
|
|
|
// Vertical pass
|
|
dofComputeShader->SetVar(dofComputeColorTex, DepthOfField1);
|
|
|
|
dofComputeShader->SetVarUAV( dofComputeOutputTex, static_cast<grcTextureUAV*>( DepthOfField2 ) );
|
|
|
|
groupCountX = DepthOfField2->GetWidth();
|
|
groupCountY = (u32)((DepthOfField2->GetHeight() / (float)GridSize) + 0.5f);
|
|
groupCountY += (DepthOfField2->GetHeight() % GridSize) > 0 ? 1 : 0;
|
|
|
|
u32 vertPass = pp_DOF_ComputeGaussian_Blur_V;
|
|
#if ADAPTIVE_DOF_OUTPUT_UAV
|
|
if( settings.m_AdaptiveDof )
|
|
vertPass = pp_DOF_ComputeGaussian_Blur_V_Adaptive;
|
|
#endif //ADAPTIVE_DOF_OUTPUT_UAV
|
|
|
|
GRCDEVICE.RunComputation( "DOF Compute - V", *dofComputeShader, vertPass, groupCountX, groupCountY, 1);
|
|
|
|
# if SUPPORT_RENDERTARGET_DUMP
|
|
static_cast<grcRenderTargetDefault*>(DepthOfField2)->SaveTarget();
|
|
# endif
|
|
|
|
# if __D3D11 || RSG_ORBIS
|
|
GRCDEVICE.SynchronizeComputeToGraphics();
|
|
# endif
|
|
PIXEnd();
|
|
};
|
|
#endif //DOF_COMPUTE_GAUSSIAN
|
|
|
|
#if COC_SPREAD
|
|
void COCSpread(u32 GridSize)
|
|
{
|
|
if (!BokehDepthBlurHalfResTemp)
|
|
return;
|
|
|
|
dofComputeShader->SetVar( DofRenderTargetSizeVar, Vector4((float)BokehDepthBlurHalfRes->GetWidth(), (float)BokehDepthBlurHalfRes->GetHeight(), 1.0f/(float)BokehDepthBlurHalfRes->GetWidth(), 1.0f/(float)BokehDepthBlurHalfRes->GetHeight()));
|
|
|
|
dofComputeShader->SetVar( DofCocSpreadKernelRadius, (float)DofCocSpreadKernelRadiusVar);
|
|
//horizontal pass
|
|
dofComputeShader->SetVar(dofComputeDepthBlurHalfResTex, BokehDepthBlurHalfRes);
|
|
dofComputeShader->SetVarUAV( cocComputeOutputTex, static_cast<grcTextureUAV*>( BokehDepthBlurHalfResTemp ) );
|
|
|
|
unsigned groupCountX = (u32)((BokehDepthBlurHalfResTemp->GetWidth() / (float)GridSize) + 0.5f);
|
|
groupCountX += (BokehDepthBlurHalfResTemp->GetHeight() % GridSize) > 0 ? 1 : 0;
|
|
unsigned groupCountY = BokehDepthBlurHalfResTemp->GetHeight();
|
|
|
|
GRCDEVICE.RunComputation( "DOF Compute COC spread - H", *dofComputeShader, pp_DOF_ComputeGaussian_COCSpread_H, groupCountX, groupCountY, 1);
|
|
|
|
# if SUPPORT_RENDERTARGET_DUMP
|
|
static_cast<grcRenderTargetDefault*>(BokehDepthBlurHalfResTemp)->SaveTarget();
|
|
# endif
|
|
|
|
//vertical pass
|
|
dofComputeShader->SetVar(dofComputeDepthBlurHalfResTex, BokehDepthBlurHalfResTemp);
|
|
dofComputeShader->SetVarUAV( cocComputeOutputTex, static_cast<grcTextureUAV*>( BokehDepthBlurHalfRes ) );
|
|
|
|
groupCountX = BokehDepthBlurHalfRes->GetWidth();
|
|
groupCountY = (u32)((BokehDepthBlurHalfRes->GetHeight() / (float)GridSize) + 0.5f);
|
|
groupCountY += (BokehDepthBlurHalfRes->GetHeight() % GridSize) > 0 ? 1 : 0;
|
|
|
|
GRCDEVICE.RunComputation( "DOF Compute COC spread - V", *dofComputeShader, pp_DOF_ComputeGaussian_COCSpread_V, groupCountX, groupCountY, 1);
|
|
|
|
# if SUPPORT_RENDERTARGET_DUMP
|
|
static_cast<grcRenderTargetDefault*>(BokehDepthBlurHalfRes)->SaveTarget();
|
|
# endif
|
|
# if __D3D11 || RSG_ORBIS
|
|
GRCDEVICE.SynchronizeComputeToGraphics();
|
|
# endif
|
|
}
|
|
#endif //COC_SPREAD
|
|
|
|
void LastGenDOF(grcRenderTarget*& pDOFLargeBlur, grcRenderTarget*& pDOFMedBlur)
|
|
{
|
|
// 1) downsample and initialise near CoC
|
|
PostFXShader->SetVar(TextureID_0, HalfScreen0);
|
|
PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/float(HalfScreen0->GetWidth()),1.0f/float(HalfScreen0->GetHeight()),0.0, 0.0f));
|
|
PostFXBlit(DepthOfField0, PostFXTechnique, pp_DownSampleBloom);
|
|
|
|
// 2) blur colour + initial near CoC
|
|
PostFXShader->SetVar(TextureID_0, DepthOfField0);
|
|
PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/float(DepthOfField0->GetWidth()),1.0f/float(DepthOfField0->GetHeight()),0.0, 0.0f));
|
|
PostFXBlit(DepthOfField1, PostFXTechnique, pp_Blur);
|
|
|
|
|
|
// 3) compute actual near CoC
|
|
PostFXShader->SetVar(TextureID_0, DepthOfField0);
|
|
PostFXShader->SetVar(TextureID_1, DepthOfField1);
|
|
PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/float(DepthOfField0->GetWidth()),1.0f/float(DepthOfField0->GetHeight()),0.0, 0.0f));
|
|
PostFXBlit(DepthOfField2, PostFXTechnique, pp_DOFCoC);
|
|
|
|
// slightly cheaper, uglier
|
|
//// 4) blur colour + near CoC
|
|
//PostFXShader->SetVar(TextureID_0, DepthOfField2);
|
|
//PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/float(DepthOfField2->GetWidth()),1.0f/float(DepthOfField2->GetHeight()),0.0, 0.0f));
|
|
//PostFXBlit(DepthOfField0, PostFXTechnique, pp_Blur);
|
|
|
|
//// 5) second blur (optional)
|
|
//PostFXShader->SetVar(TextureID_0, DepthOfField0);
|
|
//PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/float(DepthOfField2->GetWidth()),1.0f/float(DepthOfField2->GetHeight()),0.0, 0.0f));
|
|
//PostFXBlit(DepthOfField1, PostFXTechnique, pp_Blur);
|
|
|
|
|
|
// 4) blur med
|
|
PostFXShader->SetVar(TextureID_0, DepthOfField2);
|
|
PostFXShader->SetVar(BloomTexelSizeId, Vector4(1.0f/float(DepthOfField2->GetWidth()),1.0f/float(DepthOfField2->GetHeight()),0.0, 0.0f));
|
|
PostFXBlit(DepthOfField0, PostFXTechnique, pp_GaussBlur_Hor);
|
|
|
|
// 5) blur med
|
|
PostFXShader->SetVar(TextureID_0, DepthOfField0);
|
|
PostFXShader->SetVar(BloomTexelSizeId, Vector4(1.0f/float(DepthOfField2->GetWidth()),1.0f/float(DepthOfField2->GetHeight()),0.0, 0.0f));
|
|
PostFXBlit(DepthOfField2, PostFXTechnique, pp_GaussBlur_Ver);
|
|
|
|
// 6) blur colour + near CoC
|
|
PostFXShader->SetVar(TextureID_0, DepthOfField2);
|
|
PostFXShader->SetVar(BloomTexelSizeId, Vector4(1.0f/float(DepthOfField2->GetWidth()),1.0f/float(DepthOfField2->GetHeight()),0.0, 0.0f));
|
|
PostFXBlit(DepthOfField0, PostFXTechnique, pp_GaussBlur_Hor);
|
|
|
|
// 7) second blur (optional)
|
|
PostFXShader->SetVar(TextureID_0, DepthOfField0);
|
|
PostFXShader->SetVar(BloomTexelSizeId, Vector4(1.0f/float(DepthOfField2->GetWidth()),1.0f/float(DepthOfField2->GetHeight()),0.0, 0.0f));
|
|
PostFXBlit(DepthOfField1, PostFXTechnique, pp_GaussBlur_Ver);
|
|
|
|
pDOFLargeBlur = DepthOfField1;
|
|
pDOFMedBlur = DepthOfField2;
|
|
}
|
|
|
|
void ProcessHighDOFBuffers(const PostFX::PostFXParamBlock::paramBlock &settings, grcRenderTarget*& pDOFLargeBlur, grcRenderTarget*& pDOFMedBlur, grcRenderTarget*& currExposureRT, float screenBlurFadeLevel)
|
|
{
|
|
PF_AUTO_PUSH_TIMEBAR("ProcessHighDOFBuffers");
|
|
|
|
#if __PS3
|
|
grcEffectVar BloomTexelSizeId = TexelSizeId;
|
|
#endif
|
|
|
|
SetNonDepthFXStateBlocks();
|
|
|
|
#if DOF_TYPE_CHANGEABLE_IN_RAG
|
|
PostFXShader->SetVar(CurrentDOFTechniqueVar, (float)CurrentDOFTechnique);
|
|
#endif
|
|
|
|
Vector4 hiDofParameters = settings.m_hiDofParameters;
|
|
PackHiDofParameters(hiDofParameters);
|
|
|
|
if( PostFX::ExtraEffectsRequireBlur() )
|
|
hiDofParameters.Lerp(screenBlurFadeLevel, Vector4(0.0f, 0.0f, 0.0f, 0.0f));
|
|
|
|
PostFXShader->SetVar(HiDofParamsId, hiDofParameters);
|
|
|
|
#if ADAPTIVE_DOF_GPU
|
|
if( settings.m_AdaptiveDof && CurrentDOFTechnique != dof_console )
|
|
{
|
|
AdaptiveDepthOfField.ProcessAdaptiveDofGPU(settings, currExposureRT, WasAdaptiveDofProcessedOnPreviousUpdate);
|
|
}
|
|
|
|
WasAdaptiveDofProcessedOnPreviousUpdate = settings.m_AdaptiveDof;
|
|
#else
|
|
(void) currExposureRT;
|
|
#endif
|
|
|
|
|
|
#if BOKEH_SUPPORT || DOF_COMPUTE_GAUSSIAN
|
|
if( BokehEnable || CurrentDOFTechnique == dof_computeGaussian )
|
|
{
|
|
ProcessBokehPreDOF(settings, screenBlurFadeLevel);
|
|
}
|
|
#endif //BOKEH_SUPPORT
|
|
|
|
#if DOF_COMPUTE_GAUSSIAN
|
|
#if RSG_PC
|
|
PostFX::SetGaussianBlur();
|
|
#endif // RSG_PC
|
|
|
|
if( CurrentDOFTechnique == dof_computeGaussian )
|
|
{
|
|
#if COC_SPREAD
|
|
dofComputeShader->SetVar(GaussianWeightsBufferVar, &s_GaussianWeightsCOCBuffer);
|
|
COCSpread(DOF_ComputeGridSizeCOC);
|
|
#endif
|
|
|
|
dofComputeShader->SetVar(GaussianWeightsBufferVar, &s_GaussianWeightsBuffer);
|
|
ProcessComputeGaussianDOF(settings, screenBlurFadeLevel);
|
|
|
|
pDOFLargeBlur = DepthOfField2;
|
|
}
|
|
else
|
|
#endif //DOF_COMPUTE_GAUSSIAN
|
|
#if DOF_DIFFUSION
|
|
if( CurrentDOFTechnique == dof_diffusion )
|
|
{
|
|
#if COC_SPREAD
|
|
COCSpread(DOF_ComputeGridSizeCOC);
|
|
#endif
|
|
ProcessDiffusionDOFCS(DepthOfField2);
|
|
pDOFLargeBlur = DepthOfField2;
|
|
}
|
|
else
|
|
#endif //DOF_DIFFUSION
|
|
{
|
|
LastGenDOF(pDOFLargeBlur, pDOFMedBlur);
|
|
}
|
|
|
|
#if DEVICE_MSAA && DOF_COMPUTE_GAUSSIAN
|
|
if (GRCDEVICE.GetMSAA()>1 && (CurrentDOFTechnique == dof_computeGaussian))
|
|
{
|
|
grcDepthStencilStateHandle currentDSS = grcStateBlock::DSS_Active;
|
|
grcBlendStateHandle currentBS = grcStateBlock::BS_Active;
|
|
grcStateBlock::SetDepthStencilState(grcStateBlock::DSS_IgnoreDepth);
|
|
grcStateBlock::SetBlendState(grcStateBlock::BS_Normal);
|
|
|
|
dofComputeShader->SetVar(dofComputeColorTex, pDOFLargeBlur);
|
|
dofComputeShader->SetVar(dofBlendParams, !(DRAWLISTMGR->IsExecutingHudDrawList() || CLoadingScreens::AreActive()));
|
|
CRenderTargets::LockSceneRenderTargets();
|
|
|
|
u32 MSAABlendPass = pp_DOF_ComputeGaussian_MSAA_Blend;
|
|
#if ADAPTIVE_DOF_OUTPUT_UAV
|
|
if( settings.m_AdaptiveDof )
|
|
MSAABlendPass = pp_DOF_ComputeGaussian_MSAA_Blend_Adaptive;
|
|
#endif //ADAPTIVE_DOF_OUTPUT_UAV
|
|
|
|
#if MSAA_EDGE_PASS
|
|
if (DeferredLighting::IsEdgePassActiveForPostfx() && AssertVerify(PostFXShaderMS0) BANK_ONLY(&& (DebugDeferred::m_OptimizeDofBlend & (1<<EM_IGNORE))))
|
|
{
|
|
BANK_ONLY(if (DebugDeferred::m_OptimizeDofBlend & (1<<EM_EDGE0)))
|
|
{
|
|
grcStateBlock::SetDepthStencilState(DeferredLighting::m_directionalEdgeMaskEqualPass_DS, EDGE_FLAG);
|
|
ShaderUtil::StartShader("DoF MSAA Blend (edges)", dofComputeShader, dofComputeTechnique, MSAABlendPass);
|
|
grcDrawSingleQuadf(0.f,0.f,1.f,1.f, 0.0f, 0.0, 0.0, 0.0f, 0.0f, Color32(0));
|
|
ShaderUtil::EndShader(dofComputeShader);
|
|
}
|
|
BANK_ONLY(if (DebugDeferred::m_OptimizeDofBlend & (1<<EM_FACE0)))
|
|
{
|
|
MSAABlendPass += 1;
|
|
grcStateBlock::SetDepthStencilState(DeferredLighting::m_directionalEdgeMaskEqualPass_DS, 0);
|
|
ShaderUtil::StartShader("DoF MSAA Blend (non-edges)", dofComputeShader, dofComputeTechnique, MSAABlendPass);
|
|
grcDrawSingleQuadf(0.f,0.f,1.f,1.f, 0.0f, 0.0, 0.0, 0.0f, 0.0f, Color32(0));
|
|
ShaderUtil::EndShader(dofComputeShader);
|
|
}
|
|
}else
|
|
#endif //MSAA_EDGE_PASS
|
|
{
|
|
ShaderUtil::StartShader("DoF MSAA Blend", dofComputeShader, dofComputeTechnique, MSAABlendPass);
|
|
grcDrawSingleQuadf(0.f,0.f,1.f,1.f, 0.0f, 0.0, 0.0, 0.0f, 0.0f, Color32(0));
|
|
ShaderUtil::EndShader(dofComputeShader);
|
|
}
|
|
|
|
CRenderTargets::UnlockSceneRenderTargets();
|
|
grcStateBlock::SetDepthStencilState(currentDSS);
|
|
grcStateBlock::SetBlendState(currentBS);
|
|
}
|
|
#endif // DEVICE_MSAA && DOF_COMPUTE_GAUSSIAN
|
|
|
|
#if BOKEH_SUPPORT
|
|
if( BokehEnable )
|
|
{
|
|
ProcessBokehPostDOF(settings);
|
|
}
|
|
#endif //BOKEH_SUPPORT
|
|
|
|
}
|
|
|
|
void ProcessHeatHazeBuffers(const PostFX::PostFXParamBlock::paramBlock& settings)
|
|
{
|
|
PF_AUTO_PUSH_TIMEBAR("ProcessHeatHazeBuffers");
|
|
SetNonDepthFXStateBlocks();
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// heat haze pre-pass
|
|
|
|
if (Water::IsCameraUnderwater())
|
|
{
|
|
PostFXShader->SetVar(heatHazeParamsId, settings.m_HeatHazeParams);
|
|
PostFXBlit(HeatHaze0, PostFXTechnique, pp_HeatHazeWater);
|
|
}
|
|
else
|
|
{
|
|
// compute initial intensity mask for heat haze
|
|
const grcTexture *const gbuf1 = GBuffer::GetTarget(GBUFFER_RT_1);
|
|
PostFXShader->SetVar(GBufferTextureId0, gbuf1);
|
|
PostFXShader->SetVar(heatHazeParamsId, settings.m_HeatHazeParams);
|
|
PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/gbuf1->GetWidth(),1.0f/gbuf1->GetHeight(),0.0, 0.0f));
|
|
|
|
|
|
#if POSTFX_TILED_LIGHTING_ENABLED
|
|
if (BANK_SWITCH(PostFX::g_UseTiledTechniques == true, CTiledLighting::IsEnabled()))
|
|
{
|
|
const char* pPassName = NULL;
|
|
#if RAGE_TIMEBARS
|
|
pPassName = passName[pp_HeatHaze_Tiled];
|
|
#endif
|
|
|
|
#if __D3D11 || RSG_ORBIS
|
|
PostFXShader->SetVar(TiledDepthTextureId, CTiledLighting::GetClassificationTexture());
|
|
#endif // __D3D11 || RSG_ORBIS
|
|
|
|
CTiledLighting::RenderTiles(HeatHaze0, PostFXShader, PostFXTechnique, pp_HeatHaze_Tiled, pPassName, true);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
PostFXBlit(HeatHaze0, PostFXTechnique, pp_HeatHaze);
|
|
}
|
|
|
|
// dilate heat haze intensity mask
|
|
PostFXShader->SetVar(TextureID_v0, HeatHaze0);
|
|
PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/float(HeatHaze0->GetWidth()),1.0f/float(HeatHaze0->GetHeight()),0.0, 0.0f));
|
|
PostFXBlit(HeatHaze1, PostFXTechnique, pp_HeatHazeDilateBinary);
|
|
|
|
// 2nd dilation + "fade"
|
|
PostFXShader->SetVar(TextureID_v0, HeatHaze1);
|
|
PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/float(HeatHaze1->GetWidth()),1.0f/float(HeatHaze1->GetHeight()),0.0, 0.0f));
|
|
PostFXBlit(HeatHaze0, PostFXTechnique, pp_HeatHazeDilate);
|
|
|
|
// restore texture
|
|
PostFXShader->SetVar(GBufferTextureId0, GBuffer::GetTarget(GBUFFER_RT_0));
|
|
}
|
|
}
|
|
|
|
|
|
void SimpleBlur(grcRenderTarget* pBlur0, grcRenderTarget* pBlur1)
|
|
{
|
|
SetNonDepthFXStateBlocks();
|
|
|
|
PostFXShader->SetVar(TextureID_0, pBlur0);
|
|
PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/float(pBlur0->GetWidth()),1.0f/float(pBlur0->GetHeight()),0.0, 0.0f));
|
|
#if !__PS3
|
|
PostFXShader->SetVar(BloomTexelSizeId, Vector4(1.0f/float(pBlur0->GetWidth()),1.0f/float(pBlur0->GetHeight()),0.0, 0.0f));
|
|
#endif
|
|
PostFXBlit(pBlur1, PostFXTechnique, pp_Blur);
|
|
|
|
PostFXShader->SetVar(TextureID_0, pBlur1);
|
|
PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/float(pBlur1->GetWidth()),1.0f/float(pBlur1->GetHeight()),0.0, 0.0f));
|
|
#if !__PS3
|
|
PostFXShader->SetVar(BloomTexelSizeId, Vector4(1.0f/float(pBlur1->GetWidth()),1.0f/float(pBlur1->GetHeight()),0.0, 0.0f));
|
|
#endif
|
|
PostFXBlit(pBlur0, PostFXTechnique, pp_Blur);
|
|
}
|
|
|
|
|
|
void PostFX::SetFlashParameters(float UNUSED_PARAM(fMinIntensity), float UNUSED_PARAM(fMaxIntensity), u32 rampUpDuration, u32 holdDuration, u32 rampDownDuration)
|
|
{
|
|
g_defaultFlashEffect.Set(DefaultFlashEffectModName, POSTFX_IN_HOLD_OUT, 0U, rampUpDuration, holdDuration, rampDownDuration);
|
|
g_defaultFlashEffect.Start();
|
|
}
|
|
|
|
void PostFX::UpdatePulseEffect()
|
|
{
|
|
if (g_uPulseStartTime > 0)
|
|
{
|
|
const u32 c_uCurrentTime = fwTimer::GetTimeInMilliseconds_NonScaledClipped();
|
|
float fInterp = 0.0f;
|
|
if (c_uCurrentTime < g_uPulseStartTime + g_uPulseRampUpDuration)
|
|
{
|
|
// Ramping up
|
|
fInterp = (float)(c_uCurrentTime - g_uPulseStartTime) / (float)g_uPulseRampUpDuration;
|
|
}
|
|
else if (c_uCurrentTime < g_uPulseStartTime + g_uPulseRampUpDuration + g_uPulseHoldDuration)
|
|
{
|
|
fInterp = 1.0f;
|
|
}
|
|
else if (c_uCurrentTime < g_uPulseStartTime + g_uPulseRampUpDuration + g_uPulseHoldDuration + g_uPulseRampDownDuration)
|
|
{
|
|
fInterp = (float)(g_uPulseRampDownDuration - (c_uCurrentTime - g_uPulseStartTime - g_uPulseRampUpDuration - g_uPulseHoldDuration)) / (float)g_uPulseRampDownDuration;
|
|
}
|
|
else
|
|
{
|
|
// Done, so disable the flash effect.
|
|
g_uPulseStartTime = 0;
|
|
g_vInitialPulseParams.Zero();
|
|
g_vTargetPulseParams.Zero();
|
|
}
|
|
|
|
PostFXParamBlock::GetUpdateThreadParams().m_distortionParams = Lerp(fInterp, g_vInitialPulseParams, g_vTargetPulseParams);
|
|
}
|
|
}
|
|
|
|
void PostFX::SetPulseParameters(const Vector4& pulseParams, u32 rampUpDuration, u32 holdDuration, u32 rampDownDuration)
|
|
{
|
|
g_vInitialPulseParams.Zero();
|
|
g_vTargetPulseParams = pulseParams;
|
|
|
|
g_uPulseStartTime = fwTimer::GetTimeInMilliseconds_NonScaledClipped();
|
|
g_uPulseRampUpDuration = rampUpDuration;
|
|
g_uPulseHoldDuration = holdDuration;
|
|
g_uPulseRampDownDuration = rampDownDuration;
|
|
}
|
|
|
|
void PostFX::SetMotionBlurPrevMatrixOverride(const Matrix34& UNUSED_PARAM(mat))
|
|
{
|
|
Assertf(0, "PostFX::SetMotionBlurPrevMatrixOverride: not implemented");
|
|
}
|
|
|
|
#if __BANK
|
|
static bool IsTiledScreenCaptureOrPanorama()
|
|
{
|
|
return TiledScreenCapture::IsEnabled() || SceneGeometryCapture::IsCapturingPanorama() || LightProbe::IsCapturingPanorama();
|
|
}
|
|
#endif // __BANK
|
|
|
|
// Is motion blur active?
|
|
bool PostFX::IsMotionBlurEnabled()
|
|
{
|
|
const PostFXParamBlock::paramBlock& rSettings = PostFXParamBlock::GetRenderThreadParams();
|
|
|
|
static dev_bool debugForceMotionBlurON = false;
|
|
static dev_bool debugForceMotionBlurOFF = false;
|
|
|
|
const bool hasMotionBlur = (rSettings.m_directionalBlurLength > 0.0f || debugForceMotionBlurON)
|
|
&& !CPauseMenu::GetPauseRenderPhasesStatus() // do not allow motion blur when rendering is frozen
|
|
&& !debugForceMotionBlurOFF
|
|
&& !g_screenBlurFade.IsPlaying()
|
|
&& (!camInterface::IsRenderedCameraInsideVehicle() || rSettings.m_isForcingMotionBlur)
|
|
#if RSG_PC
|
|
&& (CSettingsManager::GetInstance().GetSettings().m_graphics.m_PostFX >= CSettings::Medium)
|
|
#endif
|
|
#if __BANK
|
|
&& !NoMotionBlur
|
|
&& !TiledScreenCapture::IsEnabled()
|
|
&& !IsTiledScreenCaptureOrPanorama()
|
|
#endif // __BANK
|
|
;
|
|
|
|
return hasMotionBlur;
|
|
}
|
|
|
|
static __forceinline float SmoothStep(float x, float a, float b)
|
|
{
|
|
x = (Clamp<float>(x, a, b) - a)/(b - a);
|
|
return x*x*(3.0f - 2.0f*x);
|
|
}
|
|
|
|
void PostFX::GetFPVPos()
|
|
{
|
|
if (g_fpvMotionBlurEnableDynamicUpdate)
|
|
{
|
|
Vec3V currPos = Vec3V(V_ZERO);
|
|
|
|
CPed* pPed = CGameWorld::FindLocalPlayer();
|
|
|
|
CPedWeaponManager *weaponManager = pPed->GetWeaponManager();
|
|
bool usedWeapon = false;
|
|
if( weaponManager )
|
|
{
|
|
CPedEquippedWeapon* equippedWeapon = weaponManager->GetPedEquippedWeapon();
|
|
if( equippedWeapon )
|
|
{
|
|
CObject *weaponObject = equippedWeapon->GetObject();
|
|
if( weaponObject )
|
|
{
|
|
currPos = weaponObject->GetTransform().GetPosition();
|
|
usedWeapon = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!usedWeapon)
|
|
{
|
|
CPed* pPed = CGameWorld::FindLocalPlayer();
|
|
pPed->GetBonePositionVec3V(currPos, BONETAG_R_HAND);
|
|
}
|
|
|
|
const grcViewport* vp = gVpMan.GetUpdateGameGrcViewport();
|
|
const Mat44V view = vp->GetViewMtx();
|
|
fpvMotionBlurCurrCameraPos = Multiply(view, Vec4V(currPos, ScalarV(V_ONE))).GetXYZ();
|
|
}
|
|
}
|
|
|
|
void PostFX::Update()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_UPDATE));
|
|
const int ub=gRenderThreadInterface.GetUpdateBuffer();
|
|
|
|
LENSARTEFACTSMGR.Update();
|
|
PHONEPHOTOEDITOR.Update();
|
|
PAUSEMENUPOSTFXMGR.Update();
|
|
g_screenBlurFade.Update();
|
|
|
|
#if USE_SCREEN_WATERMARK
|
|
UpdateScreenWatermark();
|
|
#endif
|
|
|
|
#if __BANK
|
|
g_UseTiledTechniques = g_UseTiledTechniques && CTiledLighting::IsEnabled();
|
|
#endif
|
|
|
|
#if __BANK
|
|
if (gFrameCapture || gFrameCaptureSingle)
|
|
{
|
|
CFrameDump::StartCapture(gFrameCapPath, gFrameCapJpeg, gFrameCaptureSingle, gFrameCaptureOnCutsceneStart, gFrameUseCutsceneNameForPath, gFrameCaptureMBSync, gFrameCaptureBinkMode, gFrameCaptureCutsceneMode, gFrameCaptureFPS, &gFrameCapture);
|
|
gFrameCaptureSingle = false;
|
|
}
|
|
|
|
if (!gFrameCapture)
|
|
CFrameDump::StopCapture();
|
|
#endif
|
|
|
|
// light ray switch
|
|
#if __BANK
|
|
if (g_Override==false) //only auto switch when not overridden
|
|
#endif // __BANK
|
|
{
|
|
if ((camInterface::GetPos().z<0.0f || g_lightRaysAboveWaterLine==true) &&
|
|
(Lights::GetUpdateDirectionalLight().GetIntensity()>0.0f)
|
|
#if __BANK
|
|
&& IsTiledScreenCaptureOrPanorama()==false
|
|
#endif // __BANK
|
|
)
|
|
{
|
|
g_enableLightRays=true;
|
|
}
|
|
else
|
|
{
|
|
g_enableLightRays=false;
|
|
}
|
|
}
|
|
|
|
const camFrame& frame = gVpMan.GetCurrentGameViewportFrame();
|
|
|
|
// Motion Blur/noise
|
|
bool gamePaused = fwTimer::IsGamePaused();
|
|
if (!gamePaused REPLAY_ONLY( || (CReplayMgr::IsEditModeActive() && g_UpdateReplayEffectsWhilePaused)))
|
|
{
|
|
NoiseEffectRandomValues.x = (static_cast<float>(rand())/static_cast<float>(RAND_MAX));
|
|
NoiseEffectRandomValues.y = (static_cast<float>(rand())/static_cast<float>(RAND_MAX));
|
|
}
|
|
|
|
if (!gamePaused)
|
|
{
|
|
Mat34V camMtx = RCC_MAT34V(camInterface::GetMat());
|
|
|
|
MotionBlurPrevViewProjMat=MotionBlurCurViewProjMat;
|
|
|
|
Mat44V vProjMat = gVpMan.GetUpdateGameGrcViewport()->GetCompositeMtx();
|
|
MotionBlurCurViewProjMat = RCC_MATRIX44(vProjMat);
|
|
|
|
// Check for extreme camera orientation change or camera cuts
|
|
bool hasCut = frame.GetFlags().IsFlagSet(camFrame::Flag_HasCutPosition) || frame.GetFlags().IsFlagSet(camFrame::Flag_HasCutOrientation);
|
|
|
|
float cosAng= Dot(MotionBlurPreviousCameraDir, camMtx.b()).Getf();
|
|
if (cosAng<0.0f || (hasCut && !g_motionBlurCutTestDisabled) )
|
|
{
|
|
MotionBlurPrevViewProjMat=MotionBlurCurViewProjMat;
|
|
}
|
|
MotionBlurPreviousCameraDir = camMtx.b();
|
|
|
|
MotionBlurPrevViewProjMatrix[ub]=MotionBlurPrevViewProjMat;
|
|
MotionBlurBufferedPrevViewProjMat=MotionBlurPrevViewProjMatrix[ub];
|
|
}
|
|
else
|
|
{
|
|
MotionBlurPrevViewProjMatrix[ub]=MotionBlurBufferedPrevViewProjMat;
|
|
}
|
|
|
|
PostFXParamBlock::paramBlock& settings = PostFXParamBlock::GetUpdateThreadParams();
|
|
|
|
#if __BANK
|
|
if (g_Override==false)
|
|
#endif // __BANK
|
|
{
|
|
const tcKeyframeUncompressed& currKeyframe = g_timeCycle.GetCurrUpdateKeyframe();
|
|
|
|
Vector3 currLightrayCol(currKeyframe.GetVar(TCVAR_LIGHT_RAY_COL_R), currKeyframe.GetVar(TCVAR_LIGHT_RAY_COL_G), currKeyframe.GetVar(TCVAR_LIGHT_RAY_COL_B));
|
|
Vector4 currLightrayParams;
|
|
|
|
bool useUnderwater = Water::IsCameraUnderwater();
|
|
|
|
if ( useUnderwater )
|
|
{
|
|
currLightrayParams=Vector4(currLightrayCol.x*currKeyframe.GetVar(TCVAR_LIGHT_RAY_UNDERWATER_MULT), currLightrayCol.y*currKeyframe.GetVar(TCVAR_LIGHT_RAY_UNDERWATER_MULT), currLightrayCol.z*currKeyframe.GetVar(TCVAR_LIGHT_RAY_UNDERWATER_MULT), currKeyframe.GetVar(TCVAR_LIGHT_RAY_DIST) );
|
|
}
|
|
else
|
|
{
|
|
// compute fogray density based on height falloff start and height falloff
|
|
const grcViewport *viewport = gVpMan.GetUpdateGameGrcViewport();
|
|
float lightrayDensityMult = 1.0f;
|
|
if (viewport)
|
|
{
|
|
const float fullDist = viewport->GetCameraMtx().GetM23f() ;
|
|
float dist = Max(0.0f, fullDist - currKeyframe.GetVar(TCVAR_LIGHT_RAY_HEIGHTFALLOFFSTART));
|
|
float deltaDist = fullDist * (dist/fullDist);
|
|
float t = deltaDist * (currKeyframe.GetVar(TCVAR_LIGHT_RAY_HEIGHTFALLOFF) / 1000.0f);
|
|
lightrayDensityMult = (Abs(deltaDist) > 0.01f) ? (1.0f - exp(-t)) / t : 1.0f;
|
|
}
|
|
|
|
currLightrayParams=Vector4(currLightrayCol.x*currKeyframe.GetVar(TCVAR_LIGHT_RAY_MULT)*lightrayDensityMult, currLightrayCol.y*currKeyframe.GetVar(TCVAR_LIGHT_RAY_MULT), currLightrayCol.z*currKeyframe.GetVar(TCVAR_LIGHT_RAY_MULT), currKeyframe.GetVar(TCVAR_LIGHT_RAY_DIST) );
|
|
}
|
|
Vector4 currSSLRParams(currKeyframe.GetVar(TCVAR_LIGHT_RAY_ADD_REDUCER),currKeyframe.GetVar(TCVAR_LIGHT_RAY_BLIT_SIZE),currKeyframe.GetVar(TCVAR_LIGHT_RAY_RAY_LENGTH),0.0f);
|
|
|
|
bool bSniperSightActive = g_sniperSightDefaultEnabled && CNewHud::IsSniperSightActive();
|
|
|
|
// reset sniper sight DOF params
|
|
settings.m_sniperSightActive = bSniperSightActive;
|
|
settings.m_sniperSightDOFParams = g_sniperSightDefaultDOFParams;
|
|
|
|
// check if an override is active
|
|
if (bSniperSightActive && g_sniperSightOverrideEnabled)
|
|
{
|
|
settings.m_sniperSightActive = !g_sniperSightOverrideDisableDOF;
|
|
settings.m_sniperSightDOFParams = g_sniperSightOverrideDOFParams;
|
|
}
|
|
|
|
settings.m_HighDofScriptOverrideToggle = g_scriptHighDOFOverrideToggle;
|
|
settings.m_HighDofScriptOverrideEnableDOF = g_scriptHighDOFOverrideEnableDOF;
|
|
settings.m_hiDofScriptParameters = g_scriptHighDOFOverrideParams;
|
|
|
|
// Setup tonemap settings
|
|
Vector4 darkTonemapParams0 = Vector4(
|
|
GetTonemapParam(TONEMAP_FILMIC_A_DARK),
|
|
GetTonemapParam(TONEMAP_FILMIC_B_DARK),
|
|
GetTonemapParam(TONEMAP_FILMIC_C_DARK),
|
|
GetTonemapParam(TONEMAP_FILMIC_D_DARK));
|
|
Vector4 darkTonemapParams1 = Vector4(
|
|
GetTonemapParam(TONEMAP_FILMIC_E_DARK),
|
|
GetTonemapParam(TONEMAP_FILMIC_F_DARK),
|
|
GetTonemapParam(TONEMAP_FILMIC_W_DARK),
|
|
0.0f);
|
|
float darkExposure = GetTonemapParam(TONEMAP_FILMIC_EXPOSURE_DARK);
|
|
|
|
Vector4 brightTonemapParams0 = Vector4(
|
|
GetTonemapParam(TONEMAP_FILMIC_A_BRIGHT),
|
|
GetTonemapParam(TONEMAP_FILMIC_B_BRIGHT),
|
|
GetTonemapParam(TONEMAP_FILMIC_C_BRIGHT),
|
|
GetTonemapParam(TONEMAP_FILMIC_D_BRIGHT));
|
|
Vector4 brightTonemapParams1 = Vector4(
|
|
GetTonemapParam(TONEMAP_FILMIC_E_BRIGHT),
|
|
GetTonemapParam(TONEMAP_FILMIC_F_BRIGHT),
|
|
GetTonemapParam(TONEMAP_FILMIC_W_BRIGHT),
|
|
0.0f);
|
|
float brightExposure = GetTonemapParam(TONEMAP_FILMIC_EXPOSURE_BRIGHT);
|
|
|
|
const bool darkOverriden = (currKeyframe.GetVar(TCVAR_POSTFX_TONEMAP_FILMIC_OVERRIDE_DARK) > 0.0f);
|
|
const bool brightOverriden = (currKeyframe.GetVar(TCVAR_POSTFX_TONEMAP_FILMIC_OVERRIDE_BRIGHT) > 0.0f);
|
|
|
|
if (darkOverriden || brightOverriden)
|
|
{
|
|
darkTonemapParams0 = Vector4(
|
|
currKeyframe.GetVar(TCVAR_POSTFX_TONEMAP_FILMIC_A_DARK),
|
|
currKeyframe.GetVar(TCVAR_POSTFX_TONEMAP_FILMIC_B_DARK),
|
|
currKeyframe.GetVar(TCVAR_POSTFX_TONEMAP_FILMIC_C_DARK),
|
|
currKeyframe.GetVar(TCVAR_POSTFX_TONEMAP_FILMIC_D_DARK));
|
|
|
|
darkTonemapParams1 = Vector4(
|
|
currKeyframe.GetVar(TCVAR_POSTFX_TONEMAP_FILMIC_E_DARK),
|
|
currKeyframe.GetVar(TCVAR_POSTFX_TONEMAP_FILMIC_F_DARK),
|
|
currKeyframe.GetVar(TCVAR_POSTFX_TONEMAP_FILMIC_W_DARK),
|
|
0.0f);
|
|
|
|
darkExposure = currKeyframe.GetVar(TCVAR_POSTFX_TONEMAP_FILMIC_EXPOSURE_DARK);
|
|
|
|
if (darkOverriden && !brightOverriden)
|
|
{
|
|
brightTonemapParams0 = darkTonemapParams0;
|
|
brightTonemapParams1 = darkTonemapParams1;
|
|
brightExposure = darkExposure;
|
|
}
|
|
|
|
if (!darkOverriden && brightOverriden)
|
|
{
|
|
Assertf(false, "Only bright TM settings were overrwitten instead of both dark and bright");
|
|
}
|
|
|
|
if (darkOverriden && brightOverriden)
|
|
{
|
|
brightTonemapParams0 = Vector4(
|
|
currKeyframe.GetVar(TCVAR_POSTFX_TONEMAP_FILMIC_A_BRIGHT),
|
|
currKeyframe.GetVar(TCVAR_POSTFX_TONEMAP_FILMIC_B_BRIGHT),
|
|
currKeyframe.GetVar(TCVAR_POSTFX_TONEMAP_FILMIC_C_BRIGHT),
|
|
currKeyframe.GetVar(TCVAR_POSTFX_TONEMAP_FILMIC_D_BRIGHT));
|
|
|
|
brightTonemapParams1 = Vector4(
|
|
currKeyframe.GetVar(TCVAR_POSTFX_TONEMAP_FILMIC_E_BRIGHT),
|
|
currKeyframe.GetVar(TCVAR_POSTFX_TONEMAP_FILMIC_F_BRIGHT),
|
|
currKeyframe.GetVar(TCVAR_POSTFX_TONEMAP_FILMIC_W_BRIGHT),
|
|
0.0f);
|
|
|
|
brightExposure = currKeyframe.GetVar(TCVAR_POSTFX_TONEMAP_FILMIC_EXPOSURE_BRIGHT);
|
|
|
|
Assertf(darkExposure > brightExposure, "Dark exposure (%f) needs to be greater than Bright Exposure (%f) when overriding TM", darkExposure, brightExposure);
|
|
}
|
|
}
|
|
|
|
// Blend between dark and bright
|
|
const float currentExposure = PostFX::GetUpdateExposure();
|
|
float range = (darkExposure == brightExposure) ? 1.0f : (darkExposure - brightExposure);
|
|
const float t = Saturate((currentExposure - brightExposure) / range);
|
|
|
|
settings.m_filmicParams[0].Set(Lerp(t, brightTonemapParams0, darkTonemapParams0));
|
|
settings.m_filmicParams[1].Set(Lerp(t, brightTonemapParams1, darkTonemapParams1));
|
|
|
|
settings.m_tonemapParams.x = 1.0f / range;
|
|
settings.m_tonemapParams.y = -brightExposure / range;
|
|
|
|
settings.m_brightTonemapParams[0].Set(brightTonemapParams0);
|
|
settings.m_brightTonemapParams[1].Set(brightTonemapParams1);
|
|
|
|
settings.m_darkTonemapParams[0].Set(darkTonemapParams0);
|
|
settings.m_darkTonemapParams[1].Set(darkTonemapParams1);
|
|
|
|
// Color Correction
|
|
settings.m_colorCorrect.Set(Vector4(
|
|
currKeyframe.GetVar(TCVAR_POSTFX_CORRECT_COL_R),
|
|
currKeyframe.GetVar(TCVAR_POSTFX_CORRECT_COL_G),
|
|
currKeyframe.GetVar(TCVAR_POSTFX_CORRECT_COL_B),
|
|
currKeyframe.GetVar(TCVAR_POSTFX_CORRECT_CUTOFF)));
|
|
settings.m_colorShift.Set(Vector4(
|
|
currKeyframe.GetVar(TCVAR_POSTFX_SHIFT_COL_R),
|
|
currKeyframe.GetVar(TCVAR_POSTFX_SHIFT_COL_G),
|
|
currKeyframe.GetVar(TCVAR_POSTFX_SHIFT_COL_B),
|
|
currKeyframe.GetVar(TCVAR_POSTFX_SHIFT_CUTOFF)));
|
|
settings.m_deSaturate = currKeyframe.GetVar(TCVAR_POSTFX_DESATURATION);
|
|
|
|
// Adjust for the front-end
|
|
const bool useDefaultGamma = (CPhotoManager::IsProcessingScreenshot()
|
|
VIDEO_RECORDING_ENABLED_ONLY ( || ( VideoRecording::IsRecording() && !CReplayCoordinator::ShouldShowLoadingScreen() ) ) );
|
|
|
|
settings.m_gamma = useDefaultGamma ? (1.0f / 2.2f) : (1.0f / g_gammaFrontEnd);
|
|
|
|
#if __BANK
|
|
if (CDebug::IsTakingScreenshot() ||
|
|
CSystem::GetRageSetup()->IsTakingScreenshot() ||
|
|
CBugstarIntegration::IsTakingScreenshot())
|
|
settings.m_gamma = 1.0f / 2.2f;
|
|
#endif
|
|
|
|
// HDR
|
|
settings.m_bloomThresholdMax = currKeyframe.GetVar(TCVAR_POSTFX_BRIGHT_PASS_THRESH);
|
|
settings.m_bloomThresholdWidth = currKeyframe.GetVar(TCVAR_POSTFX_BRIGHT_PASS_THRESH_WIDTH);
|
|
settings.m_bloomIntensity = currKeyframe.GetVar(TCVAR_POSTFX_INTENSITY_BLOOM);
|
|
settings.m_exposureTweak = currKeyframe.GetVar(TCVAR_POSTFX_EXPOSURE);
|
|
settings.m_exposureMin = currKeyframe.GetVar(TCVAR_POSTFX_EXPOSURE_MIN);
|
|
settings.m_exposureMax = currKeyframe.GetVar(TCVAR_POSTFX_EXPOSURE_MAX);
|
|
|
|
// Night Vision
|
|
settings.m_lowLum = currKeyframe.GetVar(TCVAR_NV_LOWLUM);
|
|
settings.m_highLum = currKeyframe.GetVar(TCVAR_NV_HIGHLUM);
|
|
settings.m_topLum = currKeyframe.GetVar(TCVAR_NV_TOPLUM);
|
|
settings.m_scalerLum = currKeyframe.GetVar(TCVAR_NV_SCALERLUM);
|
|
settings.m_offsetLum = currKeyframe.GetVar(TCVAR_NV_OFFSETLUM);
|
|
settings.m_offsetLowLum = currKeyframe.GetVar(TCVAR_NV_OFFSETLOWLUM);
|
|
settings.m_offsetHighLum = currKeyframe.GetVar(TCVAR_NV_OFFSETHIGHLUM);
|
|
settings.m_noiseLum = currKeyframe.GetVar(TCVAR_NV_NOISELUM);
|
|
settings.m_noiseLowLum = currKeyframe.GetVar(TCVAR_NV_NOISELOWLUM);
|
|
settings.m_noiseHighLum = currKeyframe.GetVar(TCVAR_NV_NOISEHIGHLUM);
|
|
settings.m_bloomLum = currKeyframe.GetVar(TCVAR_NV_BLOOMLUM);
|
|
settings.m_colorLum.Set( currKeyframe.GetVar(TCVAR_NV_COLORLUM_R),
|
|
currKeyframe.GetVar(TCVAR_NV_COLORLUM_G),
|
|
currKeyframe.GetVar(TCVAR_NV_COLORLUM_B),0.0f);
|
|
settings.m_colorLowLum.Set( currKeyframe.GetVar(TCVAR_NV_COLORLOWLUM_R),
|
|
currKeyframe.GetVar(TCVAR_NV_COLORLOWLUM_G),
|
|
currKeyframe.GetVar(TCVAR_NV_COLORLOWLUM_B),0.0f);
|
|
settings.m_colorHighLum.Set(currKeyframe.GetVar(TCVAR_NV_COLORHIGHLUM_R),
|
|
currKeyframe.GetVar(TCVAR_NV_COLORHIGHLUM_G),
|
|
currKeyframe.GetVar(TCVAR_NV_COLORHIGHLUM_B),0.0f);
|
|
|
|
// Scanline
|
|
settings.m_scanlineParams.x = currKeyframe.GetVar(TCVAR_POSTFX_SCANLINEINTENSITY);
|
|
settings.m_scanlineParams.y = currKeyframe.GetVar(TCVAR_POSTFX_SCANLINE_FREQUENCY_0);
|
|
settings.m_scanlineParams.z = currKeyframe.GetVar(TCVAR_POSTFX_SCANLINE_FREQUENCY_1);
|
|
settings.m_scanlineParams.w = currKeyframe.GetVar(TCVAR_POSTFX_SCANLINE_SPEED);
|
|
|
|
// Heat Haze
|
|
settings.m_HeatHazeParams.x = currKeyframe.GetVar(TCVAR_HH_RANGESTART); // Start range
|
|
settings.m_HeatHazeParams.y = currKeyframe.GetVar(TCVAR_HH_RANGEEND); // Far range
|
|
settings.m_HeatHazeParams.z = currKeyframe.GetVar(TCVAR_HH_MININTENSITY); // Min Intensity
|
|
settings.m_HeatHazeParams.w = currKeyframe.GetVar(TCVAR_HH_MAXINTENSITY); // Max Intensity
|
|
settings.m_HeatHazeOffsetParams.x = currKeyframe.GetVar(TCVAR_HH_DISPU); // Displacement Scale U
|
|
settings.m_HeatHazeOffsetParams.y = currKeyframe.GetVar(TCVAR_HH_DISPV); // Displacement Scale V
|
|
settings.m_HeatHazeTex1Params.x = currKeyframe.GetVar(TCVAR_HH_TEX1_USCALE); // Tex1 U scale
|
|
settings.m_HeatHazeTex1Params.y = currKeyframe.GetVar(TCVAR_HH_TEX1_VSCALE); // Tex1 V scale
|
|
settings.m_HeatHazeTex1Params.z = currKeyframe.GetVar(TCVAR_HH_TEX1_UOFFSET); // Tex1 U offset
|
|
settings.m_HeatHazeTex1Params.w = currKeyframe.GetVar(TCVAR_HH_TEX1_VOFFSET); // Tex1 V offset
|
|
settings.m_HeatHazeTex2Params.x = currKeyframe.GetVar(TCVAR_HH_TEX2_USCALE); // Tex2 U scale
|
|
settings.m_HeatHazeTex2Params.y = currKeyframe.GetVar(TCVAR_HH_TEX2_VSCALE); // Tex2 V scale
|
|
settings.m_HeatHazeTex2Params.z = currKeyframe.GetVar(TCVAR_HH_TEX2_UOFFSET); // Tex2 U offset
|
|
settings.m_HeatHazeTex2Params.w = currKeyframe.GetVar(TCVAR_HH_TEX2_VOFFSET); // Tex2 V offset
|
|
settings.m_HeatHazeTex1Anim.x = currKeyframe.GetVar(TCVAR_HH_TEX1_OFFSET); // Tex1 U Frequency offset
|
|
settings.m_HeatHazeTex1Anim.y = currKeyframe.GetVar(TCVAR_HH_TEX1_FREQUENCY); // Tex1 U Frequency
|
|
settings.m_HeatHazeTex1Anim.z = currKeyframe.GetVar(TCVAR_HH_TEX1_AMPLITUDE); // Tex1 U Amplitude
|
|
settings.m_HeatHazeTex1Anim.w = currKeyframe.GetVar(TCVAR_HH_TEX1_SCROLLING); // Tex1 V Scrolling speed
|
|
settings.m_HeatHazeTex2Anim.x = currKeyframe.GetVar(TCVAR_HH_TEX2_OFFSET); // Tex2 U Frequency offset
|
|
settings.m_HeatHazeTex2Anim.y = currKeyframe.GetVar(TCVAR_HH_TEX2_FREQUENCY); // Tex2 U Frequency
|
|
settings.m_HeatHazeTex2Anim.z = currKeyframe.GetVar(TCVAR_HH_TEX2_AMPLITUDE); // Tex2 U Amplitude
|
|
settings.m_HeatHazeTex2Anim.w = currKeyframe.GetVar(TCVAR_HH_TEX2_SCROLLING); // Tex2 V Scrolling speed
|
|
|
|
// Noise
|
|
settings.m_noise = currKeyframe.GetVar(TCVAR_POSTFX_NOISE);
|
|
settings.m_noiseSize = currKeyframe.GetVar(TCVAR_POSTFX_NOISE_SIZE);
|
|
|
|
|
|
// Vignetting
|
|
settings.m_vignettingParams.x = currKeyframe.GetVar(TCVAR_POSTFX_VIGNETTING_INTENSITY); // Vignetting Intensity
|
|
settings.m_vignettingParams.y = currKeyframe.GetVar(TCVAR_POSTFX_VIGNETTING_RADIUS); // Vignetting Radius
|
|
settings.m_vignettingParams.z = currKeyframe.GetVar(TCVAR_POSTFX_VIGNETTING_CONTRAST); // Vignetting Contrast
|
|
settings.m_vignettingColour.x = currKeyframe.GetVar(TCVAR_POSTFX_VIGNETTING_COL_R); // Vignetting Colour
|
|
settings.m_vignettingColour.y = currKeyframe.GetVar(TCVAR_POSTFX_VIGNETTING_COL_G); // Vignetting Colour
|
|
settings.m_vignettingColour.z = currKeyframe.GetVar(TCVAR_POSTFX_VIGNETTING_COL_B); // Vignetting Colour
|
|
|
|
// Lens Artefacts
|
|
settings.m_lensArtefactsGlobalMultiplier = currKeyframe.GetVar(TCVAR_LENS_ARTEFACTS_INTENSITY); // Lens Artefacts Global Multiplier
|
|
settings.m_lensArtefactsMinExposureMultiplier = currKeyframe.GetVar(TCVAR_LENS_ARTEFACTS_INTENSITY_MIN_EXP); // Lens Artefacts Exposure Based Min Multiplier
|
|
settings.m_lensArtefactsMaxExposureMultiplier = currKeyframe.GetVar(TCVAR_LENS_ARTEFACTS_INTENSITY_MAX_EXP); // Lens Artefacts Exposure Based Max Multiplier
|
|
|
|
#if __BANK
|
|
if(CutSceneManager::GetInstance()->IsPlaying() && CutSceneManager::GetInstance()->IsIsolating())
|
|
{
|
|
settings.m_bloomIntensity = 0.0f;
|
|
settings.m_lensArtefactsGlobalMultiplier = 0.0f;
|
|
settings.m_HighDofScriptOverrideEnableDOF = false;
|
|
}
|
|
#endif
|
|
|
|
// Colour gradient
|
|
const float midPoint = currKeyframe.GetVar(TCVAR_POSTFX_GRAD_MIDPOINT);
|
|
const float topMiddleMidPoint = currKeyframe.GetVar(TCVAR_POSTFX_GRAD_TOP_MIDDLE_MIDPOINT);
|
|
const float middleBottomMidPoint = currKeyframe.GetVar(TCVAR_POSTFX_GRAD_MIDDLE_BOTTOM_MIDPOINT);
|
|
|
|
settings.m_lensGradientColTop.Set(currKeyframe.GetVar(TCVAR_POSTFX_GRAD_TOP_COL_R), // Gradient Top Colour Red
|
|
currKeyframe.GetVar(TCVAR_POSTFX_GRAD_TOP_COL_G), // Gradient Top Colour Green
|
|
currKeyframe.GetVar(TCVAR_POSTFX_GRAD_TOP_COL_B), // Gradient Top Colour Blue
|
|
topMiddleMidPoint); // Gradient Top-Middle Midpoint
|
|
|
|
settings.m_lensGradientColMiddle.Set(currKeyframe.GetVar(TCVAR_POSTFX_GRAD_MIDDLE_COL_R), // Gradient Middle Colour Red
|
|
currKeyframe.GetVar(TCVAR_POSTFX_GRAD_MIDDLE_COL_G), // Gradient Middle Colour Green
|
|
currKeyframe.GetVar(TCVAR_POSTFX_GRAD_MIDDLE_COL_B), // Gradient Middle Colour Blue
|
|
midPoint); // Gradient Middle Colour Position
|
|
|
|
|
|
settings.m_lensGradientColBottom.Set(currKeyframe.GetVar(TCVAR_POSTFX_GRAD_BOTTOM_COL_R), // Gradient Bottom Colour Red
|
|
currKeyframe.GetVar(TCVAR_POSTFX_GRAD_BOTTOM_COL_G), // Gradient Bottom Colour Green
|
|
currKeyframe.GetVar(TCVAR_POSTFX_GRAD_BOTTOM_COL_B), // Gradient Bottom Colour Blue
|
|
middleBottomMidPoint); // Gradient Middle-Bottom Midpoint
|
|
|
|
if(g_timeCycle.GetLightningOverrideUpdate())
|
|
{
|
|
settings.m_SunDirection = RCC_VECTOR3(g_timeCycle.GetLightningDirectionUpdate());
|
|
}
|
|
else
|
|
{
|
|
settings.m_SunDirection = RCC_VECTOR3(g_timeCycle.GetSunSpriteDirection());
|
|
}
|
|
|
|
float lightrayIntensity = currLightrayParams.x + currLightrayParams.y + currLightrayParams.z; // not real intesity, but used as a threshold
|
|
|
|
settings.m_lightRaysActive = (true == g_enableLightRays) && (lightrayIntensity >0.0f) && (false == g_enableNightVision);
|
|
|
|
if (settings.m_lightRaysActive && !useUnderwater)
|
|
{
|
|
// adjust sslr when in sniper scope mode, since the it pops when the horizon touches the top of the screen if the sun is offscreen.
|
|
// also disable sslr when the sun is behind the camera, since it does nothing then anyway
|
|
if (const grcViewport * vp = gVpMan.GetUpdateGameGrcViewport())
|
|
{
|
|
float sslrAlpha = 1.0f;
|
|
Vec3V sunInView = Multiply(vp->GetViewMtx(),Vec4V(VECTOR3_TO_VEC3V(settings.m_SunDirection),ScalarV(V_ZERO))).GetXYZ();
|
|
|
|
if (IsLessThanAll(sunInView.GetZ(),ScalarV(V_ZERO)))
|
|
{
|
|
bool enableFade = g_fadeSSLROffscreen;
|
|
float scale = 1.0f/g_fadeSSLROffscreenValue;
|
|
|
|
if (!enableFade) // if not forcing it, check for sniper mode
|
|
{
|
|
// the sun is in front of the camera, see if we're in sniper mode
|
|
const camBaseCamera* activeCamera = camInterface::GetDominantRenderedCamera();
|
|
if (activeCamera && activeCamera->GetIsClassId(camAimCamera::GetStaticClassId()))
|
|
{
|
|
if (const camControlHelper *helper = static_cast<const camAimCamera*>(activeCamera)->GetControlHelper())
|
|
{
|
|
if (helper->IsUsingZoomInput()) // for sniper mode only: fade off as the sun get near the edge of the screen
|
|
{
|
|
enableFade = true;
|
|
scale = 1.0f;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (enableFade)
|
|
{
|
|
sunInView /= Vec3V(ScalarV(vp->GetTanHFOV()), ScalarV(vp->GetTanVFOV()), ScalarV(V_ONE)) * sunInView.GetZ(); // normalize to view volume
|
|
sslrAlpha = Min(1.0f,scale*Max(Abs(sunInView.GetXf()),Abs(sunInView.GetYf())));
|
|
sslrAlpha = 1-sslrAlpha*sslrAlpha*sslrAlpha;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// the sun is behind the camera, so we can skip the sslr work altogether
|
|
sslrAlpha = 0.0f;
|
|
}
|
|
|
|
if (sslrAlpha*lightrayIntensity <= 0.00f) // if the adjusted amount is less than the threshold, just turn them off.
|
|
settings.m_lightRaysActive = false;
|
|
else
|
|
currLightrayParams *= Vector4(sslrAlpha,sslrAlpha,sslrAlpha,1.0f);
|
|
}
|
|
}
|
|
|
|
settings.m_lightrayParams.Set(currLightrayParams);
|
|
settings.m_sslrParams.Set(currSSLRParams);
|
|
|
|
#if __BANK
|
|
settings.m_nightVision = g_enableNightVision != g_overrideNightVision;
|
|
#else
|
|
settings.m_nightVision = g_enableNightVision;
|
|
#endif // __BANK
|
|
|
|
// Don't allow effect to render if the game is paused, since we don't have depth/stencil
|
|
settings.m_seeThrough = RenderPhaseSeeThrough::GetState() && (CPauseMenu::GetPauseRenderPhasesStatus() == false);
|
|
|
|
settings.m_SeeThroughDepthParams = Vector4( RenderPhaseSeeThrough::GetFadeStartDistance(),
|
|
RenderPhaseSeeThrough::GetFadeEndDistance(),
|
|
RenderPhaseSeeThrough::GetMaxThickness(),
|
|
1.0f);
|
|
|
|
settings.m_SeeThroughParams = Vector4( RenderPhaseSeeThrough::GetMinNoiseAmount(),
|
|
RenderPhaseSeeThrough::GetMaxNoiseAmount(),
|
|
RenderPhaseSeeThrough::GetHiLightIntensity(),
|
|
RenderPhaseSeeThrough::GetHiLightNoise() );
|
|
|
|
settings.m_SeeThroughColorNear = VEC4V_TO_VECTOR4(RenderPhaseSeeThrough::GetColorNear().GetRGBA());
|
|
settings.m_SeeThroughColorFar = VEC4V_TO_VECTOR4(RenderPhaseSeeThrough::GetColorFar().GetRGBA());
|
|
settings.m_SeeThroughColorVisibleBase = VEC4V_TO_VECTOR4(RenderPhaseSeeThrough::GetColorVisibleBase().GetRGBA());
|
|
settings.m_SeeThroughColorVisibleWarm = VEC4V_TO_VECTOR4(RenderPhaseSeeThrough::GetColorVisibleWarm().GetRGBA());
|
|
settings.m_SeeThroughColorVisibleHot = VEC4V_TO_VECTOR4(RenderPhaseSeeThrough::GetColorVisibleHot().GetRGBA());
|
|
|
|
// Distortion
|
|
settings.m_distortionParams.Set(currKeyframe.GetVar(TCVAR_LENS_DISTORTION_COEFF),
|
|
currKeyframe.GetVar(TCVAR_LENS_DISTORTION_CUBE_COEFF),
|
|
currKeyframe.GetVar(TCVAR_LENS_CHROMATIC_ABERRATION_COEFF),
|
|
currKeyframe.GetVar(TCVAR_LENS_CHROMATIC_ABERRATION_CUBE_COEFF));
|
|
|
|
// Blur Vignetting
|
|
settings.m_blurVignettingParams.Set(currKeyframe.GetVar(TCVAR_BLUR_VIGNETTING_INTENSITY),
|
|
currKeyframe.GetVar(TCVAR_BLUR_VIGNETTING_RADIUS),
|
|
0.0f,
|
|
0.0f);
|
|
|
|
// Screen Blur
|
|
settings.m_screenBlurFade = currKeyframe.GetVar(TCVAR_SCREEN_BLUR_INTENSITY);
|
|
|
|
// Allow the camera system to push the screen blur
|
|
const float fullScreenBlurBlendLevelForCamera = frame.GetDofFullScreenBlurBlendLevel();
|
|
settings.m_screenBlurFade = Lerp(fullScreenBlurBlendLevelForCamera, settings.m_screenBlurFade, 1.0f);
|
|
|
|
// Damage Overlay
|
|
settings.m_damageOverlayMisc.Zero();
|
|
settings.m_damageEnabled[0] = false;
|
|
settings.m_damageEnabled[1] = false;
|
|
settings.m_damageEnabled[2] = false;
|
|
settings.m_damageEnabled[3] = false;
|
|
settings.m_drawDamageOverlayAfterHud = false;
|
|
settings.m_damageFiringPos[0].Zero();
|
|
settings.m_damageFiringPos[1].Zero();
|
|
settings.m_damageFiringPos[2].Zero();
|
|
settings.m_damageFiringPos[3].Zero();
|
|
settings.m_damagePlayerPos.Zero();
|
|
|
|
// Exposure adjusts
|
|
settings.m_exposurePush = 0.0f;
|
|
settings.m_averageTimestep = 1.0f;
|
|
|
|
// Adaption for colour compression
|
|
if (g_useAutoColourCompression)
|
|
{
|
|
const float invExposure = pow(2.0f, -g_adaptation.GetUpdateExposure());
|
|
g_adaptation.SetUpdatePackScalar(invExposure * settings.m_filmicParams[1].z);
|
|
}
|
|
|
|
// Cutscene specific overrides
|
|
CutSceneManager* csMgr = CutSceneManager::GetInstance();
|
|
Assert(csMgr);
|
|
|
|
if(csMgr->IsCutscenePlayingBack())
|
|
{
|
|
const CCutSceneCameraEntity* cam = csMgr->GetCamEntity();
|
|
if( cam )
|
|
{
|
|
settings.m_exposurePush = cam->GetExposurePush();
|
|
}
|
|
}
|
|
|
|
#if __BANK
|
|
if (g_DebugBulletImpactUseCursorPos && CDebugScene::GetMouseLeftPressed())
|
|
{
|
|
g_DebugBulletImpactTrigger = true;
|
|
}
|
|
|
|
if (g_DebugBulletImpactTrigger)
|
|
{
|
|
if (g_DebugBulletImpactUseCursorPos)
|
|
{
|
|
if (CDebugScene::GetMouseLeftReleased())
|
|
{
|
|
Vector3 worldPos;
|
|
CDebugScene::GetWorldPositionUnderMouse(worldPos);
|
|
g_bulletImpactOverlay.RegisterBulletImpact(worldPos, 1.0f, g_DebugBulletImpactUseEnduranceIndicator);
|
|
g_DebugBulletImpactTrigger = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
g_bulletImpactOverlay.RegisterBulletImpact(g_DebugBulletImpactPos, 1.0f, g_DebugBulletImpactUseEnduranceIndicator);
|
|
g_DebugBulletImpactTrigger = false;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
settings.m_BokehBrightnessThresholdMax = currKeyframe.GetVar(TCVAR_BOKEH_BRIGHTNESS_MAX);
|
|
settings.m_BokehBrightnessThresholdMin = currKeyframe.GetVar(TCVAR_BOKEH_BRIGHTNESS_MIN);
|
|
settings.m_BokehBrightnessFadeThresholdMax = currKeyframe.GetVar(TCVAR_BOKEH_FADE_MAX);
|
|
settings.m_BokehBrightnessFadeThresholdMin = currKeyframe.GetVar(TCVAR_BOKEH_FADE_MIN);
|
|
|
|
LENSARTEFACTSMGR.SetGlobalIntensity(settings.m_lensArtefactsGlobalMultiplier);
|
|
|
|
g_bulletImpactOverlay.Update();
|
|
g_cutsceneDofTODOverride.Update();
|
|
|
|
// Don't update certain parameters when render phases are paused
|
|
if (CPauseMenu::GetPauseRenderPhasesStatus())
|
|
{
|
|
settings.m_SunDirection = PostFXParamBlock::GetParams(1-ub).m_SunDirection;
|
|
settings.m_lightRaysActive = PostFXParamBlock::GetParams(1-ub).m_lightRaysActive;
|
|
settings.m_lightrayParams = PostFXParamBlock::GetParams(1-ub).m_lightrayParams;
|
|
settings.m_sslrParams = PostFXParamBlock::GetParams(1-ub).m_sslrParams;
|
|
}
|
|
}
|
|
|
|
// If we have a camera cut / adaption reset, reset the exposure next frame
|
|
const camBaseCamera* activeCamera = camInterface::GetDominantRenderedCamera();
|
|
|
|
if (activeCamera &&
|
|
((camInterface::GetFrame().GetFlags() & (camFrame::Flag_HasCutPosition | camFrame::Flag_HasCutOrientation)) > 0))
|
|
{
|
|
g_resetAdaptedLumCount = NUM_RESET_FRAMES;
|
|
}
|
|
|
|
if (g_PlayerSwitch.IsActive())
|
|
{
|
|
g_resetAdaptedLumCount = NUM_RESET_FRAMES;
|
|
}
|
|
|
|
// Reset array if needed
|
|
if (g_historyArray.GetCapacity() != settings.m_adaptionNumFramesAvg)
|
|
{
|
|
g_historyArray.Reset();
|
|
g_historyArray.Resize(settings.m_adaptionNumFramesAvg);
|
|
g_historyIndex = 0;
|
|
g_historySize = 0;
|
|
}
|
|
|
|
settings.m_isCameraCut = false;
|
|
settings.m_justUseCalculated = false;
|
|
|
|
bool resetRequired = (g_resetAdaptedLumCount > 0);
|
|
|
|
#if RSG_PC
|
|
if (GRCDEVICE.UsingMultipleGPUs())
|
|
{
|
|
g_setExposureToTarget = true;
|
|
}
|
|
#endif
|
|
|
|
if (resetRequired)
|
|
{
|
|
PF_SET(CalculationType, 0);
|
|
|
|
g_historyIndex = 0;
|
|
g_historySize = 0;
|
|
|
|
settings.m_isCameraCut = true;
|
|
settings.m_nextHistoryIndex = 0.0f;
|
|
settings.m_historySize = 0.0f;
|
|
|
|
settings.m_averageExposure = 0.0f;
|
|
settings.m_averageTimestep = 1.0f;
|
|
}
|
|
else if (g_setExposureToTarget)
|
|
{
|
|
settings.m_averageExposure = 0.0f;
|
|
settings.m_averageTimestep = 1.0f;
|
|
}
|
|
else
|
|
{
|
|
PF_SET(CalculationType, 1);
|
|
|
|
float timeStep = fwTimer::GetTimeStep();
|
|
|
|
// Update history
|
|
settings.m_nextHistoryIndex = g_historyIndex;
|
|
|
|
if (!CPauseMenu::GetPauseRenderPhasesStatus())
|
|
{
|
|
g_historyArray[g_historyIndex].exposure = g_adaptation.GetUpdateExposure();
|
|
g_historyArray[g_historyIndex].luminance = g_adaptation.GetUpdateLum();
|
|
g_historyArray[g_historyIndex].timestep = timeStep;
|
|
g_historyIndex++;
|
|
|
|
g_historySize = rage::Max(g_historySize, g_historyIndex);
|
|
g_historyIndex = g_historyIndex % settings.m_adaptionNumFramesAvg;
|
|
}
|
|
else
|
|
{
|
|
resetRequired = true;
|
|
}
|
|
|
|
settings.m_historySize = g_historySize;
|
|
|
|
// Get avg. exposure and timestep
|
|
float avgExposure = 0.0f;
|
|
float avgTimeStep = 0.0f;
|
|
|
|
for (u32 i = 0; i < g_historySize; i++)
|
|
{
|
|
avgExposure += g_historyArray[i].exposure;
|
|
avgTimeStep += g_historyArray[i].timestep;
|
|
}
|
|
|
|
float historySize = rage::Max((float)g_historySize, 1.0f);
|
|
|
|
settings.m_averageExposure = avgExposure / historySize;
|
|
settings.m_averageTimestep = avgTimeStep / historySize;
|
|
}
|
|
|
|
settings.m_adaptationResetRequired = resetRequired;
|
|
|
|
if (g_resetAdaptedLumCount > 0 && !fwTimer::IsGamePaused())
|
|
{
|
|
g_resetAdaptedLumCount--;
|
|
}
|
|
|
|
// Exposure push when we look at the sun
|
|
if (!resetRequired && g_enableExposureTweak)
|
|
{
|
|
settings.m_exposureTweak +=
|
|
g_sunExposureAdjust *
|
|
g_LensFlare.GetSunVisibility() *
|
|
Saturate(Lights::GetUpdateDirectionalLight().GetIntensity() / 64.0f);
|
|
}
|
|
|
|
#if __BANK
|
|
sprintf(
|
|
adaptionInfoStr,
|
|
"Cur Lum : %.2f, Current Exposure : %.4f, Target Exposure : %.4f, Diff : %.2f",
|
|
g_adaptation.GetUpdateLum(),
|
|
g_adaptation.GetUpdateExposure(),
|
|
g_adaptation.GetUpdateTargetExposure(),
|
|
g_adaptation.GetUpdateTargetExposure() - g_adaptation.GetUpdateExposure());
|
|
|
|
#endif //__BANK
|
|
|
|
PF_SET(UpdateExposure, g_adaptation.GetUpdateExposure());
|
|
PF_SET(Luminance, g_adaptation.GetUpdateLum());
|
|
|
|
g_defaultFlashEffect.Update();
|
|
|
|
#if __BANK
|
|
|
|
if( false == g_Override )
|
|
{
|
|
sysMemCpy(&editedSettings,&settings,sizeof(PostFXParamBlock::paramBlock));
|
|
}
|
|
else
|
|
{
|
|
editedSettings.m_adaptationResetRequired = settings.m_adaptationResetRequired;
|
|
editedSettings.m_averageExposure = settings.m_averageExposure;
|
|
editedSettings.m_averageTimestep = settings.m_averageTimestep;
|
|
editedSettings.m_historySize = settings.m_historySize;
|
|
editedSettings.m_nextHistoryIndex = settings.m_nextHistoryIndex;
|
|
|
|
// Let the LENSARTEFACTSMGR widget drive the intensity multipliers
|
|
editedSettings.m_lensArtefactsGlobalMultiplier = LENSARTEFACTSMGR.GetGlobalIntensity();
|
|
editedSettings.m_lensArtefactsMinExposureMultiplier = LENSARTEFACTSMGR.GetExposureMinForFade();
|
|
editedSettings.m_lensArtefactsMaxExposureMultiplier = LENSARTEFACTSMGR.GetExposureMaxForFade();
|
|
|
|
sysMemCpy(&settings,&editedSettings,sizeof(PostFXParamBlock::paramBlock));
|
|
}
|
|
|
|
if (settings.m_directionalBlurLength>0.0f)
|
|
{
|
|
grcDebugDraw::AddDebugOutput("POSTFX WARNING: Motion Blur is ON!");
|
|
}
|
|
|
|
if( settings.m_HighDof )
|
|
{
|
|
grcDebugDraw::AddDebugOutput("POSTFX WARNING: HQ DOF (%s, %s)",
|
|
settings.m_HighDofForceSmallBlur ? "SB" : "DB",
|
|
settings.m_ShallowDof ? "SD" : "DD" );
|
|
}
|
|
|
|
sprintf(toneMapInfoStr, "Exposure = %.2f | Exposure adjustment = %.2f | Dir intensity = %.2f | Actual maximum = %.2f",
|
|
g_adaptation.GetUpdateExposure(),
|
|
g_adaptation.GetUpdatePowTwoExposure(),
|
|
Lights::GetUpdateDirectionalLight().GetIntensity(),
|
|
Lights::GetUpdateDirectionalLight().GetIntensity() * g_adaptation.GetUpdatePowTwoExposure());
|
|
#endif // __BANK
|
|
|
|
UpdatePulseEffect();
|
|
|
|
float exposure = g_adaptation.GetUpdateExposure();
|
|
float exposureMax = settings.m_exposureMax;
|
|
float exposureMin = settings.m_exposureMin;
|
|
|
|
if(exposureMin == exposureMax)
|
|
{
|
|
exposureMax += 0.0001f; // B*7172555 - PS4: Error: NaN detected in shader parameters! from DL_MIRROR_REFLECTION
|
|
}
|
|
|
|
g_linearExposure = Saturate((exposure - exposureMin)/(exposureMax - exposureMin));
|
|
|
|
// Come up with an average linear exposure value
|
|
float averageExposur = resetRequired ? g_adaptation.GetUpdateExposure() : settings.m_averageExposure;
|
|
g_averageLinearExposure = Saturate((averageExposur - exposureMin)/(exposureMax - exposureMin));
|
|
|
|
settings.m_timeStep = fwTimer::GetTimeStep();
|
|
settings.m_time = (float)fwTimer::GetTimeInMilliseconds();
|
|
|
|
settings.m_AdaptiveDofTimeStep = fwTimer::IsGamePaused() ? 0.0f : fwTimer::GetTimeStep_NonScaledClipped();
|
|
|
|
#if GTA_REPLAY
|
|
if (CReplayMgr::IsEditModeActive())
|
|
{
|
|
settings.m_AdaptiveDofTimeStep = fwTimer::GetTimeStep_NonPausedNonScaledClipped();
|
|
if(fwTimer::IsUserPaused() && g_UpdateReplayEffectsWhilePaused)
|
|
{
|
|
settings.m_timeStep = fwTimer::GetNonPausedTimeStep();
|
|
settings.m_time = (float)fwTimer::GetNonPausedTimeInMilliseconds();
|
|
}
|
|
}
|
|
#endif //GTA_REPLAY
|
|
|
|
// Adjust bloom threshold based on exposure diff so we have more will adaptation is kicking in
|
|
const float exposureDiff = (g_adaptation.GetUpdateTargetExposure() - g_adaptation.GetUpdateExposure());
|
|
if (exposureDiff < 0.0f && g_bloomThresholdExposureDiffMin != g_bloomThresholdExposureDiffMax && !settings.m_adaptationResetRequired)
|
|
{
|
|
float t = 0.0f;
|
|
|
|
if (g_bloomThresholdExposureDiffMin >= g_bloomThresholdExposureDiffMax)
|
|
{
|
|
Assertf(false,"Bloom threshold exposure difference boudaries are not correct, revise visualsettings.dat");
|
|
t = g_bloomThresholdExposureDiffMin;
|
|
}
|
|
else
|
|
{
|
|
t = pow(SmoothStep(-exposureDiff, g_bloomThresholdExposureDiffMin, g_bloomThresholdExposureDiffMax), g_bloomThresholdPower);
|
|
}
|
|
|
|
settings.m_bloomThresholdMax = Saturate(Lerp(
|
|
t,
|
|
settings.m_bloomThresholdMax,
|
|
settings.m_bloomThresholdMax - g_bloomThresholdMin));
|
|
}
|
|
|
|
#if __BANK
|
|
|
|
if (g_bDebugTriggerPulseEffect)
|
|
{
|
|
g_bDebugTriggerPulseEffect = false;
|
|
SetPulseParameters(g_debugPulseEffectParams, g_debugPulseEffectRampUpDuration, g_debugPulseEffectHoldDuration, g_debugPulseEffectRampDownDuration);
|
|
}
|
|
|
|
if (gDisableScreenBlurFadeOut)
|
|
{
|
|
g_screenBlurFade.Reset();
|
|
gDisableScreenBlurFadeOut = false;
|
|
gTriggerScreenBlurFadeOut = false;
|
|
gTriggerScreenBlurFadeIn = false;
|
|
}
|
|
if (gTriggerScreenBlurFadeOut || gTriggerScreenBlurFadeIn)
|
|
{
|
|
g_screenBlurFade.Trigger(gTriggerScreenBlurFadeOut);
|
|
gTriggerScreenBlurFadeOut = false;
|
|
gTriggerScreenBlurFadeIn = false;
|
|
}
|
|
#endif
|
|
|
|
#if ADAPTIVE_DOF_CPU
|
|
bool bGaussian = (GRCDEVICE.GetDxFeatureLevel() >=1100) ? true : false;
|
|
#if RSG_PC
|
|
bGaussian &= ((GET_POSTFX_SETTING(CSettingsManager::GetInstance().GetSettings().m_graphics.m_PostFX) >= CSettings::High) && (GRCDEVICE.IsStereoEnabled() == false)) ? true : false;
|
|
#endif
|
|
if (!bGaussian && UseAdaptiveDofCPU())
|
|
AdaptiveDepthOfField.ProcessAdaptiveDofCPU();
|
|
#endif
|
|
|
|
UpdateDefaultMotionBlur();
|
|
|
|
PostFX::SetDofParams();
|
|
PostFX::SetMotionBlur();
|
|
PostFX::SetFograyParams(CRenderPhaseCascadeShadowsInterface::IsShadowActive());
|
|
|
|
Vec3V currCameraPos = Vec3V(V_ZERO);
|
|
Vec3V prevCameraPos = Vec3V(V_ZERO);
|
|
|
|
float blurSize = fpvMotionBlurSize;
|
|
Vector4 weights = fpvMotionBlurWeights;
|
|
float maxVelocity = fpvMotionVelocityMaxSize;
|
|
|
|
bool enableMotionBlur = g_fpvMotionBlurEnable;
|
|
|
|
if (g_fpvMotionBlurEnableDynamicUpdate)
|
|
{
|
|
currCameraPos = fpvMotionBlurCurrCameraPos;
|
|
prevCameraPos = fpvMotionBlurPrevCameraPos[0];
|
|
|
|
if (!fwTimer::IsGamePaused())
|
|
{
|
|
fpvMotionBlurPrevCameraPos[1] = fpvMotionBlurPrevCameraPos[0];
|
|
fpvMotionBlurPrevCameraPos[0] = currCameraPos;
|
|
}
|
|
else
|
|
{
|
|
prevCameraPos = fpvMotionBlurPrevCameraPos[1];
|
|
currCameraPos = fpvMotionBlurPrevCameraPos[0];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const CClipEventTags::CMotionBlurEventTag::MotionBlurData* mbData = CClipEventTags::GetCurrentMotionBlur();
|
|
if (mbData != NULL)
|
|
{
|
|
currCameraPos = mbData->GetCurrentPosition();
|
|
prevCameraPos = mbData->GetLastPosition();
|
|
if (!g_fpvMotionBlurOverrideTagData)
|
|
{
|
|
blurSize = mbData->GetCurrentBlurAmount();
|
|
weights = Vector4(1.0f, 0.0f, mbData->GetVelocityBlend(), mbData->GetNoisiness());
|
|
maxVelocity = mbData->GetMaximumVelocity();
|
|
}
|
|
enableMotionBlur = true;
|
|
}
|
|
else
|
|
{
|
|
fpvMotionBlurVelocity = Vec2V(0.0f, 0.0f);
|
|
fpvMotionBlurFirstFrame = true;
|
|
}
|
|
}
|
|
|
|
Vec4V plane = BuildPlane(Vec3V(V_ZERO), Vec3V(0.0f, 0.0f, -1.0f));
|
|
|
|
Vec3V ssCurrPos = PlaneProject(plane, currCameraPos);
|
|
Vec3V ssPrevPos = PlaneProject(plane, prevCameraPos);
|
|
|
|
Vec2V diff = Subtract(ssCurrPos.GetXY(), ssPrevPos.GetXY());
|
|
Vec2V ssPosDiff = Scale(diff, Vec2V(SCREEN_WIDTH/2.0f, SCREEN_HEIGHT/2.0f));
|
|
ssPosDiff = Scale(ssPosDiff, Vec2V(1.0f, -1.0f));
|
|
|
|
#if __BANK
|
|
if (g_fpvMotionBlurDrawDebug)
|
|
{
|
|
Vec2V debugCurrPos = ssCurrPos.GetXY() * Vec2V(V_HALF) + Vec2V(V_HALF);
|
|
Vec2V debugPrevPos = ssPrevPos.GetXY() * Vec2V(V_HALF) + Vec2V(V_HALF);
|
|
grcDebugDraw::Circle(debugCurrPos, 0.01f, Color32(255, 0, 0, 128));
|
|
grcDebugDraw::Circle(debugPrevPos, 0.01f, Color32(0, 0, 255, 128));
|
|
grcDebugDraw::Line(debugCurrPos, debugPrevPos, Color32(255, 0, 0, 255), Color32(0, 0, 255, 255));
|
|
}
|
|
#endif
|
|
|
|
if (enableMotionBlur && fpvMotionBlurFirstFrame)
|
|
{
|
|
fpvMotionBlurVelocity = ssPosDiff;
|
|
fpvMotionBlurFirstFrame = false;
|
|
}
|
|
|
|
Vec2V velocity =
|
|
Scale(fpvMotionBlurVelocity, ScalarV(1.0f - weights.z)) +
|
|
Scale(ssPosDiff, ScalarV(weights.z)) *
|
|
ScalarV((1.0f / fwTimer::GetTimeStep()) / 30.0f);
|
|
|
|
velocity = Clamp(velocity,
|
|
Vec2V(-maxVelocity, -maxVelocity),
|
|
Vec2V( maxVelocity, maxVelocity));
|
|
|
|
settings.m_fpvMotionBlurVelocity = velocity;
|
|
|
|
if (!fwTimer::IsGamePaused())
|
|
{
|
|
fpvMotionBlurVelocity = velocity;
|
|
}
|
|
|
|
settings.m_fpvMotionBlurWeights = weights;
|
|
settings.m_fpvMotionBlurSize = blurSize;
|
|
|
|
bool applyFPVMB = camInterface::IsRenderingFirstPersonShooterCamera();
|
|
|
|
if (activeCamera && activeCamera->GetIsClassId(camCinematicMountedCamera::GetStaticClassId()))
|
|
{
|
|
applyFPVMB = static_cast<const camCinematicMountedCamera*>(activeCamera)->IsFirstPersonCamera();
|
|
}
|
|
|
|
#if RSG_PC
|
|
applyFPVMB &= (GET_POSTFX_SETTING(CSettingsManager::GetInstance().GetSettings().m_graphics.m_PostFX) >= CSettings::Medium) ? true : false;
|
|
#endif
|
|
|
|
settings.m_fpvMotionBlurActive = applyFPVMB && enableMotionBlur && !CNewHud::IsWeaponWheelActive();
|
|
}
|
|
|
|
#if __BANK
|
|
void PostFX::RenderDofDebug(grcRenderTarget* pDepthBlurTarget, const PostFX::PostFXParamBlock::paramBlock &settings)
|
|
{
|
|
#if ADAPTIVE_DOF_GPU
|
|
AdaptiveDepthOfField.DrawFocusGrid();
|
|
#endif //ADAPTIVE_DOF_GPU
|
|
#if DOF_COMPUTE_GAUSSIAN
|
|
if( g_DrawCOCOverlay )
|
|
{
|
|
#if RSG_DURANGO && __BANK
|
|
if (AltBokehDepthBlur)
|
|
{
|
|
ESRAMManager::ESRAMCopyIn(BokehDepthBlur, AltBokehDepthBlur);
|
|
}
|
|
#endif
|
|
grcDepthStencilStateHandle currentDSS = grcStateBlock::DSS_Active;
|
|
grcBlendStateHandle currentBS = grcStateBlock::BS_Active;
|
|
grcStateBlock::SetDepthStencilState(grcStateBlock::DSS_IgnoreDepth);
|
|
grcStateBlock::SetBlendState(grcStateBlock::BS_Normal);
|
|
|
|
dofComputeShader->SetVar( g_cocOverlayAlpha, (float)g_cocOverlayAlphaVal);
|
|
|
|
grcStateBlock::SetDepthStencilState(grcStateBlock::DSS_IgnoreDepth);
|
|
dofComputeShader->SetVar(dofComputeColorTex, pDepthBlurTarget);
|
|
|
|
u32 COCOverlayPass = pp_DOF_ComputeGaussian_COC_Overlay;
|
|
#if ADAPTIVE_DOF_OUTPUT_UAV
|
|
if( settings.m_AdaptiveDof )
|
|
COCOverlayPass = pp_DOF_ComputeGaussian_COC_Overlay_Adaptive;
|
|
#endif //ADAPTIVE_DOF_OUTPUT_UAV
|
|
ShaderUtil::StartShader("DoF COC Overlay", dofComputeShader, dofComputeTechnique, COCOverlayPass);
|
|
|
|
grcDrawSingleQuadf(0.f,0.f,1.f,1.f, 0.0f, 0.0, 0.0, 0.0f, 0.0f, Color32(0));
|
|
ShaderUtil::EndShader(dofComputeShader);
|
|
|
|
grcStateBlock::SetDepthStencilState(currentDSS);
|
|
grcStateBlock::SetBlendState(currentBS);
|
|
}
|
|
#endif //DOF_COMPUTE_GAUSSIAN
|
|
}
|
|
#endif //__BANK
|
|
|
|
void PostFX::ProcessUISubSampleAlpha(grcRenderTarget* pDstColorTarget, grcRenderTarget* pSrcColorTarget, grcRenderTarget* pSrcAlphaTarget, grcRenderTarget* pDepthStencilTarget, const Vector4 &scissorRect)
|
|
{
|
|
GRC_ALLOC_SCOPE_AUTO_PUSH_POP()
|
|
|
|
PIXBegin(0, "SSA Combine");
|
|
GRCDBG_PUSH("SSA Combine");
|
|
|
|
grcResolveFlags flags;
|
|
#if SSA_USES_EARLYSTENCIL
|
|
grcTextureFactory::GetInstance().LockRenderTarget(0, NULL, pDepthStencilTarget); // Binding just the depth buffer saves ~0.025ms on PS3
|
|
|
|
GRCDEVICE.SetScissor((int)scissorRect.x, (int)scissorRect.y, (int)scissorRect.z, (int)scissorRect.w);
|
|
|
|
CRenderTargets::ConvertAlphaMaskToStencilMask( 0, pSrcAlphaTarget );
|
|
grcStateBlock::SetRasterizerState(subSampleAlphaRasterizerState);
|
|
grcStateBlock::SetBlendState(subSampleAlphaBlendState);
|
|
grcStateBlock::SetDepthStencilState(subSampleAlphaWithStencilCullDSState, DEFERRED_MATERIAL_SPECIALBIT);
|
|
|
|
// unlock target
|
|
#if __XENON
|
|
flags.NeedResolve = true;
|
|
#endif
|
|
grcTextureFactory::GetInstance().UnlockRenderTarget(0, &flags);
|
|
|
|
#if __PS3
|
|
if (pSrcColorTarget != pDstColorTarget)
|
|
{
|
|
grcTextureFactory::GetInstance().LockRenderTarget(0, pSrcColorTarget, NULL); // Re-bind the color buffer
|
|
GRCDEVICE.SetScissor((int)scissorRect.x, (int)scissorRect.y, (int)scissorRect.z, (int)scissorRect.w);
|
|
CSprite2d copyBuffer;
|
|
copyBuffer.BeginCustomList(CSprite2d::CS_BLIT_NOFILTERING, pDstColorTarget);
|
|
grcDrawSingleQuadf(-1.0, 1.0f, 1.0f, -1.0f, 0.0f, 0.0, 0.0, 1.0f, 1.0f,Color32(255, 255, 255, 255));
|
|
copyBuffer.EndCustomList();
|
|
grcTextureFactory::GetInstance().UnlockRenderTarget(0);
|
|
}
|
|
#endif
|
|
|
|
#if RSG_PC
|
|
Assertf((pSrcColorTarget != pDstColorTarget), "Make sure source contains copy of destination");
|
|
Assertf((pSrcAlphaTarget != pDstColorTarget), "Source alpha can not share with destination texture");
|
|
#endif // RSG_PC
|
|
#else // SSA_USES_EARLYSTENCIL
|
|
|
|
grcStateBlock::SetRasterizerState(subSampleAlphaRasterizerState);
|
|
grcStateBlock::SetBlendState(subSampleAlphaBlendState);
|
|
grcStateBlock::SetDepthStencilState(subSampleAlphaDSState);
|
|
#endif // SSA_USES_EARLYSTENCIL
|
|
grcTextureFactory::GetInstance().LockRenderTarget(0, pDstColorTarget, pDepthStencilTarget); // Re-bind the color buffer
|
|
|
|
grcRenderTarget* target = pSrcColorTarget;
|
|
#if RSG_DURANGO || RSG_PC
|
|
DURANGO_ONLY(if(!GRCDEVICE.GetMSAA()))
|
|
{
|
|
float GBufferSizeX = 1.0f;
|
|
float GBufferSizeY = 1.0f;
|
|
if(pSrcAlphaTarget)
|
|
{
|
|
GBufferSizeX = (float)pSrcAlphaTarget->GetWidth();
|
|
GBufferSizeY = (float)pSrcAlphaTarget->GetHeight();
|
|
}
|
|
PostFXShader->SetVar(GBufferTexture0ParamId, Vec4V(GBufferSizeX, GBufferSizeY, 1.0f/GBufferSizeX, 1.0f/GBufferSizeY));
|
|
PostFXShader->SetVar(GBufferTextureId0, pSrcAlphaTarget);
|
|
}
|
|
#endif
|
|
PostFXShader->SetVar(TextureID_0, target);
|
|
PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/float(target->GetWidth()),1.0f/float(target->GetHeight()), 0.0, 0.0f));
|
|
PostFXShader->SetVar(GBufferTextureIdSSAODepth, pSrcAlphaTarget);
|
|
|
|
GRCDEVICE.SetScissor((int)scissorRect.x, (int)scissorRect.y, (int)scissorRect.z, (int)scissorRect.w);
|
|
|
|
#if DEVICE_MSAA
|
|
if(GRCDEVICE.GetMSAA()>1)
|
|
{
|
|
PostFXShader->SetVar(TextureHDR_AA, target);
|
|
}
|
|
#endif
|
|
|
|
PostFXBlit(NULL, PostFXTechnique, pp_subsampleAlphaUI, false);
|
|
|
|
#if SSA_USES_EARLYSTENCIL
|
|
// Disable early-stencil
|
|
XENON_ONLY( GRCDEVICE.GetCurrent()->SetRenderState( D3DRS_HIZENABLE, false ) );
|
|
DeferredLighting::SetHiStencilCullState( DeferredLighting::CULL_OFF );
|
|
|
|
#if __XENON
|
|
D3DRECT srcRect = { 0, 0, pDstColorTarget->GetWidth(), pDstColorTarget->GetHeight()};
|
|
D3DPOINT dstPoint = { 0, 0 };
|
|
GRCDEVICE.GetCurrent()->Resolve(
|
|
D3DRESOLVE_RENDERTARGET0 | D3DRESOLVE_ALLFRAGMENTS,
|
|
&srcRect,
|
|
pDstColorTarget->GetTexturePtr(),
|
|
&dstPoint,
|
|
0, 0, NULL, 0.0f, 0L, NULL);
|
|
flags.NeedResolve = false;
|
|
#endif
|
|
#endif // SSA_USES_EARLYSTENCIL
|
|
grcTextureFactory::GetInstance().UnlockRenderTarget(0, &flags);
|
|
|
|
GRCDBG_POP();
|
|
PIXEnd();
|
|
}
|
|
|
|
void PostFX::ProcessSubSampleAlpha(grcRenderTarget* PS3_ONLY(pColorTarget), grcRenderTarget* PS3_ONLY(pDepthStencilTarget))
|
|
{
|
|
GRC_ALLOC_SCOPE_AUTO_PUSH_POP()
|
|
|
|
PIXBegin(0, "SSA Combine");
|
|
GRCDBG_PUSH("SSA Combine");
|
|
|
|
#if SSA_USES_CONDITIONALRENDER
|
|
// The SSA Conditional Render path is only implemented efficiently for platforms that are doing early-stencil culling with SSA Combine.
|
|
CompileTimeAssert( SSA_USES_EARLYSTENCIL );
|
|
#endif
|
|
|
|
#if DEVICE_GPU_WAIT
|
|
// If we don't wait for writes to finish, we get graphical issues in the sky (particularly at night: B*1878659) due to
|
|
// read after write hazzards. I think the fact that we are reading/writing the same render target here confuses
|
|
// the Durango driver's built in hazard tracking.
|
|
GRCDEVICE.GpuWaitOnPreviousWrites();
|
|
#endif
|
|
|
|
if ( g_UseSubSampledAlpha)
|
|
{
|
|
#if RSG_PC
|
|
// Swap backbuffers to avoid copy
|
|
CRenderTargets::UnlockSceneRenderTargets();
|
|
CRenderTargets::SwapBackBuffer();
|
|
CRenderTargets::LockSceneRenderTargets();
|
|
#endif
|
|
|
|
// Use Early-Stencil culling on the consoles to only apply SSA Combine to pixels that need it. Not sure this will be
|
|
// worth the trouble on PC? We also support conditional rendering on the 360 & PS3.
|
|
#if SSA_USES_CONDITIONALRENDER
|
|
// Only do SSA Combine if there are SSA pixels visible (conditional rendering path is enabled and valid) and we're not shmooing
|
|
if (g_UseConditionalSSA && DeferredLighting::HasValidSSAQuery() && !ShmooHandling::IsShmooEnable(PostFxShmoo))
|
|
{
|
|
grcRenderTarget* pBackBuffer = XENON_SWITCH(CRenderTargets::GetBackBuffer7e3toInt(true), CRenderTargets::GetBackBuffer());
|
|
// Set both texture and texel size parameter.
|
|
SetSrcTextureAndSize(TextureID_0, pBackBuffer);
|
|
PostFXShader->SetVar(GBufferTextureId0, GBuffer::GetTarget(GBUFFER_RT_0));
|
|
|
|
#if __XENON
|
|
// On 360, the predicate is only valid for the 2nd tile (the 2nd tile's predicate overwrite the 1st tile's predicate).
|
|
D3DRECT pTilingRects[NUM_TILES];
|
|
GBuffer::CalculateTiles(pTilingRects, NUM_TILES);
|
|
|
|
// Top tile
|
|
GRCDEVICE.SetScissor(pTilingRects[0].x1, pTilingRects[0].y1, pTilingRects[0].x2-pTilingRects[0].x1, pTilingRects[0].y2-pTilingRects[0].y1 );
|
|
CRenderTargets::ConvertAlphaMaskToStencilMask( 0, GBuffer::GetTarget(GBUFFER_RT_0) );
|
|
grcStateBlock::SetRasterizerState(subSampleAlphaRasterizerState);
|
|
grcStateBlock::SetBlendState(subSampleAlphaBlendState);
|
|
grcStateBlock::SetDepthStencilState(subSampleAlphaWithStencilCullDSState, DEFERRED_MATERIAL_SPECIALBIT);
|
|
PostFXBlit(NULL,PostFXTechnique, g_UseSinglePassSSA ? pp_subsampleAlphaSinglePass : pp_subsampleAlpha, false);
|
|
|
|
// Bottom tile.
|
|
GRCDEVICE.SetScissor(pTilingRects[1].x1, pTilingRects[1].y1, pTilingRects[1].x2-pTilingRects[1].x1, pTilingRects[1].y2-pTilingRects[1].y1 );
|
|
DeferredLighting::BeginSSAConditionalRender();
|
|
CRenderTargets::ConvertAlphaMaskToStencilMask( 0, GBuffer::GetTarget(GBUFFER_RT_0) );
|
|
grcStateBlock::SetRasterizerState(subSampleAlphaRasterizerState);
|
|
grcStateBlock::SetBlendState(subSampleAlphaBlendState);
|
|
grcStateBlock::SetDepthStencilState(subSampleAlphaWithStencilCullDSState, DEFERRED_MATERIAL_SPECIALBIT);
|
|
PostFXBlit(NULL,PostFXTechnique, g_UseSinglePassSSA ? pp_subsampleAlphaSinglePass : pp_subsampleAlpha, false);
|
|
DeferredLighting::EndSSAConditionalRender();
|
|
|
|
// Reset scissor
|
|
GRCDEVICE.SetScissor(0, 0, GRCDEVICE.GetWidth(), GRCDEVICE.GetHeight());
|
|
#else // __XENON
|
|
DeferredLighting::BeginSSAConditionalRender();
|
|
PS3_ONLY(grcTextureFactory::GetInstance().LockRenderTarget(0, NULL, pDepthStencilTarget)); // Binding just the depth buffer saves ~0.025ms on PS3
|
|
CRenderTargets::ConvertAlphaMaskToStencilMask( 0, GBuffer::GetTarget(GBUFFER_RT_0) );
|
|
grcStateBlock::SetRasterizerState(subSampleAlphaRasterizerState);
|
|
grcStateBlock::SetBlendState(subSampleAlphaBlendState);
|
|
grcStateBlock::SetDepthStencilState(subSampleAlphaWithStencilCullDSState, DEFERRED_MATERIAL_SPECIALBIT);
|
|
PS3_ONLY(grcTextureFactory::GetInstance().LockRenderTarget(0, pColorTarget, pDepthStencilTarget)); // Re-bind the color buffer
|
|
PostFXBlit(NULL,PostFXTechnique, g_UseSinglePassSSA ? pp_subsampleAlphaSinglePass : pp_subsampleAlpha, false);
|
|
DeferredLighting::EndSSAConditionalRender();
|
|
#endif // __XENON
|
|
}
|
|
else // Non-conditional rendering path
|
|
#endif // #if SSA_USES_CONDITIONALRENDER
|
|
{
|
|
#if SSA_USES_EARLYSTENCIL
|
|
PS3_ONLY(grcTextureFactory::GetInstance().LockRenderTarget(0, NULL, pDepthStencilTarget)); // Binding just the depth buffer saves ~0.025ms on PS3
|
|
CRenderTargets::ConvertAlphaMaskToStencilMask( 0, GBuffer::GetTarget(GBUFFER_RT_0) );
|
|
grcStateBlock::SetRasterizerState(subSampleAlphaRasterizerState);
|
|
grcStateBlock::SetBlendState(subSampleAlphaBlendState);
|
|
grcStateBlock::SetDepthStencilState(subSampleAlphaWithStencilCullDSState, DEFERRED_MATERIAL_SPECIALBIT);
|
|
PS3_ONLY( grcTextureFactory::GetInstance().LockRenderTarget(0, pColorTarget, pDepthStencilTarget) ); // Re-bind the color buffer
|
|
#else // SSA_USES_EARLYSTENCIL
|
|
grcStateBlock::SetRasterizerState(subSampleAlphaRasterizerState);
|
|
grcStateBlock::SetBlendState(subSampleAlphaBlendState);
|
|
grcStateBlock::SetDepthStencilState(subSampleAlphaDSState);
|
|
#endif // SSA_USES_EARLYSTENCIL
|
|
|
|
const grcTexture* pBackBuffer = NULL;
|
|
#if RSG_PC
|
|
pBackBuffer = CRenderTargets::GetBackBufferCopy();
|
|
#else
|
|
// We don't sample outside of the 2x2 pixel quad, so there is no read/write hazard here (safe to read/write the back buffer)
|
|
pBackBuffer = CRenderTargets::GetBackBuffer();
|
|
#endif
|
|
|
|
// Set both texture and texel size parameter.
|
|
SetSrcTextureAndSize(TextureID_0, pBackBuffer);
|
|
|
|
float GBufferSizeX = (float)GBuffer::GetTarget(GBUFFER_RT_0)->GetWidth();
|
|
float GBufferSizeY = (float)GBuffer::GetTarget(GBUFFER_RT_0)->GetHeight();
|
|
PostFXShader->SetVar(GBufferTexture0ParamId, Vec4V(GBufferSizeX, GBufferSizeY, 1.f/GBufferSizeX, 1.f/GBufferSizeY));
|
|
|
|
// Using GBufferTextureSamplerSSAODepth because it's one of the non-MSAA samplers available.
|
|
// We can't use GBufferTextureSampler0, since this shader is postfxMS, and the GBufferTexture0 is MSAA.
|
|
//PostFXShader->SetVar(GBufferTextureId0, GBuffer::GetTarget(GBUFFER_RT_0));
|
|
PostFXShader->SetVar(GBufferTextureIdSSAODepth, GBuffer::GetTarget(GBUFFER_RT_0));
|
|
|
|
#if DEVICE_MSAA
|
|
if(GRCDEVICE.GetMSAA()>1)
|
|
{
|
|
PostFXShader->SetVar(TextureHDR_AA, CRenderTargets::GetBackBuffer());
|
|
}
|
|
#endif
|
|
|
|
PostFXBlit(NULL,PostFXTechnique, g_UseSinglePassSSA ? pp_subsampleAlphaSinglePass : pp_subsampleAlpha, false);
|
|
}
|
|
|
|
#if SSA_USES_EARLYSTENCIL
|
|
// Disable early-stencil
|
|
XENON_ONLY( GRCDEVICE.GetCurrent()->SetRenderState( D3DRS_HIZENABLE, false ) );
|
|
DeferredLighting::SetHiStencilCullState( DeferredLighting::CULL_OFF );
|
|
#endif
|
|
}
|
|
|
|
grcStateBlock::SetRasterizerState(exitSubSampleAlphaRasterizerState);
|
|
grcStateBlock::SetBlendState(exitSubSampleAlphaBlendState);
|
|
grcStateBlock::SetDepthStencilState(exitSubSampleAlphaDepthStencilState);
|
|
|
|
GRCDBG_POP();
|
|
PIXEnd();
|
|
}
|
|
|
|
|
|
static void SetFograyPostFxParamsHelper(grmShader *const shader, grcEffectVar param, grcEffectVar fadeParam, float fograyIntensity, float fograyContrast, float fograyFadeStart, float fograyFadeEnd)
|
|
{
|
|
Vector4 globalfograyParam = Vector4(fograyIntensity, 0.0f, fograyContrast, 0.0f);
|
|
const float jitterDivisor = 1.0f/(PostFX::g_fograyJitterEnd - PostFX::g_fograyJitterStart);
|
|
Vector4 globalfograyFadeParam = Vector4(fograyFadeStart, 1.0f/(fograyFadeEnd - fograyFadeStart), jitterDivisor, -PostFX::g_fograyJitterStart * jitterDivisor);
|
|
shader->SetVar(param, globalfograyParam);
|
|
shader->SetVar(fadeParam, globalfograyFadeParam);
|
|
}
|
|
|
|
void PostFX::SetFograyPostFxParams(float fograyIntensity, float fograyContrast, float fograyFadeStart, float fograyFadeEnd)
|
|
{
|
|
SetFograyPostFxParamsHelper(PostFXShader, globalFograyParamId, globalFograyFadeParamId, fograyIntensity, fograyContrast, fograyFadeStart, fograyFadeEnd);
|
|
}
|
|
|
|
static void ProcessDepthRender(grmShader *const shader)
|
|
{
|
|
if(!shader->BeginDraw(grmShader::RMC_DRAW, true, PostFXTechnique))
|
|
return;
|
|
|
|
#if RSG_PC
|
|
u32 shaderModelMajor, shaderModelMinor;
|
|
|
|
GRCDEVICE.GetDxShaderModel(shaderModelMajor, shaderModelMinor);
|
|
#endif
|
|
|
|
PostFXPass pass = WIN32PC_SWITCH((shaderModelMajor == 5) ? pp_depthfx : pp_depthfx_nogather, pp_depthfx);
|
|
|
|
ShmooHandling::BeginShmoo(PostFxShmoo, shader, (int)pass);
|
|
shader->Bind(pass);
|
|
GRCDEVICE.DrawPrimitive(drawTriStrip, sm_FogVertexDeclaration, *sm_FogVertexBuffer, 0, sm_FogVertexBuffer->GetVertexCount());
|
|
shader->UnBind();
|
|
ShmooHandling::EndShmoo(PostFxShmoo);
|
|
shader->EndDraw();
|
|
}
|
|
|
|
void PostFX::ProcessDepthFX()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
PF_PUSH_MARKER("PostFX::ProcessDepthFX");
|
|
|
|
GRC_ALLOC_SCOPE_AUTO_PUSH_POP()
|
|
|
|
#if POSTFX_FOGRAY
|
|
const PostFXParamBlock::paramBlock& settings = PostFXParamBlock::GetRenderThreadParams();
|
|
bool bFogRay = (WIN32PC_ONLY((grcEffect::GetShaderQuality() > 0) && ) (settings.m_fograyIntensity > 0.0f) && settings.m_bShadowActive);
|
|
|
|
#if DEVICE_MSAA
|
|
// need to resolve depth for fogray (due to water rendering, etc ...)
|
|
if (bFogRay && GRCDEVICE.GetMSAA()>1 WIN32PC_ONLY(&& Water::IsDepthUpdated()))
|
|
CRenderTargets::ResolveDepth(depthResolve_Farthest);
|
|
#endif
|
|
#endif
|
|
|
|
grcStateBlock::SetRasterizerState(depthFXRasterizerState);
|
|
grcStateBlock::SetBlendState(depthFXBlendState);
|
|
|
|
const Vector4 projParams = ShaderUtil::CalculateProjectionParams();
|
|
PostFXShader->SetVar(DofProjId, projParams);
|
|
|
|
const Vector2 dofShear = grcViewport::GetCurrent()->GetPerspectiveShear();
|
|
PostFXShader->SetVar(DofShearId, Vector4(dofShear.x,dofShear.y,0.f,0.f) );
|
|
|
|
#if POSTFX_FOGRAY
|
|
if (bFogRay)
|
|
{
|
|
CShaderLib::SetFogRayIntensity(settings.m_fograyIntensity);
|
|
// copy cascade shadowmap to mini map
|
|
PostFXShader->SetVar(ResolvedTextureIdDepth, CRenderPhaseCascadeShadowsInterface::GetShadowMap());
|
|
|
|
grcRenderTarget* shadowmap = CRenderPhaseCascadeShadowsInterface::GetShadowMapMini(SM_MINI_FOGRAY);
|
|
|
|
//This is done before the GPU Particle FX render (during PostFX::ProcessDepthFX). If in case this is moved to after Ptfx Render, we'll have to change the logic there
|
|
#if RSG_ORBIS
|
|
PostFXBlit(shadowmap, PostFXTechnique, pp_shadowmapblit, false, false, NULL, false, Vector2(0.0f,0.0f), Vector2(1.0f, 1.0f), true);
|
|
#else
|
|
PostFXBlit(shadowmap, PostFXTechnique, pp_shadowmapblit, false, false, NULL, false, Vector2(0.0f,0.0f), Vector2(1.0f, 1.0f));
|
|
#endif
|
|
|
|
#if __ASSERT
|
|
//Used for making sure that other systems using this shadow map will be on the same thread
|
|
g_FogRayCascadeShadowMapDownsampleThreadId = sysIpcGetCurrentThreadId();
|
|
#endif
|
|
|
|
CRenderPhaseCascadeShadowsInterface::SetSharedShadowMap(shadowmap);
|
|
|
|
//#if DEVICE_MSAA
|
|
// #if __D3D11
|
|
// const grcRenderTarget* pDepthBuffer = CRenderTargets::GetDepthBufferResolved_ReadOnly();
|
|
// #else
|
|
// const grcRenderTarget* pDepthBuffer = CRenderTargets::GetDepthResolved();
|
|
// #endif
|
|
////#else
|
|
// const grcRenderTarget* pDepthBuffer = CRenderTargets::GetDepthBuffer();
|
|
//#endif
|
|
|
|
PostFXShader->SetVar(ResolvedTextureIdDepth, CRenderTargets::GetDepthResolved());
|
|
|
|
// fog ray param
|
|
SetFograyPostFxParams(settings.m_fograyIntensity, settings.m_fograyContrast, settings.m_fograyFadeStart, settings.m_fograyFadeEnd);
|
|
|
|
#if RSG_ORBIS
|
|
PostFXBlit(FogRayRT, PostFXTechnique, pp_fogray,false,true,NULL,false,Vector2(0.0f,0.0f),Vector2(1.0f,1.0f),true);
|
|
#else
|
|
u32 FogRayPass = pp_fogray;
|
|
|
|
#if RSG_PC
|
|
u32 shaderModelMajor, shaderModelMinor;
|
|
|
|
GRCDEVICE.GetDxShaderModel(shaderModelMajor, shaderModelMinor);
|
|
|
|
FogRayPass = (shaderModelMajor == 5) ? pp_fogray : pp_fogray_nogather;
|
|
|
|
if(CSettingsManager::GetInstance().GetSettings().m_graphics.m_PostFX >= CSettings::Ultra)
|
|
FogRayPass = (shaderModelMajor == 5) ? pp_fogray_high : pp_fogray_high_nogather;
|
|
#endif
|
|
PostFXBlit(FogRayRT, PostFXTechnique, FogRayPass,false,true);
|
|
#endif
|
|
|
|
PostFXShader->SetVar(TextureID_0, FogRayRT);
|
|
PostFXShader->SetVar(BloomTexelSizeId, Vector4(1.0f/float(FogRayRT->GetWidth()),1.0f/float(FogRayRT->GetHeight()),0.0, 0.0f));
|
|
|
|
#if RSG_ORBIS
|
|
PostFXBlit(FogRayRT2, PostFXTechnique, pp_GaussBlurBilateral_Hor,false,false,NULL,false,Vector2(0.0f,0.0f),Vector2(1.0f,1.0f),true);
|
|
#else
|
|
u32 BlurHorPass = pp_GaussBlurBilateral_Hor;
|
|
#if RSG_PC
|
|
if(CSettingsManager::GetInstance().GetSettings().m_graphics.m_PostFX >= CSettings::Ultra)
|
|
BlurHorPass = pp_GaussBlurBilateral_Hor_High;
|
|
#endif
|
|
PostFXBlit(FogRayRT2, PostFXTechnique, BlurHorPass);
|
|
#endif
|
|
|
|
PostFXShader->SetVar(TextureID_0, FogRayRT2);
|
|
PostFXShader->SetVar(BloomTexelSizeId, Vector4(1.0f/float(FogRayRT2->GetWidth()),1.0f/float(FogRayRT2->GetHeight()),0.0, 0.0f));
|
|
|
|
#if RSG_ORBIS
|
|
PostFXBlit(FogRayRT, PostFXTechnique, pp_GaussBlurBilateral_Ver,false,false,NULL,false,Vector2(0.0f,0.0f),Vector2(1.0f,1.0f),true);
|
|
#else
|
|
u32 BlurVerPass = pp_GaussBlurBilateral_Ver;
|
|
|
|
#if RSG_PC
|
|
if(CSettingsManager::GetInstance().GetSettings().m_graphics.m_PostFX >= CSettings::Ultra)
|
|
BlurVerPass = pp_GaussBlurBilateral_Ver_High;
|
|
#endif
|
|
PostFXBlit(FogRayRT, PostFXTechnique, BlurVerPass);
|
|
#endif
|
|
|
|
}
|
|
else
|
|
{
|
|
CRenderTargets::UnlockSceneRenderTargets();
|
|
|
|
WIN32PC_ONLY(if(grcEffect::GetShaderQuality() > 0))
|
|
{
|
|
// if fogray intensity is greater than 0, and no dir. shadow active, clear out fogray RT
|
|
// since some shaders use fogray RT when fogray intensity is > 0.0f
|
|
grcTextureFactory::GetInstance().LockRenderTarget(0, FogRayRT, NULL);
|
|
GRCDEVICE.Clear(true, Color32(1.0f,1.0f,1.0f,1.0f),false, 0.0f, false);
|
|
grcTextureFactory::GetInstance().UnlockRenderTarget(0);
|
|
}
|
|
|
|
CRenderTargets::LockSceneRenderTargets(true);
|
|
}
|
|
#endif
|
|
|
|
grcStateBlock::SetDepthStencilState(depthFXDepthStencilState, DEFERRED_MATERIAL_CLEAR);
|
|
|
|
#if __XENON
|
|
GRCGPRALLOCATION->SetGPRAllocation(CGPRCounts::ms_DepthFXPsRegs); // this should probably go higher up so it can go around the sky and clouds as well.
|
|
GRCDEVICE.GetCurrent()->SetRenderState(D3DRS_HIZENABLE, false);
|
|
GRCDEVICE.GetCurrent()->SetRenderState(D3DRS_HIZWRITEENABLE, false);
|
|
#endif // __XENON
|
|
|
|
#if !RSG_PC && !RSG_DURANGO && !__PS3 &&!RSG_ORBIS
|
|
CRenderTargets::RefreshStencilCull(false, DEFERRED_MATERIAL_CLEAR, 0x07);
|
|
#endif
|
|
|
|
//use updated depth buffer
|
|
#if __PPU
|
|
PostFXShader->SetVar(GBufferTextureIdDepth, CRenderTargets::GetDepthBufferAsColor());
|
|
#elif __D3D11
|
|
// On Win32PC (DX9/DX10) we use a copy of the depth buffer to avoid a read/write hazard.
|
|
// On DX11 we no longer need to copy, just using a read-only depth view
|
|
grcTexture *const texDepth = CRenderTargets::LockReadOnlyDepth(false); //note: actually locks in DX11
|
|
PostFXShader->SetVar(GBufferTextureIdDepth, texDepth);
|
|
#else
|
|
PostFXShader->SetVar(GBufferTextureIdDepth, CRenderTargets::GetDepthBuffer());
|
|
#endif // __PPU, __D3D11
|
|
|
|
//const Vector4 projParams = ShaderUtil::CalculateProjectionParams();
|
|
//PostFXShader->SetVar(DofProjId, projParams);
|
|
|
|
//const Vector2 dofShear = grcViewport::GetCurrent()->GetPerspectiveShear();
|
|
//PostFXShader->SetVar(DofShearId, Vector4(dofShear.x,dofShear.y,0.f,0.f) );
|
|
|
|
g_timeCycle.SetShaderData();
|
|
|
|
#if __XENON
|
|
PostFX::SetLDR10bitHDR10bit();
|
|
#elif __PS3
|
|
PostFX::SetLDR8bitHDR16bit();
|
|
#else
|
|
PostFX::SetLDR16bitHDR16bit();
|
|
#endif
|
|
|
|
#if __PPU
|
|
// Fence to be sure that the depth buffer's ready...
|
|
grcFenceHandle fence = GRCDEVICE.InsertFence();
|
|
GRCDEVICE.GPUBlockOnFence(fence);
|
|
#endif // __PPU
|
|
|
|
#if __XENON
|
|
GRCDEVICE.GetCurrent()->SetRenderState( D3DRS_HIZENABLE, D3DHIZ_AUTOMATIC );
|
|
GRCDEVICE.GetCurrent()->SetRenderState( D3DRS_HIZWRITEENABLE, D3DHIZ_AUTOMATIC );
|
|
#endif
|
|
|
|
#if POSTFX_FOGRAY
|
|
// fog ray param
|
|
PostFXShader->SetVar(TextureID_1, FogRayRT);
|
|
float fogRayIntensity = settings.m_fograyIntensity;
|
|
CShaderLib::SetFogRayIntensity(fogRayIntensity);
|
|
SetFograyPostFxParams(fogRayIntensity, settings.m_fograyContrast, settings.m_fograyFadeStart, settings.m_fograyFadeEnd);
|
|
#endif
|
|
|
|
#if POSTFX_USE_TILEDFOG
|
|
if (BANK_SWITCH(PostFX::g_UseTiledTechniques == true, CTiledLighting::IsEnabled()))
|
|
{
|
|
PostFXPass pass = WIN32PC_SWITCH((shaderModelMajor == 5) ? pp_depthfx_tiled : pp_depthfx_tiled_nogather, pp_depthfx_tiled);
|
|
|
|
const char* pPassName = NULL;
|
|
#if RAGE_TIMEBARS
|
|
pPassName = passName[pass];
|
|
#endif
|
|
|
|
#if __D3D11 || RSG_ORBIS
|
|
PostFXShader->SetVar(TiledDepthTextureId, CTiledLighting::GetClassificationTexture());
|
|
#endif // __D3D11 || RSG_ORBIS
|
|
|
|
CTiledLighting::RenderTiles(NULL, PostFXShader, PostFXTechnique, pass, pPassName, false, false, false);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
#if MSAA_EDGE_PASS
|
|
if (DeferredLighting::IsEdgePassActiveForPostfx() && AssertVerify(PostFXShaderMS0) BANK_ONLY(&& (DebugDeferred::m_OptimizeDepthEffects & (1<<EM_IGNORE))))
|
|
{
|
|
BANK_ONLY(if (DebugDeferred::m_OptimizeDepthEffects & (1<<EM_EDGE0)))
|
|
{
|
|
grcStateBlock::SetDepthStencilState(DeferredLighting::m_directionalEdgeMaskEqualPass_DS, EDGE_FLAG);
|
|
ProcessDepthRender(PostFXShader);
|
|
}
|
|
BANK_ONLY(if (DebugDeferred::m_OptimizeDepthEffects & (1<<EM_FACE0)))
|
|
{
|
|
#if RSG_PC
|
|
u32 shaderModelMajor, shaderModelMinor;
|
|
|
|
GRCDEVICE.GetDxShaderModel(shaderModelMajor, shaderModelMinor);
|
|
#endif
|
|
PostFXPass pass = WIN32PC_SWITCH((shaderModelMajor == 5) ? pp_depthfx : pp_depthfx_nogather, pp_depthfx);
|
|
|
|
grcStateBlock::SetDepthStencilState(edgeMaskDepthEffectFace_DS, DEFERRED_MATERIAL_CLEAR); // Face: s < 7
|
|
PostFXShaderMS0->CopyPassData(PostFXTechnique, pass, PostFXShader);
|
|
ProcessDepthRender(PostFXShaderMS0);
|
|
}
|
|
}else
|
|
#endif //MSAA_EDGE_PASS
|
|
{
|
|
ProcessDepthRender(PostFXShader);
|
|
}
|
|
}
|
|
|
|
#if __D3D11
|
|
CRenderTargets::UnlockReadOnlyDepth(); //note: actually unlocks in DX11
|
|
#endif
|
|
|
|
#if __XENON
|
|
// set the pixel shader threads to 112 -> vertex shader can only use 16 threads
|
|
GRCGPRALLOCATION->SetGPRAllocation(0);
|
|
#endif
|
|
|
|
#if !__WIN32PC && !RSG_DURANGO && !RSG_ORBIS
|
|
CRenderTargets::ClearStencilCull( DEFERRED_MATERIAL_CLEAR );
|
|
#endif
|
|
grcStateBlock::SetRasterizerState(exitDepthFXRasterizerState);
|
|
grcStateBlock::SetBlendState(exitDepthFXBlendState);
|
|
grcStateBlock::SetDepthStencilState(exitDepthFXDepthStencilState);
|
|
|
|
PF_POP_MARKER();
|
|
}
|
|
|
|
|
|
#if __DEV && __PS3
|
|
void CRenderPhaseCascadeShadows_DumpRenderTargetsAfterSetWaitFlip();
|
|
#endif // __DEV && __PS3
|
|
|
|
bool NeedSDDownsample()
|
|
{
|
|
#if __PS3
|
|
return !((VideoResManager::GetUIHeight() == VideoResManager::GetNativeHeight()) && (VideoResManager::GetUIWidth() == VideoResManager::GetNativeWidth()));
|
|
#else
|
|
return false;
|
|
#endif //__PS3
|
|
}
|
|
|
|
void GetScanlineParams(const PostFX::PostFXParamBlock::paramBlock& settings, Vector4& outParams)
|
|
{
|
|
outParams = settings.m_scanlineParams;
|
|
|
|
// we're blending two sets of scanlines, no need to halve the intensity in the shader
|
|
outParams.x *= 0.5f;
|
|
|
|
// adjust speed
|
|
outParams.w = settings.m_time*0.001f*settings.m_scanlineParams.w;
|
|
|
|
}
|
|
|
|
void PrimeBloomBufferFrom(const grcTexture * pSrcBuffer)
|
|
{
|
|
PostFXShader->SetVar(TextureID_v1, PostFX::g_currentExposureRT);
|
|
SetSrcTextureAndSize(BloomTextureID, pSrcBuffer);
|
|
SetNonDepthFXStateBlocks();
|
|
PostFX::SetBloomParams();
|
|
PostFXBlit(BloomBufferHalf0, PostFXTechnique, pp_calcbloom0);
|
|
|
|
// Run a min filter to remove bright pixels
|
|
ProcessBloomBuffer(BloomBuffer, BloomBufferHalf0, pp_bloom_min);
|
|
|
|
// Keep a copy of the unblurred bloom buffer around
|
|
ProcessBloomBuffer(BloomBufferUnfiltered, BloomBuffer, pp_DownSampleBloom);
|
|
}
|
|
|
|
void ComputeLuminance()
|
|
{
|
|
PF_AUTO_PUSH_TIMEBAR("ComputeLuminance");
|
|
|
|
#if RSG_DURANGO
|
|
grcRenderTarget* BloomBufferQuarterDS = BloomBufferQuarterX;
|
|
#else
|
|
grcRenderTarget* BloomBufferQuarterDS = BloomBufferQuarter0;
|
|
#endif
|
|
|
|
// Half to quarter size max downsample
|
|
SetNonDepthFXStateBlocks();
|
|
PostFXShader->SetVar(TextureID_0, HalfScreen0);
|
|
PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/float(HalfScreen0->GetWidth()),1.0f/float(HalfScreen0->GetHeight()), 0.0, 0.0f));
|
|
PostFXBlit(BloomBufferQuarterDS, PostFXTechnique, pp_max);
|
|
|
|
#if AVG_LUMINANCE_COMPUTE
|
|
if(AverageLumunianceComputeEnable)
|
|
{
|
|
#if RSG_DURANGO
|
|
g_grcCurrentContext->GpuSendPipelinedEvent(D3D11X_GPU_PIPELINED_EVENT_PS_PARTIAL_FLUSH);
|
|
#endif
|
|
|
|
u32 GroupCountX = (u32)((float)BloomBufferQuarterDS->GetWidth() / 16.0f);
|
|
u32 GroupCountY = (u32)((float)BloomBufferQuarterDS->GetHeight() / 16.0f);
|
|
|
|
|
|
GroupCountX += (BloomBufferQuarterDS->GetWidth() % 16) > 0 ? 1 : 0;
|
|
GroupCountY += (BloomBufferQuarterDS->GetHeight() % 16) > 0 ? 1 : 0;
|
|
|
|
//avgLuminanceShader->SetVar(LumCSDownsampleSrcId, BloomBufferQuarterDS);
|
|
avgLuminanceShader->SetVar(LumCSDownsampleInitSrcId, BloomBufferQuarterDS);
|
|
avgLuminanceShader->SetVar(LumCSDownsampleTexSizeId, Vec4f(float(PostFX::LumCSDownsampleUAV[0]->GetWidth()),float(PostFX::LumCSDownsampleUAV[0]->GetHeight()), float(BloomBufferQuarterDS->GetWidth()), float(BloomBufferQuarterDS->GetHeight())));
|
|
avgLuminanceShader->SetVarUAV(LumCSDownsampleDstId, static_cast< grcTextureUAV*>(PostFX::LumCSDownsampleUAV[0]));
|
|
GRCDEVICE.RunComputation("Luminance Compute CS Conversion", *avgLuminanceShader, pp_luminance_downsample_init, GroupCountX, GroupCountY, 1);
|
|
|
|
# if __D3D11 || RSG_ORBIS
|
|
GRCDEVICE.SynchronizeComputeToCompute();
|
|
# endif
|
|
|
|
for(u32 i = 1; i < PostFX::LumCSDownsampleUAVCount; i++)
|
|
{
|
|
GroupCountX = (u32)(PostFX::LumCSDownsampleUAV[i-1]->GetWidth() / 16.0f);
|
|
GroupCountY = (u32)(PostFX::LumCSDownsampleUAV[i-1]->GetHeight() / 16.0f);
|
|
|
|
GroupCountX += (PostFX::LumCSDownsampleUAV[i-1]->GetWidth() % 16) > 0 ? 1 : 0;
|
|
GroupCountY += (PostFX::LumCSDownsampleUAV[i-1]->GetHeight() % 16) > 0 ? 1 : 0;
|
|
|
|
avgLuminanceShader->SetVar(LumCSDownsampleSrcId, PostFX::LumCSDownsampleUAV[i-1]);
|
|
avgLuminanceShader->SetVar(LumCSDownsampleTexSizeId, Vec4f(float(PostFX::LumCSDownsampleUAV[i]->GetWidth()),float(PostFX::LumCSDownsampleUAV[i]->GetHeight()), float(PostFX::LumCSDownsampleUAV[i-1]->GetWidth()), float(PostFX::LumCSDownsampleUAV[i-1]->GetHeight())));
|
|
avgLuminanceShader->SetVarUAV(LumCSDownsampleDstId, static_cast< grcTextureUAV*>(PostFX::LumCSDownsampleUAV[i]));
|
|
GRCDEVICE.RunComputation("Luminance Compute CS", *avgLuminanceShader, pp_luminance_downsample, GroupCountX, GroupCountY, 1);
|
|
|
|
# if __D3D11 || RSG_ORBIS
|
|
GRCDEVICE.SynchronizeComputeToCompute();
|
|
# endif
|
|
}
|
|
|
|
//write to 1x1
|
|
const u32 last_uav = PostFX::LumCSDownsampleUAVCount-1;
|
|
avgLuminanceShader->SetVar(LumCSDownsampleSrcId, PostFX::LumCSDownsampleUAV[last_uav]);
|
|
avgLuminanceShader->SetVar(LumCSDownsampleTexSizeId, Vec4f(float(PostFX::LumCSDownsampleUAV[last_uav+1]->GetWidth()),float(PostFX::LumCSDownsampleUAV[last_uav+1]->GetWidth()), float(PostFX::LumCSDownsampleUAV[last_uav]->GetWidth()), float(PostFX::LumCSDownsampleUAV[last_uav]->GetHeight())));
|
|
avgLuminanceShader->SetVarUAV(LumCSDownsampleDstId, static_cast< grcTextureUAV*>(PostFX::LumCSDownsampleUAV[PostFX::LumCSDownsampleUAVCount]));
|
|
GRCDEVICE.RunComputation("Luminance Compute CS Final", *avgLuminanceShader, pp_luminance_downsample, 1, 1, 1);
|
|
|
|
# if __D3D11 || RSG_ORBIS
|
|
GRCDEVICE.SynchronizeComputeToGraphics();
|
|
# endif
|
|
}
|
|
else
|
|
{
|
|
#endif //AVG_LUMINANCE_COMPUTE
|
|
// Initial downsample luminance pass
|
|
SetNonDepthFXStateBlocks();
|
|
PostFXShader->SetVar(TextureID_v0, BloomBufferQuarterDS);
|
|
PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/float(BloomBufferQuarterDS->GetWidth()),1.0f/float(BloomBufferQuarterDS->GetHeight()), float(BloomBufferQuarterDS->GetWidth()), float(BloomBufferQuarterDS->GetHeight())));
|
|
|
|
Vector4 lumDownsampleSrcDstOOSize = Vector4(1.0f/float(BloomBufferQuarterDS->GetWidth()), 1.0f/float(BloomBufferQuarterDS->GetHeight()), 1.0f/float(PostFX::LumDownsampleRT[0]->GetWidth()), 1.0f/float(PostFX::LumDownsampleRT[0]->GetHeight()));
|
|
#if (RSG_PC)
|
|
for (int i = 0; i < PostFX::ImLumDownsampleRTCount; i++)
|
|
{
|
|
if(i != 0)
|
|
{
|
|
PostFXShader->SetVar(TextureID_0,PostFX::ImLumDownsampleRT[i-1]);
|
|
PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/float(PostFX::ImLumDownsampleRT[i-1]->GetWidth()),1.0f/float(PostFX::ImLumDownsampleRT[i-1]->GetHeight()),0.0, 0.0f));
|
|
}
|
|
|
|
PostFXBlit(PostFX::ImLumDownsampleRT[i], PostFXTechnique, pp_max, false, false);
|
|
}
|
|
if(PostFX::ImLumDownsampleRTCount > 0)
|
|
{
|
|
PostFXShader->SetVar(TextureID_v0, PostFX::ImLumDownsampleRT[PostFX::ImLumDownsampleRTCount-1]);
|
|
lumDownsampleSrcDstOOSize = Vector4(1.0f/float(PostFX::ImLumDownsampleRT[PostFX::ImLumDownsampleRTCount-1]->GetWidth()), 1.0f/float(PostFX::ImLumDownsampleRT[PostFX::ImLumDownsampleRTCount-1]->GetHeight()), 1.0f/float(PostFX::LumDownsampleRT[0]->GetWidth()), 1.0f/float(PostFX::LumDownsampleRT[0]->GetHeight()));
|
|
}
|
|
#endif //(RSG_PC && !AVG_LUMINANCE_COMPUTE)
|
|
PostFXShader->SetVar(LuminanceDownsampleOOSrcDstSizeId, lumDownsampleSrcDstOOSize);
|
|
PostFXBlit(PostFX::LumDownsampleRT[0], PostFXTechnique, LumDownsamplePass[0], false, false, NULL, true);
|
|
|
|
// Luminance downsample passes down to 1x1
|
|
for (int i = 1; i < PostFX::LumDownsampleRTCount; i++)
|
|
{
|
|
SetNonDepthFXStateBlocks();
|
|
Vector4 lumDownsampleSrcDstOOSize = Vector4(
|
|
1.0f / float(PostFX::LumDownsampleRT[i-1]->GetWidth()), 1.0f / float(PostFX::LumDownsampleRT[i-1]->GetHeight()),
|
|
1.0f / float(PostFX::LumDownsampleRT[i-0]->GetWidth()), 1.0f / float(PostFX::LumDownsampleRT[i-0]->GetHeight()));
|
|
PostFXShader->SetVar(LuminanceDownsampleOOSrcDstSizeId, lumDownsampleSrcDstOOSize);
|
|
PostFXShader->SetVar(TextureID_v0, PostFX::LumDownsampleRT[i-1]);
|
|
PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/float(PostFX::LumDownsampleRT[i-1]->GetWidth()),1.0f/float(PostFX::LumDownsampleRT[i-1]->GetHeight()), 0.0, 0.0f));
|
|
PostFXBlit(PostFX::LumDownsampleRT[i], PostFXTechnique, LumDownsamplePass[i], false, false, NULL, true);
|
|
}
|
|
#if AVG_LUMINANCE_COMPUTE
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
#if USE_NV_TXAA
|
|
void CopyToNvMatrix2(const Mat44V& mIn, gfsdk_float4x4& mOut)
|
|
{
|
|
mOut._11 = mIn.GetM00f();
|
|
mOut._21 = mIn.GetM10f();
|
|
mOut._31 = mIn.GetM20f();
|
|
mOut._41 = mIn.GetM30f();
|
|
|
|
mOut._12 = mIn.GetM01f();
|
|
mOut._22 = mIn.GetM11f();
|
|
mOut._32 = mIn.GetM21f();
|
|
mOut._42 = mIn.GetM31f();
|
|
|
|
mOut._13 = mIn.GetM02f();
|
|
mOut._23 = mIn.GetM12f();
|
|
mOut._33 = mIn.GetM22f();
|
|
mOut._43 = mIn.GetM32f();
|
|
|
|
mOut._14 = mIn.GetM03f();
|
|
mOut._24 = mIn.GetM13f();
|
|
mOut._34 = mIn.GetM23f();
|
|
mOut._44 = mIn.GetM33f();
|
|
}
|
|
|
|
template <class T>
|
|
#ifdef DEBUG
|
|
void AssertDXInterfaceType(IUnknown* pI)
|
|
{
|
|
T* pCast = NULL;
|
|
HRESULT hr = pI->QueryInterface(_uuidof(T), (void**)&pCast);
|
|
Assert(SUCCEEDED(hr));
|
|
}
|
|
#else
|
|
void AssertDXInterfaceType(IUnknown*) {}
|
|
#endif
|
|
|
|
bool PostFX::IsTXAAAvailable()
|
|
{
|
|
const bool isNV = GRCDEVICE.GetManufacturer() == NVIDIA;
|
|
const bool isDX11 = GRCDEVICE.GetDxFeatureLevel() >= 1100;
|
|
const bool isMSAA = GRCDEVICE.GetMSAA() == grcDevice::MSAA_2 || GRCDEVICE.GetMSAA() == grcDevice::MSAA_4;
|
|
const bool isSupportedByCard = GRCDEVICE.GetTXAASupported();
|
|
return ( isNV && isDX11 && isMSAA && isSupportedByCard );
|
|
}
|
|
|
|
static void ResolveTXAA(grcRenderTarget* pColourDst, grcRenderTargetMSAA* pColourSrc)
|
|
{
|
|
ID3D11ShaderResourceView* pSrcSRV = pColourSrc->GetTextureView();
|
|
|
|
grcRenderTargetDX11* hackyCastDst = reinterpret_cast<grcRenderTargetDX11*>(pColourDst);
|
|
const grcDeviceView* devView = hackyCastDst->GetTargetView();
|
|
ID3D11RenderTargetView* pDstRTV = reinterpret_cast<ID3D11RenderTargetView*>(const_cast<grcDeviceView*>(devView));
|
|
|
|
// TXAA works best with a min depth resolve. Using the debugger, depth seems to be resolved *three* times per frame.
|
|
// The last one to this target does appear to be a min resolve. It's not clear how to guarantee min without redundantly
|
|
// resolving depth here ourselves or redesigning the interface to track the contents of the resolved target.
|
|
ID3D11ShaderResourceView* pDepthSRV = CRenderTargets::GetDepthResolved()->GetTextureView();
|
|
|
|
// We need a casting frenzy from Rage types to DX above. Paranoid check that it worked.
|
|
AssertDXInterfaceType<ID3D11DeviceContext>(rage::g_grcCurrentContext);
|
|
AssertDXInterfaceType<ID3D11RenderTargetView>(pDstRTV);
|
|
AssertDXInterfaceType<ID3D11ShaderResourceView>(pSrcSRV);
|
|
AssertDXInterfaceType<ID3D11ShaderResourceView>(pDepthSRV);
|
|
AssertDXInterfaceType<ID3D11ShaderResourceView>(pSrcSRV);
|
|
|
|
grcViewport* vp = grcViewport::GetCurrent();
|
|
if (vp != NULL)
|
|
{
|
|
Mat44V_ConstRef view = vp->GetViewMtx();
|
|
Mat44V_ConstRef proj = vp->GetProjection();
|
|
Mat44V viewProj;
|
|
Multiply(viewProj,proj,view);
|
|
|
|
// TBD: the previous view proj matrix probably shouldn't be a local static.
|
|
gfsdk_float4x4 nvViewProj;
|
|
CopyToNvMatrix2(viewProj, nvViewProj);
|
|
static gfsdk_float4x4 oldNvViewProj = nvViewProj;
|
|
|
|
const gfsdk_F32 w = (gfsdk_F32) pColourSrc->GetWidth();
|
|
const gfsdk_F32 h = (gfsdk_F32) pColourSrc->GetHeight();
|
|
|
|
// We need a copy of the previous frame's TXAA output.
|
|
ID3D11ShaderResourceView* pPreviousSRV = g_TXAAResolve->GetTextureView();
|
|
|
|
// If the dev mode is not TXAA_MODE_TOTAL, then use that. Otherwise, choose a mode based on the MSAA count.
|
|
gfsdk_U32 mode = g_TXAADevMode;
|
|
if (mode == TXAA_MODE_TOTAL)
|
|
{
|
|
switch (GRCDEVICE.GetMSAA())
|
|
{
|
|
// z_2x and z_4x are the only valid non-dev modes (m could be but we are not supplying motion vectors from the game.
|
|
case 2: mode = TXAA_MODE_Z_2xTXAA; break;
|
|
case 4: mode = TXAA_MODE_Z_4xTXAA; break;
|
|
}
|
|
}
|
|
|
|
D3DPERF_BeginEvent(D3DCOLOR_ARGB(0,0,0,0), L"NV TXAA resolve");
|
|
TxaaResolveDX(&g_txaaContext, rage::g_grcCurrentContext,
|
|
pDstRTV, // Destination texture.
|
|
pSrcSRV, // Source MSAA texture shader resource view.
|
|
pDepthSRV, // Source motion vector or depth texture SRV.
|
|
pPreviousSRV, // SRV to destination from prior frame.
|
|
mode, // TXAA_MODE_* select TXAA resolve mode.
|
|
w, // Source/destination texture dimensions in pixels.
|
|
h,
|
|
0.1f, // first depth position 0-1 in Z buffer
|
|
0.9f, // second depth position 0-1 in Z buffer
|
|
0.125f, // first depth position motion limit in pixels
|
|
32.0f, // second depth position motion limit in pixels
|
|
&(nvViewProj._11), // matrix for world to view projection (current frame)
|
|
&(oldNvViewProj._11)); // matrix for world to view projection (prior frame)
|
|
D3DPERF_EndEvent();
|
|
|
|
oldNvViewProj = nvViewProj;
|
|
|
|
// going nuclear on cached states.
|
|
GRCDEVICE.ResetContext();
|
|
GRCDEVICE.ClearCachedState();
|
|
|
|
grcStateBlock::MakeDirty();
|
|
|
|
PIXBegin(0, "NV TXAA copy result");
|
|
|
|
NVDX_ObjectHandle pNvAPIObj = 0;
|
|
ID3D11Device* pDev = NULL;
|
|
g_grcCurrentContext->GetDevice(&pDev);
|
|
|
|
if (pDev)
|
|
{
|
|
// We indicate to the driver when we start and end rendering to g_TXAAResolve. If the driver knows when we
|
|
// have finished updating this resource for the frame, it can "early push" it to other GPUs in the system.
|
|
NvAPI_D3D_GetObjectHandleForResource(pDev, g_TXAAResolve->GetTexturePtr(), &pNvAPIObj);
|
|
if (pNvAPIObj)
|
|
NvAPI_D3D_BeginResourceRendering(pDev, pNvAPIObj, NVAPI_D3D_RR_FLAG_FORCE_KEEP_CONTENT);
|
|
}
|
|
|
|
Assert(g_TXAAResolve != NULL);
|
|
g_TXAAResolve->Copy(pColourDst);
|
|
if (pDev && pNvAPIObj)
|
|
NvAPI_D3D_EndResourceRendering(pDev, pNvAPIObj, 0);
|
|
PIXEnd();
|
|
}
|
|
|
|
}
|
|
#endif // USE_NV_TXAA
|
|
|
|
#if RSG_PC
|
|
void PostFX::DoPauseResolve(PostFX::eResolvePause PauseState)
|
|
{
|
|
if ( CLandingPageArbiter::ShouldGameRunLandingPageUpdate() && (PauseState == UNRESOLVE_PAUSE) && (g_DoPauseResolve != IN_RESOLVE_PAUSE) && GRCDEVICE.UsingMultipleGPUs())
|
|
return;
|
|
|
|
g_DoPauseResolve = PauseState;
|
|
}
|
|
|
|
PostFX::eResolvePause PostFX::GetPauseResolve()
|
|
{
|
|
return g_DoPauseResolve;
|
|
}
|
|
#endif
|
|
|
|
void PostFX::ProcessNonDepthFX()
|
|
{
|
|
PF_AUTO_PUSH_TIMEBAR("PostFX::ProcessNonDepthFX");
|
|
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
// KS/AH - we used to wait for flip HERE!.
|
|
|
|
#if RSG_PC
|
|
CShaderLib::SetStereoTexture();
|
|
#endif
|
|
|
|
PF_PUSH_TIMEBAR("Initialize Exposure");
|
|
if (!ExposureInitialised)
|
|
{
|
|
grcTextureLock lock;
|
|
for (int i = 0; i < MAX_EXP_TARGETS; i++)
|
|
{
|
|
#if __D3D11
|
|
grcTextureD3D11* currentTarget = (grcTextureD3D11*)CurExposureTex[i];
|
|
currentTarget->UpdateCPUCopy();
|
|
#else
|
|
grcRenderTarget* currentTarget = CurExposureRT[i];
|
|
#endif
|
|
|
|
#if RSG_PC
|
|
if(currentTarget->MapStagingBufferToBackingStore(true))
|
|
{
|
|
#endif
|
|
if (currentTarget->LockRect(0,0,lock,grcsWrite))
|
|
{
|
|
float* currentRT = (float*)lock.Base;
|
|
currentRT[0] = 0.0f;
|
|
currentRT[1] = 0.0f;
|
|
currentRT[2] = 0.0f;
|
|
currentRT[3] = 0.0f;
|
|
currentTarget->UnlockRect(lock);
|
|
}
|
|
#if RSG_PC
|
|
}
|
|
#endif
|
|
}
|
|
|
|
ExposureInitialised = true;
|
|
}
|
|
PF_POP_TIMEBAR(); //"Initialize Exposure"
|
|
|
|
if( CPauseMenu::GetPauseRenderPhasesStatus() )
|
|
{
|
|
#if PTFX_APPLY_DOF_TO_PARTICLES
|
|
if (CPtFxManager::UseParticleDOF())
|
|
g_ptFxManager.ClearPtfxDepthAlphaMap();
|
|
#endif //PTFX_APPLY_DOF_TO_PARTICLES
|
|
}
|
|
|
|
CShaderLib::UpdateGlobalGameScreenSize();
|
|
|
|
#if DEVICE_MSAA
|
|
//We need the min depth here for the adaptive dof and depth of field blur.
|
|
if( GRCDEVICE.GetMSAA()>1)
|
|
CRenderTargets::ResolveDepth(depthResolve_Closest);
|
|
#endif
|
|
|
|
GRC_ALLOC_SCOPE_AUTO_PUSH_POP()
|
|
|
|
|
|
#if DOF_TYPE_CHANGEABLE_IN_RAG
|
|
if( ProcessDOFChangeOnRenderThread )
|
|
ProcessDOFChangeRenderThread();
|
|
#endif
|
|
|
|
grcStateBlock::SetRasterizerState(nonDepthFXRasterizerState);
|
|
grcStateBlock::SetBlendState(nonDepthFXBlendState);
|
|
grcStateBlock::SetDepthStencilState(nonDepthFXDepthStencilState);
|
|
|
|
int rb=gRenderThreadInterface.GetRenderBuffer();
|
|
|
|
const bool bUseExtraEffects = AreExtraEffectsActive();
|
|
const bool bExtraEffectsBlur = ExtraEffectsRequireBlur();
|
|
|
|
const PostFXParamBlock::paramBlock& settings = PostFXParamBlock::GetRenderThreadParams();
|
|
|
|
// scanline filter
|
|
Vector4 scanlineParams;
|
|
GetScanlineParams(settings, scanlineParams);
|
|
PostFXShader->SetVar(ScanlineFilterParamsId, scanlineParams);
|
|
|
|
float screenBlurFadeLevel = settings.m_screenBlurFade;
|
|
|
|
// screen blur fade
|
|
if (g_screenBlurFade.IsPlaying())
|
|
{
|
|
screenBlurFadeLevel = Lerp(g_screenBlurFade.GetFadeLevel(), screenBlurFadeLevel, 1.0f);
|
|
}
|
|
|
|
PostFXShader->SetVar(ScreenBlurFadeID, screenBlurFadeLevel);
|
|
|
|
PostFX::SetLDR16bitHDR16bit();
|
|
|
|
PostFXShader->SetVar(GBufferTextureId0, GBuffer::GetTarget(GBUFFER_RT_0));
|
|
PostFXShader->SetVar(GBufferTextureIdDepth, CRenderTargets::GetDepthBuffer());
|
|
|
|
Matrix44 MBPrevViewProjMatrix = MotionBlurPrevViewProjMatrix[rb];
|
|
|
|
// transpose so we can simply dot vectors in shader
|
|
MBPrevViewProjMatrix.Transpose();
|
|
|
|
PostFXShader->SetVar(MBPrevViewProjMatrixXId, MBPrevViewProjMatrix.a);
|
|
PostFXShader->SetVar(MBPrevViewProjMatrixYId, MBPrevViewProjMatrix.b);
|
|
PostFXShader->SetVar(MBPrevViewProjMatrixWId, MBPrevViewProjMatrix.d);
|
|
|
|
Vec4V projParams;
|
|
Vec3V shearProj0, shearProj1, shearProj2;
|
|
DeferredLighting::GetProjectionShaderParams(projParams, shearProj0, shearProj1, shearProj2);
|
|
|
|
PostFXShader->SetVar(MBPerspectiveShearParams0Id, shearProj0);
|
|
PostFXShader->SetVar(MBPerspectiveShearParams1Id, shearProj1);
|
|
PostFXShader->SetVar(MBPerspectiveShearParams2Id, shearProj2);
|
|
|
|
// Reduce blur length to compensate for low framerate
|
|
const float lengthReduction = Clamp((1.0f/30.0f)/settings.m_timeStep,0.0f,1.0f);
|
|
|
|
Vector4 motionBlurParams( settings.m_directionalBlurLength*lengthReduction,
|
|
settings.m_directionalBlurGhostingFade,
|
|
1.0f,
|
|
1.0f);
|
|
|
|
const float motionBlurNumSamples = WIN32PC_ONLY((CSettingsManager::GetInstance().GetSettings().m_graphics.m_PostFX >= CSettings::Ultra) ? 16.0f :) 6.0f;
|
|
Vector4 motionBlurSamplesParams( motionBlurNumSamples, 1.0f / motionBlurNumSamples, 0.0f, 0.0f);
|
|
|
|
PostFXShader->SetVar( DirectionalMotionBlurParamsId, motionBlurParams);
|
|
PostFXShader->SetVar( DirectionalMotionBlurIterParamsId, motionBlurSamplesParams );
|
|
|
|
BANK_ONLY(SetDebugParams();)
|
|
|
|
const bool hasMotionBlur = IsMotionBlurEnabled();
|
|
const bool hasHeatHaze0 = (settings.m_HeatHazeOffsetParams.x != 0.0f || settings.m_HeatHazeOffsetParams.y != 0.0f)
|
|
&& !camInterface::GetDebugDirector().IsFreeCamActive()
|
|
#if __BANK
|
|
&& IsTiledScreenCaptureOrPanorama()==false
|
|
#endif // __BANK
|
|
;
|
|
|
|
bool hasHeatHaze1 = true;
|
|
if (Water::IsCameraUnderwater())
|
|
{
|
|
// disable HeatHaze for stromberg when underwater in first person camera mode (B*4119583 - Stromberg - Water camera effect in first person mode):
|
|
if(camInterface::IsDominantRenderedCameraAnyFirstPersonCamera())
|
|
{
|
|
CPed *pPlayerPed = CGameWorld::FindLocalPlayer();
|
|
if (pPlayerPed)
|
|
{
|
|
CVehicle *pVehicle = pPlayerPed->GetVehiclePedInside();
|
|
if(pVehicle)
|
|
{
|
|
if(pVehicle->GetVehicleType()==VEHICLE_TYPE_SUBMARINECAR)
|
|
{
|
|
hasHeatHaze1 = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const bool hasHeatHaze = hasHeatHaze0 && hasHeatHaze1;
|
|
|
|
|
|
|
|
#if __PS3 || __XENON || RSG_ORBIS || __D3D11
|
|
u32 prevIndex = ((CurExportRTIndex - 1) + NUM_EXP_TARGETS) % NUM_EXP_TARGETS;
|
|
#endif
|
|
|
|
#if RSG_ORBIS
|
|
grcTextureLock lock;
|
|
if (CurExposureRT[prevIndex]->LockRect(0,0,lock,grcsRead))
|
|
{
|
|
float* currentRT = (float*)lock.Base;
|
|
|
|
g_adaptation.SetRenderPowTwoExposure(currentRT[0]);
|
|
g_adaptation.SetRenderExposure(currentRT[1]);
|
|
g_adaptation.SetRenderTargetExposure(currentRT[2]);
|
|
g_adaptation.SetRenderLum(currentRT[3]);
|
|
|
|
PF_SET(RenderExposure, currentRT[1]);
|
|
CurExposureRT[prevIndex]->UnlockRect(lock);
|
|
}
|
|
#endif
|
|
|
|
#if RSG_DURANGO
|
|
grcTextureD3D11* currentTarget = (grcTextureD3D11*)CurExposureTex[prevIndex];
|
|
currentTarget->UpdateCPUCopy();
|
|
|
|
grcTextureLock lock;
|
|
if (currentTarget->LockRect(0,0, lock, grcsRead))
|
|
{
|
|
float* currentRT = (float*)lock.Base;
|
|
|
|
g_adaptation.SetRenderPowTwoExposure(currentRT[0]);
|
|
g_adaptation.SetRenderExposure(currentRT[1]);
|
|
g_adaptation.SetRenderTargetExposure(currentRT[2]);
|
|
g_adaptation.SetRenderLum(currentRT[3]);
|
|
|
|
PF_SET(RenderExposure, currentRT[1]);
|
|
currentTarget->UnlockRect(lock);
|
|
}
|
|
#endif
|
|
|
|
#if RSG_PC
|
|
if (!GRCDEVICE.UsingMultipleGPUs() || g_forceExposureReadback)
|
|
{
|
|
PF_PUSH_TIMEBAR_BUDGETED("PostFX - Cur Exp GPU Read Back", 0.4f);
|
|
|
|
ASSERT_ONLY(bool targetLocked = false;)
|
|
for( u32 i = 0; i < NUM_EXP_TARGETS; i++ )
|
|
{
|
|
prevIndex = ((CurExportRTIndex - (1+i)) + NUM_EXP_TARGETS) % NUM_EXP_TARGETS;
|
|
|
|
grcTextureD3D11* currentTarget = (grcTextureD3D11*)CurExposureTex[prevIndex];
|
|
if( currentTarget->MapStagingBufferToBackingStore(true) )
|
|
{
|
|
grcTextureLock lock;
|
|
if (currentTarget->LockRect( 0, 0, lock, grcsRead ))
|
|
{
|
|
float* currentRT = (float*)lock.Base;
|
|
|
|
g_adaptation.SetRenderPowTwoExposure(currentRT[0]);
|
|
g_adaptation.SetRenderExposure(currentRT[1]);
|
|
g_adaptation.SetRenderTargetExposure(currentRT[2]);
|
|
g_adaptation.SetRenderLum(currentRT[3]);
|
|
|
|
PF_SET(RenderExposure, currentRT[1]);
|
|
|
|
currentTarget->UnlockRect(lock);
|
|
ASSERT_ONLY(targetLocked = true;)
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
PF_POP_TIMEBAR();
|
|
#if __ASSERT
|
|
if(!targetLocked)
|
|
Warningf("Failed to find an exposure target that wasnt being rendered to");
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
// Temporary fix while I work out WHY we have bad frames sometimes
|
|
if (g_adaptation.GetRenderExposure() != g_adaptation.GetRenderExposure() &&
|
|
g_adaptation.GetRenderExposure() > 100.0f)
|
|
{
|
|
renderWarningf("We got QNANs in the exposur RT again");
|
|
g_adaptation.SetRenderPowTwoExposure(1.0f);
|
|
g_adaptation.SetRenderExposure(0.0f);
|
|
g_adaptation.SetRenderTargetExposure(0.0f);
|
|
g_adaptation.SetRenderLum(1.0f);
|
|
}
|
|
|
|
PostFX::g_prevExposureRT = CurExposureRT[CurExportRTIndex];
|
|
CurExportRTIndex = (CurExportRTIndex + 1) % NUM_EXP_TARGETS;
|
|
PostFX::g_currentExposureRT = CurExposureRT[CurExportRTIndex];
|
|
|
|
#if __D3D11 || RSG_ORBIS
|
|
|
|
const grcTexture *backBuffer = CRenderTargets::GetBackBuffer();
|
|
#if DEVICE_MSAA
|
|
if( GRCDEVICE.GetMSAA()>1)
|
|
{
|
|
bool doResolve = true;
|
|
//When we go into the pause menu dont resolve the backbuffer to keep the original unchanged
|
|
//otherwise the backbuffer gets progressively more blurred by the dof msaa blend.
|
|
if(DRAWLISTMGR->IsExecutingHudDrawList() || CLoadingScreens::AreActive())
|
|
{
|
|
doResolve = false;
|
|
}
|
|
|
|
backBuffer = CRenderTargets::GetBackBufferCopy(doResolve);
|
|
}
|
|
#endif //DEVICE_MSAA
|
|
#elif __PPU
|
|
grcRenderTarget *backBuffer = CRenderTargets::GetBackBuffer();
|
|
#elif __XENON
|
|
grcRenderTarget *backBuffer = g_UsePacked7e3IntBackBuffer ? CRenderTargets::GetBackBuffer7e3toInt(false) : grcTextureFactory::GetInstance().GetBackBuffer();
|
|
#else
|
|
#error "[PostFX] Missed a platform in back-buffer selection"
|
|
#endif
|
|
|
|
// downsample to quarter-size screen
|
|
const PostFXPass downSamplePass = (hasMotionBlur ? pp_DownSampleStencil : pp_passthrough);
|
|
|
|
SetExposureParams();
|
|
SetNonDepthFXStateBlocks();
|
|
PostFXShader->SetVar(TextureID_0, backBuffer);
|
|
PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/float(backBuffer->GetWidth()),1.0f/float(backBuffer->GetHeight()), 0.0, 0.0f));
|
|
#if __D3D11 || RSG_ORBIS
|
|
PostFXShader->SetVar(StencilCopyTextureId, CRenderTargets::GetDepthBuffer_Stencil());
|
|
#endif
|
|
PostFXBlit(HalfScreen0, PostFXTechnique, downSamplePass);
|
|
|
|
#if RSG_PC
|
|
// compute center
|
|
if (GRCDEVICE.IsStereoEnabled() && GRCDEVICE.CanUseStereo())
|
|
{
|
|
CPed *pPlayerPed = CGameWorld::FindLocalPlayer();
|
|
if (pPlayerPed && pPlayerPed->GetPlayerInfo() && camInterface::GetDominantRenderedCamera())
|
|
{
|
|
CPlayerPedTargeting& rTargeting = pPlayerPed->GetPlayerInfo()->GetTargeting();
|
|
const Vector3 aimDir = rTargeting.GetFreeAimTargetDir();
|
|
|
|
const Vector3 aimDirT = camInterface::GetDominantRenderedCamera()->GetFrame().GetFront();
|
|
(void)aimDirT;
|
|
|
|
const PostFXPass centerDist = pp_centerdist;
|
|
|
|
PostFXShader->SetVar(ResolvedTextureIdDepth, CRenderTargets::GetDepthResolved());
|
|
|
|
PostFXShader->SetVar(globalFreeAimDirId, Vector4(/*aimDir*/aimDirT));
|
|
PostFXBlit(CenterReticuleDist, PostFXTechnique, centerDist);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if __XENON
|
|
//set LDR exp bias for 7e3 format
|
|
GRCDEVICE.SetColorExpBiasNow(CRenderer::GetBackbufferColorExpBiasLDR());
|
|
#endif
|
|
|
|
// Compute Luminance
|
|
ComputeLuminance();
|
|
|
|
// Exposure
|
|
SetExposureParams();
|
|
SetNonDepthFXStateBlocks();
|
|
|
|
#if __BANK
|
|
if (g_AutoExposureSkip || IsTiledScreenCaptureOrPanorama())
|
|
{
|
|
PostFXBlit(g_currentExposureRT, PostFXTechnique, pp_exposure_set);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
if (settings.m_adaptationResetRequired)
|
|
{
|
|
PostFXBlit(g_currentExposureRT, PostFXTechnique, pp_exposure_reset);
|
|
}
|
|
else
|
|
{
|
|
PostFXBlit(g_currentExposureRT, PostFXTechnique, pp_exposure);
|
|
}
|
|
}
|
|
|
|
#if RSG_PC
|
|
grcTextureD3D11* UpdateContentsTarget = (grcTextureD3D11*)CurExposureTex[CurExportRTIndex];
|
|
UpdateContentsTarget->CopyFromGPUToStagingBuffer();
|
|
#endif // RSG_PC
|
|
|
|
// process high DOF
|
|
const Vector4 projParamsA = ShaderUtil::CalculateProjectionParams();
|
|
PostFXShader->SetVar(DofProjId, projParamsA);
|
|
|
|
grcRenderTarget* pDOFLargeBlur = NULL;
|
|
grcRenderTarget* pDOFMedBlur = NULL;
|
|
Vector4 hiDofMiscParams;
|
|
#if ADAPTIVE_DOF_GPU && ADAPTIVE_DOF_OUTPUT_UAV
|
|
AdaptiveDepthOfField.InitiliaseOnRenderThread();
|
|
#endif //ADAPTIVE_DOF_OUTPUT_UAV
|
|
if (settings.m_HighDof || settings.m_AdaptiveDof || bExtraEffectsBlur)
|
|
{
|
|
PostFXShader->SetVar(TextureID_v1, g_prevExposureRT);
|
|
hiDofMiscParams.x = settings.m_hiDofParameters.y;
|
|
hiDofMiscParams.y = settings.m_hiDofParameters.z;
|
|
ProcessHighDOFBuffers(settings, pDOFLargeBlur, pDOFMedBlur, g_currentExposureRT, screenBlurFadeLevel);
|
|
}
|
|
|
|
if (hasHeatHaze)
|
|
{
|
|
ProcessHeatHazeBuffers(settings);
|
|
}
|
|
|
|
grcViewport *vp = grcViewport::GetCurrent();
|
|
|
|
if( true == settings.m_nightVision )
|
|
{
|
|
PostFXShader->SetVar(lowLumId, settings.m_lowLum);
|
|
PostFXShader->SetVar(highLumId, settings.m_highLum);
|
|
PostFXShader->SetVar(topLumId, settings.m_topLum);
|
|
|
|
PostFXShader->SetVar(scalerLumId, settings.m_scalerLum);
|
|
|
|
PostFXShader->SetVar(offsetLumId, settings.m_offsetLum);
|
|
PostFXShader->SetVar(offsetLowLumId, settings.m_offsetLowLum);
|
|
PostFXShader->SetVar(offsetHighLumId, settings.m_offsetHighLum);
|
|
|
|
float noiseLum = (true == g_noiseOverride) ? g_noisinessOverride : settings.m_noiseLum;
|
|
float noiseLowLum = (true == g_noiseOverride) ? g_noisinessOverride : settings.m_noiseLowLum;
|
|
float noiseHighLum = (true == g_noiseOverride) ? g_noisinessOverride : settings.m_noiseHighLum;
|
|
|
|
PostFXShader->SetVar(noiseLumId, noiseLum);
|
|
PostFXShader->SetVar(noiseLowLumId, noiseLowLum);
|
|
PostFXShader->SetVar(noiseHighLumId, noiseHighLum);
|
|
|
|
PostFXShader->SetVar(bloomLumId, settings.m_bloomLum);
|
|
|
|
PostFXShader->SetVar(colorLumId, settings.m_colorLum);
|
|
PostFXShader->SetVar(colorLowLumId, settings.m_colorLowLum);
|
|
PostFXShader->SetVar(colorHighLumId, settings.m_colorHighLum);
|
|
}
|
|
|
|
SetFilmicParams();
|
|
|
|
PostFXShader->SetVar(TextureID_v1, g_currentExposureRT);
|
|
|
|
SetBloomParams();
|
|
PostFXShader->SetVar(ColorCorrectId, settings.m_colorCorrect);
|
|
|
|
#if FILM_EFFECT
|
|
PostFXShader->SetVar(LensDistortionId, Vector4(g_BaseDistortionCoefficient, g_BaseCubeDistortionCoefficient, g_ChromaticAberrationOffset, g_ChromaticAberrationCubeOffset));
|
|
#endif
|
|
|
|
PostFXShader->SetVar(ColorShiftId, settings.m_colorShift);
|
|
PostFXShader->SetVar(DesaturateId, settings.m_deSaturate);
|
|
PostFXShader->SetVar(GammaId, settings.m_gamma);
|
|
PostFXShader->SetVar(sslrParamsId, Vector4(0.0f, 0.0f,0.0f, 0.0f)); // disable intensity buffer in final combines
|
|
|
|
Vector4 noiseParams;
|
|
GetNoiseParams(settings, noiseParams);
|
|
|
|
#if __BANK
|
|
for (int i = 0; i < NUM_DEBUG_PARAMS; i++)
|
|
{
|
|
PostFXShader->SetVar(DebugParamsId[i], DebugParams[i]);
|
|
}
|
|
#endif
|
|
bool bBloomEnabled = true;
|
|
#if __BANK
|
|
bBloomEnabled = g_bloomEnable;
|
|
#endif // __BANK
|
|
#if RSG_PC
|
|
bBloomEnabled &= (GET_POSTFX_SETTING(CSettingsManager::GetInstance().GetSettings().m_graphics.m_PostFX) >= CSettings::Medium) ? true : false;
|
|
#endif // RSG_PC
|
|
|
|
if( settings.m_seeThrough )
|
|
{
|
|
PostFXShader->SetVar(GBufferTextureIdSSAODepth, SSAO::GetSSAOTexture());
|
|
|
|
#if __D3D11 || RSG_ORBIS
|
|
PostFXShader->SetVar(StencilCopyTextureId, CRenderTargets::GetDepthBuffer_Stencil());
|
|
#endif // __XENON
|
|
|
|
CShaderLib::ForceScalarGlobals2(settings.m_SeeThroughDepthParams);
|
|
|
|
SetSrcTextureAndSize(BloomTextureID, RenderPhaseSeeThrough::GetColorRT());
|
|
SetNonDepthFXStateBlocks();
|
|
PostFXBlit(RenderPhaseSeeThrough::GetBlurRT(), PostFXTechnique, pp_calcbloom_seethrough);
|
|
|
|
SetSrcTextureAndSize(BloomTextureGID, RenderPhaseSeeThrough::GetBlurRT());
|
|
SetNonDepthFXStateBlocks();
|
|
PostFXBlit(RenderPhaseSeeThrough::GetColorRT(), PostFXTechnique, pp_calcbloom1);
|
|
}
|
|
else if (settings.m_lightRaysActive)
|
|
{
|
|
PostFXShader->SetVar(GBufferTextureIdSSAODepth, CRenderTargets::GetDepthBufferQuarterLinear());
|
|
|
|
if (g_pNoiseTexture!=NULL) //lightrays now use noise
|
|
{
|
|
PostFXShader->SetVar(TextureID_1, g_pNoiseTexture);
|
|
PostFXShader->SetVar(NoiseParamsId, noiseParams);
|
|
}
|
|
//new light ray control params
|
|
SetSrcTextureAndSize(BloomTextureID, BloomBufferQuarter0);
|
|
|
|
bool useUnderwater = Water::IsCameraUnderwater();
|
|
|
|
#if __BANK
|
|
useUnderwater=useUnderwater||g_ForceUnderWaterTech;
|
|
useUnderwater=useUnderwater&&!g_ForceAboveWaterTech;
|
|
#endif //__BANK
|
|
|
|
useUnderwater = useUnderwater && !CLoadingScreens::AreActive();
|
|
|
|
Vector4 lightRayParams = settings.m_lightrayParams;
|
|
if(useUnderwater)
|
|
{
|
|
const CLightSource &dirLight = Lights::GetRenderDirectionalLight();
|
|
float brightness = Max(-dirLight.GetDirection().GetZ(), 0.0f);
|
|
Vector4 underwaterParamsMask = Vector4(brightness, brightness, brightness, 1.0f);
|
|
lightRayParams *= underwaterParamsMask;
|
|
}
|
|
PostFXShader->SetVar(lightrayParamsId, lightRayParams);
|
|
|
|
PostFXShader->SetVar(sslrParamsId, Vector4(settings.m_sslrParams.x, settings.m_sslrParams.z, 1.0f, vp->GetFarClip()));
|
|
BANK_ONLY(SetDebugParams();)
|
|
|
|
grcRenderTarget *sslrRT = NULL;
|
|
if(useUnderwater)
|
|
{
|
|
grcRenderTarget* mini = CRenderPhaseCascadeShadowsInterface::GetShadowMapMini();
|
|
|
|
CRenderPhaseCascadeShadowsInterface::SetSharedShadowMap(mini);
|
|
|
|
static dev_float timeScale=0.01f;
|
|
PostFXShader->SetVar(lightrayParams2Id, Vector4(Water::GetWaterLevel() + 1.0f, TIME.GetElapsedTime()*timeScale, 0.0f, 0.0f));
|
|
PostFXShader->SetVar(TextureID_v1, g_currentExposureRT);
|
|
|
|
SetNonDepthFXStateBlocks();
|
|
PostFXBlit(LRIntensity2, PostFXTechnique, pp_lightrays1);
|
|
|
|
// need to blur the buffer to blend the dithered lightray samples
|
|
SetSrcTextureAndSize(BloomTextureID, LRIntensity2);
|
|
SetNonDepthFXStateBlocks();
|
|
PostFXBlit(LRIntensity, PostFXTechnique, pp_sslrblur);
|
|
|
|
// do the max blur filter to reduce haloing
|
|
SetSrcTextureAndSize(BloomTextureID, LRIntensity);
|
|
SetNonDepthFXStateBlocks();
|
|
PostFXBlit(LRIntensity2, PostFXTechnique, pp_maxx);
|
|
SetSrcTextureAndSize(BloomTextureID, LRIntensity2);
|
|
PostFXBlit(LRIntensity, PostFXTechnique, pp_maxy);
|
|
|
|
if (bBloomEnabled)
|
|
{
|
|
PrimeBloomBufferFrom(backBuffer);
|
|
}
|
|
sslrRT = LRIntensity;
|
|
}
|
|
else
|
|
{
|
|
PF_PUSH_MARKER("sslr");
|
|
const Matrix34 &camMatrix = RCC_MATRIX34(vp->GetCameraMtx());
|
|
|
|
Vector3 position = (settings.m_SunDirection * 10.0f + camMatrix.d); // 10.0f should be adjustable
|
|
|
|
rage::Vector3 acc = camMatrix.a * settings.m_sslrParams.y;
|
|
rage::Vector3 up = camMatrix.b * -settings.m_sslrParams.y;
|
|
|
|
PostFXShader->SetVar(SSLRTextureId, SSLRCutout);
|
|
PostFXShader->SetVar(sslrCenterId, position);
|
|
PostFXShader->SetVar(BloomTextureID, LRIntensity); // borrow the intensity buffer during the cutout generation
|
|
|
|
// render the clouds into a lowres buffer
|
|
PF_PUSH_MARKER("clouds");
|
|
grcTextureFactory::GetInstance().LockRenderTarget(0, LRIntensity, NULL);
|
|
GRCDEVICE.Clear(true, Color32(255,255,255,255), false, 0.0f, false);
|
|
|
|
// should we turn off z buffer here?
|
|
int oldForceTechId = grmShader::GetForcedTechniqueGroupId();
|
|
grmShader::SetForcedTechniqueGroupId(CloudDepthTechGroup);
|
|
|
|
// clouds viewprojection adjust the world mtx to be camera relative, so we need to move the camera to the origin
|
|
Mat34V oldCamMtx = vp->GetCameraMtx();
|
|
Mat34V newCamMtx = oldCamMtx;
|
|
newCamMtx.SetCol3(Vec3V(V_ZERO));
|
|
vp->SetCameraMtx(newCamMtx);
|
|
vp->SetWorldIdentity();
|
|
|
|
CLOUDHATMGR->SetCameraPos(oldCamMtx.GetCol3());
|
|
CLOUDHATMGR->Draw(CClouds::GetCurrentRenderCloudFrame(), false, 1.0f); // tell CLOUDHATMGR we're not in reflection mode, so it does not replace the technique group.
|
|
|
|
grmShader::SetForcedTechniqueGroupId(oldForceTechId);
|
|
vp->SetCameraMtx(oldCamMtx);
|
|
vp->SetWorldIdentity();
|
|
|
|
Water::RenderWaterFLODDisc(Water::pass_flodblack, Water::GetCurrentDefaultWaterHeight());
|
|
|
|
grcTextureFactory::GetInstance().UnlockRenderTarget(0);
|
|
PF_POP_MARKER();
|
|
|
|
// render depth cutout (combined with the clouds)
|
|
SetNonDepthFXStateBlocks();
|
|
|
|
#if POSTFX_TILED_LIGHTING_ENABLED
|
|
if (BANK_SWITCH(PostFX::g_UseTiledTechniques == true, CTiledLighting::IsEnabled())
|
|
#if RSG_PC
|
|
&& !(GRCDEVICE.IsStereoEnabled() && GRCDEVICE.CanUseStereo())
|
|
#endif
|
|
)
|
|
{
|
|
const char* pPassName = NULL;
|
|
#if RAGE_TIMEBARS
|
|
pPassName = passName[pp_sslrcutout_tiled];
|
|
#endif
|
|
#if __D3D11 || RSG_ORBIS
|
|
PostFXShader->SetVar(TiledDepthTextureId, CTiledLighting::GetClassificationTexture());
|
|
#endif // __D3D11 || RSG_ORBIS
|
|
CTiledLighting::RenderTiles(SSLRCutout, PostFXShader, PostFXTechnique, pp_sslrcutout_tiled, pPassName, true);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
PostFXBlit(SSLRCutout, PostFXTechnique, pp_sslrcutout, false, false);
|
|
}
|
|
|
|
|
|
// put the light rays into the intensity buffer
|
|
SetNonDepthFXStateBlocks();
|
|
PostFXBlit(LRIntensity2, PostFXTechnique, pp_sslrextruderays, false, true, Color32(0,0,0,0),
|
|
position - acc - up, position + acc - up, position + acc + up, position - acc + up);
|
|
|
|
// need to blur the intensity buffer.
|
|
// chaning to guassian blur to remove horizontal pattern on light ray (+0.03ms)
|
|
PostFXShader->SetVar(TextureID_0, LRIntensity2);
|
|
PostFXShader->SetVar(BloomTexelSizeId, Vector4(1.0f/float(LRIntensity2->GetWidth()),1.0f/float(LRIntensity2->GetHeight()),0.0, 0.0f));
|
|
PostFXBlit(LRIntensity, PostFXTechnique, pp_GaussBlur_Hor);
|
|
|
|
PostFXShader->SetVar(TextureID_0, LRIntensity);
|
|
PostFXShader->SetVar(BloomTexelSizeId, Vector4(1.0f/float(LRIntensity->GetWidth()),1.0f/float(LRIntensity->GetHeight()),0.0, 0.0f));
|
|
PostFXBlit(LRIntensity2, PostFXTechnique, pp_GaussBlur_Ver);
|
|
|
|
if (bBloomEnabled)
|
|
{
|
|
PrimeBloomBufferFrom(backBuffer);
|
|
}
|
|
|
|
PF_POP_MARKER();
|
|
|
|
sslrRT = LRIntensity2;
|
|
}
|
|
|
|
// Scale the light rays color to the value used in postfx.fx for Composite
|
|
PostFXShader->SetVar(lightrayParamsId, lightRayParams * Vector4(4.0f, 4.0f, 4.0f, 1.0f));
|
|
|
|
PostFXShader->SetVar(SSLRTextureId, sslrRT);
|
|
}
|
|
else
|
|
{
|
|
if (bBloomEnabled)
|
|
{
|
|
PostFXShader->SetVar(SSLRTextureId, LRIntensity);
|
|
PrimeBloomBufferFrom(backBuffer);
|
|
}
|
|
}
|
|
|
|
//PostFXShader->SetVar(SSLRTextureId, LRIntensity);
|
|
|
|
grcRenderTarget *bloom = NULL;
|
|
if( settings.m_seeThrough )
|
|
{
|
|
// blur the bloom buffer
|
|
grcRenderTarget* SeeThruBloomBuffer = RenderPhaseSeeThrough::GetColorRT();
|
|
BlurBloomBuffer(SeeThruBloomBuffer, true);
|
|
bloom = SeeThruBloomBuffer;
|
|
}
|
|
else
|
|
{
|
|
if (bBloomEnabled)
|
|
{
|
|
BlurBloomBuffer(BloomBuffer);
|
|
}
|
|
bloom = BloomBuffer;
|
|
}
|
|
|
|
Vector4 dofParams;
|
|
dofParams.Set(settings.m_dofParameters);
|
|
|
|
if (g_overrideDistanceBlur)
|
|
{
|
|
dofParams.SetZ(g_distanceBlurOverride);
|
|
g_overrideDistanceBlur = false;
|
|
}
|
|
|
|
#if __BANK //for screenshots
|
|
if (NoDOF == true)
|
|
{
|
|
// set blur strength to 0
|
|
dofParams.z = 0.0f;
|
|
}
|
|
#endif
|
|
|
|
// Lens artefacts
|
|
bool bUseLensArtefacts = LENSARTEFACTSMGR.IsActive();
|
|
Vector4 lensArtefactsParams0, lensArtefactsParams1, lensArtefactsParams2;
|
|
lensArtefactsParams0.Zero();
|
|
lensArtefactsParams1.Zero();
|
|
lensArtefactsParams2.Zero();
|
|
|
|
if (bUseLensArtefacts && hasHeatHaze == false)
|
|
{
|
|
// Prime lens artefacts buffer
|
|
LENSARTEFACTSMGR.Render();
|
|
|
|
// Set values driven by timecycle
|
|
LENSARTEFACTSMGR.SetExposureMinMaxFadeMultipliers( settings.m_exposureMin, settings.m_exposureMax,
|
|
settings.m_lensArtefactsMinExposureMultiplier, settings.m_lensArtefactsMaxExposureMultiplier);
|
|
|
|
// Get data for exposure based fade multiplier
|
|
LENSARTEFACTSMGR.GetExposureBasedOpacityMultipliers(lensArtefactsParams0, lensArtefactsParams1);
|
|
|
|
// Bind output and params for main composite pass
|
|
lensArtefactsParams2.w = settings.m_lensArtefactsGlobalMultiplier;
|
|
PostFXShader->SetVar(LensArtefactParams0ID, lensArtefactsParams0);
|
|
PostFXShader->SetVar(LensArtefactParams1ID, lensArtefactsParams1);
|
|
PostFXShader->SetVar(LensArtefactParams2ID, lensArtefactsParams2);
|
|
PostFXShader->SetVar(HeatHazeTextureId, LENSARTEFACTSMGR.GetRenderTarget());
|
|
}
|
|
// Set black texture for lens artefacts and dummy params
|
|
else
|
|
{
|
|
Vector4 lensArtefactsParams0 = Vector4(Vector4::ZeroType);
|
|
Vector4 lensArtefactsParams1 = Vector4(Vector4::ZeroType);
|
|
PostFXShader->SetVar(LensArtefactParams0ID, lensArtefactsParams0);
|
|
PostFXShader->SetVar(LensArtefactParams1ID, lensArtefactsParams1);
|
|
PostFXShader->SetVar(LensArtefactParams2ID, lensArtefactsParams2);
|
|
PostFXShader->SetVar(HeatHazeTextureId, grcTexture::NoneBlack);
|
|
}
|
|
|
|
PostFXShader->SetVar(DofParamsId, dofParams);
|
|
|
|
const Vector4 dofProj = ShaderUtil::CalculateProjectionParams();
|
|
PostFXShader->SetVar(DofProjId, dofProj);
|
|
|
|
const Vector2 dofShear = grcViewport::GetCurrent()->GetPerspectiveShear();
|
|
PostFXShader->SetVar(DofShearId, Vector4(dofShear.x,dofShear.y,0.f,0.f) );
|
|
|
|
SetSrcTextureAndSize(TextureID_0, backBuffer);
|
|
bool bBloomCalculated = bBloomEnabled || settings.m_seeThrough;
|
|
PostFXShader->SetVar(BloomTextureID, bBloomCalculated ? bloom : grcTexture::NoneBlack);
|
|
|
|
PostFXShader->SetVar(TextureID_v0, LumRT);
|
|
|
|
Vector4 hiDofParameters = settings.m_hiDofParameters;
|
|
PackHiDofParameters(hiDofParameters);
|
|
PostFXShader->SetVar(HiDofParamsId, hiDofParameters);
|
|
|
|
SetFilmicParams();
|
|
SetBloomParams();
|
|
|
|
#if USE_FXAA
|
|
PostFXShader->SetVar(FXAABackBuffer, backBuffer);
|
|
#endif // USE_FXAA
|
|
|
|
#if DEVICE_MSAA
|
|
PostFXShader->SetVar(TextureHDR_AA, CRenderTargets::GetBackBuffer());
|
|
#endif //DEVICE_MSAA
|
|
|
|
// If TXAA is on, that overrides FXAA and MLAA.
|
|
const bool TXAAEnabled = USE_NV_TXAA TXAA_ONLY(&& g_TXAAEnable && IsTXAAAvailable()) && (g_DoPauseResolve != PostFX::IN_RESOLVE_PAUSE);
|
|
const bool FXAAEnabled = !TXAAEnabled && g_FXAAEnable && USE_FXAA && (g_DoPauseResolve != PostFX::IN_RESOLVE_PAUSE);
|
|
const bool MLAAEnabled = !TXAAEnabled && !FXAAEnabled && MLAA_ONLY(g_MLAA.IsEnabled() || ) 0 && USE_FXAA && (g_DoPauseResolve != PostFX::IN_RESOLVE_PAUSE);
|
|
|
|
// This buffer must have the real fmask associated with it (we resolve MSAA/EQAA after the postfx composite pass and before the FXAA pass).
|
|
grcRenderTarget *FXTarget = CRenderTargets::GetUIBackBuffer();
|
|
if(TXAAEnabled || FXAAEnabled || MLAAEnabled || GRCDEVICE.GetMSAA() || bUseExtraEffects)
|
|
FXTarget = CRenderTargets::GetOffscreenBuffer1();
|
|
|
|
#if __PS3
|
|
BANK_ONLY( if( g_delayFlipWait) )
|
|
{
|
|
GCM_DEBUG(cellGcmSetWaitFlip(GCM_CONTEXT));
|
|
s_NeedWaitFlip = false;
|
|
}
|
|
#endif // __PS3
|
|
|
|
#if __DEV
|
|
// Either use command-line parameter or when LastGen is enabled
|
|
if( gLastGenMode )
|
|
{
|
|
SSAO::Enable(settings.m_seeThrough);
|
|
}
|
|
|
|
bool applySimplePfx = g_ForceUseSimple ||
|
|
( gLastGenMode && !(settings.m_nightVision || settings.m_seeThrough) );
|
|
|
|
CShaderLib::UpdateGlobalGameScreenSize();
|
|
|
|
if( applySimplePfx BANK_ONLY( || g_JustExposure))
|
|
{
|
|
#if __XENON
|
|
//set LDR exp bias for 7e3 format
|
|
GRCDEVICE.SetColorExpBiasNow(CRenderer::GetBackbufferColorExpBiasLDR());
|
|
#endif
|
|
|
|
PostFXShader->SetVar(TextureID_v0, LumRT);
|
|
|
|
#if __BANK
|
|
if (g_JustExposure)
|
|
{
|
|
SetNonDepthFXStateBlocks();
|
|
PostFXBlit(FXTarget, PostFXTechnique, pp_JustExposure);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
SetNonDepthFXStateBlocks();
|
|
PostFXBlit(FXTarget, PostFXTechnique, pp_simple);
|
|
}
|
|
}
|
|
else
|
|
#endif // __DEV
|
|
{
|
|
// Extra effects passes always use noise, so we always need to update the noise parameters if we're running with any of these
|
|
const bool hasNoise = (noiseParams.z>0.0f) || bUseExtraEffects;
|
|
|
|
// We have no depth when paused: skip DOF
|
|
const bool bSkipHighDofTechniques = XENON_SWITCH(CPauseMenu::GetPauseRenderPhasesStatus(), false);
|
|
|
|
int techniqueIdx = 0;
|
|
if( (settings.m_HighDof || settings.m_AdaptiveDof) && !bSkipHighDofTechniques )
|
|
{
|
|
if (settings.m_ShallowDof && settings.m_HighDofForceSmallBlur == false)
|
|
{
|
|
techniqueIdx |= BM_HighDofShallow;
|
|
}
|
|
else
|
|
{
|
|
techniqueIdx |= BM_HighDof;
|
|
}
|
|
}
|
|
if( hasMotionBlur ) techniqueIdx |= BM_MotionBlur;
|
|
if( settings.m_nightVision ) techniqueIdx |= BM_NightVision;
|
|
if( hasHeatHaze ) techniqueIdx |= BM_HeatHaze;
|
|
if( hasNoise ) techniqueIdx |= BM_Noise;
|
|
|
|
if (bUseExtraEffects)
|
|
{
|
|
techniqueIdx |= BM_ExtraEffects;
|
|
}
|
|
|
|
// Vignetting
|
|
const float vignettingBias = 1.0f-settings.m_vignettingParams.x;
|
|
const float vignettingRadius = settings.m_vignettingParams.y;
|
|
const float vignettingContrast = 1.0f + ((vignettingRadius-1.0f)*settings.m_vignettingParams.z);
|
|
|
|
// pack some gradient filter terms in unused components
|
|
const float ooMiddleColPos = 1.0f/settings.m_lensGradientColMiddle.w;
|
|
const float ooOneMinusMiddleColPos = 1.0f/(1.0f-settings.m_lensGradientColMiddle.w);
|
|
|
|
PostFXShader->SetVar(VignettingParamsId, Vector4(vignettingBias, vignettingRadius, vignettingContrast, ooOneMinusMiddleColPos));
|
|
|
|
Vector4 vignettingColour(settings.m_vignettingColour);
|
|
vignettingColour.w = ooMiddleColPos;
|
|
PostFXShader->SetVar(VignettingColorId, vignettingColour);
|
|
|
|
// Lens Gradient Filter
|
|
|
|
Vec4V vColTop(RCC_VEC4V(settings.m_lensGradientColTop));
|
|
Vec4V vColMiddle(RCC_VEC4V(settings.m_lensGradientColMiddle));
|
|
Vec4V vColBottom(RCC_VEC4V(settings.m_lensGradientColBottom));
|
|
Vec4V vGamma(settings.m_gamma, settings.m_gamma, settings.m_gamma, settings.m_gamma);
|
|
|
|
Vec4V vColTopGamma = Pow(vColTop, vGamma);
|
|
Vec4V vColMiddleGamma = Pow(vColMiddle, vGamma);
|
|
Vec4V vColBottomGamma = Pow(vColBottom, vGamma);
|
|
|
|
vColTopGamma.SetW(SubtractScaled(ScalarV(V_ONE),vColTop.GetW(), ScalarV(V_TWO)));
|
|
vColBottomGamma.SetW(SubtractScaled(ScalarV(V_ONE),vColBottom.GetW(), ScalarV(V_TWO)));
|
|
vColMiddleGamma.SetW(vColMiddle.GetW());
|
|
|
|
|
|
PostFXShader->SetVar(GradientFilterColTopId, vColTopGamma);
|
|
PostFXShader->SetVar(GradientFilterColBottomId, vColBottomGamma);
|
|
PostFXShader->SetVar(GradientFilterColMiddleId, vColMiddleGamma);
|
|
|
|
// Distortion
|
|
PostFXShader->SetVar(DistortionParamsID, BANK_ONLY(IsTiledScreenCaptureOrPanorama() ? Vector4(Vector4::ZeroType) :) settings.m_distortionParams);
|
|
|
|
// Blur Vignetting
|
|
const float blurVignettingBias = 1.0f-settings.m_blurVignettingParams.x;
|
|
const float blurVignettingRadius = settings.m_blurVignettingParams.y;
|
|
PostFXShader->SetVar(BlurVignettingParamsID, Vector4(blurVignettingBias, blurVignettingRadius, bUseExtraEffects ? 1.0f : 0.0f, 0.0f));
|
|
|
|
|
|
if( settings.m_HighDof || settings.m_AdaptiveDof || bExtraEffectsBlur )
|
|
{
|
|
PostFXShader->SetVar(HiDofSmallBlurId, (settings.m_HighDofForceSmallBlur ? 1.0f : 0.0f));
|
|
|
|
// dof samplers
|
|
PostFXShader->SetVar(PostFxTexture2Id, pDOFMedBlur);
|
|
PostFXShader->SetVar(PostFxTexture3Id, pDOFLargeBlur);
|
|
|
|
#if DOF_COMPUTE_GAUSSIAN || DOF_DIFFUSION
|
|
//With these DOF types we use the blurred target as the hdrsampler.
|
|
//When we're using screen blur we need both the blurred and non blurred version so dont do this then.
|
|
if( (CurrentDOFTechnique == dof_computeGaussian || CurrentDOFTechnique == dof_diffusion) )
|
|
{
|
|
PostFXShader->SetVar(TextureID_0, pDOFLargeBlur);
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
PostFXShader->SetVar(PostFxTexture3Id, backBuffer);
|
|
}
|
|
|
|
PostFXPass pass = PassLookupTable[techniqueIdx];
|
|
if( settings.m_seeThrough ) // force see through
|
|
{
|
|
pass = pp_composite_seethrough;
|
|
|
|
if (g_pNoiseTexture != NULL)
|
|
{
|
|
PostFXShader->SetVar(TextureID_1, g_pNoiseTexture);
|
|
PostFXShader->SetVar(NoiseParamsId, noiseParams);
|
|
}
|
|
|
|
PostFXShader->SetVar(seeThroughParamsId, settings.m_SeeThroughParams);
|
|
PostFXShader->SetVar(seeThroughColorNearId, settings.m_SeeThroughColorNear);
|
|
PostFXShader->SetVar(seeThroughColorFarId, settings.m_SeeThroughColorFar);
|
|
PostFXShader->SetVar(seeThroughColorVisibleBaseId, settings.m_SeeThroughColorVisibleBase);
|
|
PostFXShader->SetVar(seeThroughColorVisibleWarmId, settings.m_SeeThroughColorVisibleWarm);
|
|
PostFXShader->SetVar(seeThroughColorVisibleHotId, settings.m_SeeThroughColorVisibleHot);
|
|
PostFXShader->SetVar(PostFxTexture2Id, RenderPhaseSeeThrough::GetBlurRT());
|
|
}
|
|
|
|
// also used for distance blur
|
|
const grcTexture* motionBlurTarget = HalfScreen0;
|
|
#if DOF_COMPUTE_GAUSSIAN || DOF_DIFFUSION
|
|
if( CurrentDOFTechnique == dof_computeGaussian || CurrentDOFTechnique == dof_diffusion )
|
|
{
|
|
motionBlurTarget = backBuffer;
|
|
if( settings.m_HighDof || settings.m_AdaptiveDof)
|
|
motionBlurTarget = DepthOfField2;
|
|
}
|
|
else
|
|
{
|
|
motionBlurTarget = backBuffer;
|
|
}
|
|
#endif
|
|
PostFXShader->SetVar(PostFxMotionBlurTextureID, motionBlurTarget);
|
|
|
|
|
|
if (hasMotionBlur)
|
|
{
|
|
PostFXShader->SetVar(JitterTextureId, JitterTexture);
|
|
#if __XENON
|
|
PostFXShader->SetVar(StencilCopyTextureId, CRenderTargets::GetDepthBufferAsColor());
|
|
#elif __D3D11 || RSG_ORBIS
|
|
PostFXShader->SetVar(StencilCopyTextureId, CRenderTargets::GetDepthBuffer_Stencil());
|
|
#endif // __XENON
|
|
}
|
|
|
|
if( settings.m_nightVision )
|
|
{
|
|
if (g_pNoiseTexture!=NULL)
|
|
{
|
|
PostFXShader->SetVar(TextureID_1, g_pNoiseTexture);
|
|
PostFXShader->SetVar(NoiseParamsId, Vector4(NoiseEffectRandomValues.x, NoiseEffectRandomValues.y, 10.0f, 1.0f));
|
|
}
|
|
}
|
|
|
|
if( hasHeatHaze )
|
|
{
|
|
const float t_time=settings.m_time / 1000.0f;
|
|
|
|
Vector4 HeatHazeParams = settings.m_HeatHazeParams;
|
|
Vector4 HeatHazeTex1Params = settings.m_HeatHazeTex1Params;
|
|
Vector4 HeatHazeTex2Params = settings.m_HeatHazeTex2Params;
|
|
Vector4 HeatHazeOffsetParams = settings.m_HeatHazeOffsetParams;
|
|
|
|
const Matrix34 &camMatrix = RCC_MATRIX34(vp->GetCameraMtx());
|
|
float cosAngA=camMatrix.a.x;
|
|
const float cosAngC=camMatrix.c.z;
|
|
|
|
#if !__FINAL
|
|
// Fix for an occasional assert that triggers due to a precision issues
|
|
cosAngA = Clamp(cosAngA, -1.0f, 1.0f);
|
|
#endif
|
|
|
|
const float AngA = Acosf(cosAngA)/(PI);
|
|
const float HeatHazeTextureWidth = (float)HeatHazeTexture->GetWidth();
|
|
const float HeatHazeTextureHeight = (float)HeatHazeTexture->GetHeight();
|
|
|
|
HeatHazeTex1Params.z -= (AngA) * HeatHazeTex1Params.x;
|
|
HeatHazeTex1Params.w += cosAngC * HeatHazeTex1Params.y;
|
|
|
|
HeatHazeTex2Params.z -= (AngA) * HeatHazeTex2Params.x;
|
|
HeatHazeTex2Params.w += cosAngC * HeatHazeTex2Params.y;
|
|
|
|
HeatHazeTex1Params.z += Sinf(settings.m_HeatHazeTex1Anim.x + settings.m_HeatHazeTex1Anim.y * t_time) * (settings.m_HeatHazeTex1Anim.z/HeatHazeTextureWidth);
|
|
HeatHazeTex1Params.z -= Floorf(HeatHazeTex1Params.z);
|
|
HeatHazeTex1Params.w += (settings.m_HeatHazeTex1Anim.w/HeatHazeTextureHeight) * t_time;
|
|
HeatHazeTex1Params.w -= Floorf(HeatHazeTex1Params.w);
|
|
|
|
HeatHazeTex2Params.z += Sinf(settings.m_HeatHazeTex2Anim.x + settings.m_HeatHazeTex2Anim.y * t_time) * (settings.m_HeatHazeTex2Anim.z/HeatHazeTextureWidth);
|
|
HeatHazeTex2Params.z -= Floorf(HeatHazeTex2Params.z);
|
|
HeatHazeTex2Params.w += (settings.m_HeatHazeTex2Anim.w/HeatHazeTextureHeight) * t_time;
|
|
HeatHazeTex2Params.w -= Floorf(HeatHazeTex2Params.w);
|
|
|
|
HeatHazeOffsetParams.x *= 1.0f/ (float)backBuffer->GetWidth();
|
|
HeatHazeOffsetParams.y *= 1.0f/ (float)backBuffer->GetHeight();
|
|
|
|
float angleFade = 1.0f;
|
|
bool bIsUnderWater = CVfxHelper::GetGameCamWaterDepth()>0.0f;
|
|
|
|
// use angle fade only if not under water
|
|
if (!bIsUnderWater)
|
|
{
|
|
angleFade = 1.0f-Clamp(fabs(camMatrix.c.z), 0.0f, 1.0f);
|
|
angleFade*=angleFade;
|
|
}
|
|
|
|
HeatHazeOffsetParams.z = angleFade;
|
|
|
|
PostFXShader->SetVar(heatHazeParamsId,HeatHazeParams);
|
|
PostFXShader->SetVar(HeatHazeTex1ParamsId,HeatHazeTex1Params);
|
|
PostFXShader->SetVar(HeatHazeTex2ParamsId,HeatHazeTex2Params);
|
|
PostFXShader->SetVar(HeatHazeOffsetParamsId,HeatHazeOffsetParams);
|
|
|
|
PostFXShader->SetVar(PostFxHHTextureID, backBuffer);
|
|
PostFXShader->SetVar(HeatHazeTextureId, HeatHazeTexture);
|
|
PostFXShader->SetVar(HeatHazeMaskTextureID, HeatHaze0);
|
|
}
|
|
|
|
if( hasNoise )
|
|
{
|
|
if (g_pNoiseTexture!=NULL)
|
|
{
|
|
PostFXShader->SetVar(TextureID_1, g_pNoiseTexture);
|
|
PostFXShader->SetVar(NoiseParamsId, noiseParams);
|
|
}
|
|
}
|
|
|
|
if( settings.m_HighDof || settings.m_AdaptiveDof || bExtraEffectsBlur )
|
|
{
|
|
#if BOKEH_SUPPORT
|
|
PostFXShader->SetVar( BokehEnableVar, BokehEnable);
|
|
if( BokehEnable && BokehGenerated )
|
|
{
|
|
PostFXShader->SetVar( BloomTextureGID, BokehPoints);
|
|
}
|
|
else
|
|
{
|
|
//If bokeh is disabled or no bokeh is drawn use the black 1x1
|
|
PostFXShader->SetVar( BloomTextureGID, BokehNoneRenderedTexture);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
PostFXShader->SetVar(TextureID_v1, g_currentExposureRT);
|
|
|
|
#if __BANK || __WIN32PC || RSG_DURANGO || RSG_ORBIS
|
|
|
|
#if FILM_EFFECT
|
|
//if the fxaa is disabled, then we apply the film effect here
|
|
if(FXAAEnabled == false && MLAAEnabled == false && (g_EnableFilmEffect || PARAM_filmeffect.Get()))
|
|
ApplyFilmEffect(pass, NULL, settings);
|
|
else
|
|
#endif //FILM_EFFECT
|
|
#endif
|
|
{
|
|
//=============== Main PostFX Composite Pass ======================================
|
|
|
|
PostFXShader->SetVar(TextureID_v1, g_currentExposureRT);
|
|
SetNonDepthFXStateBlocks();
|
|
#if __D3D11 || RSG_ORBIS
|
|
# if MSAA_EDGE_PASS
|
|
if (DeferredLighting::IsEdgePassActiveForPostfx() &&
|
|
GetPauseResolve() != NOT_RESOVE_PAUSE && GetPauseResolve() != UNRESOLVE_PAUSE &&
|
|
PostFXShaderMS0)
|
|
{
|
|
grcTextureFactory::GetInstance().LockRenderTarget(0, FXTarget, NULL);
|
|
grcStateBlock::SetDepthStencilState(DeferredLighting::m_directionalEdgeMaskEqualPass_DS, 0);
|
|
PostFXShaderMS0->CopyPassData(PostFXTechnique, pass, PostFXShader);
|
|
PostFXBlitHelper(PostFXShaderMS0, PostFXTechnique, pass);
|
|
grcTextureFactory::GetInstance().UnlockRenderTarget(0);
|
|
}else
|
|
if (DeferredLighting::IsEdgePassActiveForPostfx() && AssertVerify(PostFXShaderMS0)
|
|
BANK_ONLY(&& (DebugDeferred::m_OptimizeComposite & (1<<EM_IGNORE))))
|
|
{
|
|
PIX_AUTO_TAG(1, passName[pass]);
|
|
grcTextureFactory::GetInstance().LockRenderTarget(0, FXTarget,
|
|
# if __D3D11
|
|
GRCDEVICE.IsReadOnlyDepthAllowed() ? CRenderTargets::GetDepthBuffer_ReadOnly() :
|
|
# endif
|
|
CRenderTargets::GetDepthBufferCopy());
|
|
// edges
|
|
BANK_ONLY(if (DebugDeferred::m_OptimizeComposite & (1<<EM_EDGE0)))
|
|
{
|
|
grcStateBlock::SetDepthStencilState(DeferredLighting::m_directionalEdgeMaskEqualPass_DS, EDGE_FLAG);
|
|
PostFXBlitHelper(PostFXShader, PostFXTechnique, pass);
|
|
}
|
|
// non-edges
|
|
BANK_ONLY(if (DebugDeferred::m_OptimizeComposite & (1<<EM_FACE0)))
|
|
{
|
|
grcStateBlock::SetDepthStencilState(DeferredLighting::m_directionalEdgeMaskEqualPass_DS, 0);
|
|
PostFXShaderMS0->CopyPassData(PostFXTechnique, pass, PostFXShader);
|
|
PostFXBlitHelper(PostFXShaderMS0, PostFXTechnique, pass);
|
|
}
|
|
grcTextureFactory::GetInstance().UnlockRenderTarget(0);
|
|
grcStateBlock::SetDepthStencilState(nonDepthFXDepthStencilState);
|
|
}else
|
|
# endif //MSAA_EDGE_PASS
|
|
{
|
|
PostFXBlit(FXTarget, PostFXTechnique, pass);
|
|
}
|
|
#else //__D3D11 || RSG_ORBIS
|
|
// If we're using the default composite pass, use tile classification data to select where to apply distance blur
|
|
// Performance was slightly worse on 360, so only do this on ps3
|
|
#if __PS3 && POSTFX_TILED_LIGHTING_ENABLED
|
|
if (pass == pp_composite BANK_ONLY(&& g_PS3UseCompositeTiledTechniques && g_UseTiledTechniques) && CTiledLighting::IsEnabled())
|
|
{
|
|
const char* pPassName = NULL;
|
|
pass = pp_composite_tiled;
|
|
#if RAGE_TIMEBARS
|
|
pPassName = passName[pass];
|
|
#endif
|
|
|
|
// distance blur ON
|
|
dofParams.w = 0.0f;
|
|
PostFXShader->SetVar(DofParamsId, dofParams);
|
|
CTiledLighting::RenderTiles(FXTarget, PostFXShader, PostFXTechnique, pass, pPassName, false, false, false);
|
|
|
|
pass = pp_composite_tiled_noblur;
|
|
#if RAGE_TIMEBARS
|
|
pPassName = passName[pass];
|
|
#endif
|
|
// distance blur OFF
|
|
dofParams.w = 1.0f;
|
|
PostFXShader->SetVar(DofParamsId, dofParams);
|
|
CTiledLighting::RenderTiles(FXTarget, PostFXShader, PostFXTechnique, pass, pPassName, false, false, false);
|
|
}
|
|
else if (pass == pp_composite_highdof BANK_ONLY(&& g_PS3UseCompositeTiledTechniques && g_UseTiledTechniques))
|
|
{
|
|
const char* pPassName = NULL;
|
|
pass = pp_composite_highdof_blur_tiled;
|
|
#if RAGE_TIMEBARS
|
|
pPassName = passName[pass];
|
|
#endif
|
|
|
|
// hq dof ON
|
|
hiDofMiscParams.w = 0.0f;
|
|
PostFXShader->SetVar(HiDofMiscParamsId, hiDofMiscParams);
|
|
CTiledLighting::RenderTiles(FXTarget, PostFXShader, PostFXTechnique, pass, pPassName, false, false, false);
|
|
|
|
pass = pp_composite_highdof_noblur_tiled;
|
|
#if RAGE_TIMEBARS
|
|
pPassName = passName[pass];
|
|
#endif
|
|
// hq dof OFF
|
|
hiDofMiscParams.w = 1.0f;
|
|
PostFXShader->SetVar(HiDofMiscParamsId, hiDofMiscParams);
|
|
CTiledLighting::RenderTiles(FXTarget, PostFXShader, PostFXTechnique, pass, pPassName, false, false, false);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
PostFXBlit(FXTarget, PostFXTechnique, pass, false, false, NULL, false);
|
|
}
|
|
#endif
|
|
//=================================================================================
|
|
}
|
|
|
|
PostFXGradientFilter(FXTarget, PostFXTechnique, pp_gradientfilter, settings);
|
|
|
|
//============== Scanline Filter ===============
|
|
|
|
// Extra effects passes always include scanline filter, but night vision doesn't.
|
|
if(settings.m_scanlineParams.x > 0.01f && (bUseExtraEffects == false || settings.m_nightVision))
|
|
{
|
|
Vector4 scanlineParams;
|
|
GetScanlineParams(settings, scanlineParams);
|
|
|
|
PostFXShader->SetVar(ScanlineFilterParamsId, scanlineParams);
|
|
#if __D3D11 || RSG_ORBIS
|
|
PostFXBlit(FXTarget, PostFXTechnique, pp_scanlinefilter);
|
|
#else
|
|
PostFXBlit(FXTarget, PostFXTechnique, pp_scanlinefilter, false, false, NULL, false);
|
|
#endif // __D3D11 || RSG_ORBIS
|
|
}
|
|
//==============================================
|
|
}
|
|
|
|
#if DYNAMIC_BB
|
|
if(CPauseMenu::GetGPUCountdownToPauseStatus() && !DRAWLISTMGR->IsExecutingHudDrawList())
|
|
{
|
|
// copy the BackBuffer from ESRAM to DRAM ready for pause
|
|
CRenderTargets::FlushAltBackBuffer();
|
|
CPauseMenu::ClearGPUCountdownToPauseStatus();
|
|
}
|
|
#endif
|
|
|
|
grcRenderTarget *const finalRT = CRenderTargets::GetUIBackBuffer();
|
|
grcRenderTarget* UIRT = finalRT;
|
|
#if DEVICE_MSAA && POSTFX_SEPARATE_LENS_DISTORTION_PASS
|
|
const bool bSeparateLensDistortionPass = bUseExtraEffects;
|
|
if (bSeparateLensDistortionPass)
|
|
{
|
|
// Using a spare RGBA8 single-sampled buffer. Note that we don't care
|
|
// about the contents, so make sure we call the _SingleSample version of
|
|
// the function, not _Resolved.
|
|
#if RSG_DURANGO
|
|
// use a one-off ESRAM temp buffer
|
|
UIRT = CRenderTargets::GetOffscreenBuffer_SingleSample(3);
|
|
#else
|
|
UIRT = CRenderTargets::GetOffscreenBuffer_SingleSample(2);
|
|
#endif
|
|
Assert(UIRT);
|
|
}
|
|
#endif // DEVICE_MSAA && POSTFX_SEPARATE_LENS_DISTORTION_PASS
|
|
|
|
if(FXAAEnabled || MLAAEnabled)
|
|
{
|
|
#if __PS3
|
|
#if __BANK
|
|
if( g_delayFlipWait )
|
|
#endif // __BANK
|
|
{
|
|
GCM_DEBUG(cellGcmSetWaitFlip(GCM_CONTEXT));
|
|
s_NeedWaitFlip = false;
|
|
}
|
|
#endif // __PS3
|
|
|
|
//Resolve the Composite target
|
|
Assert(FXTarget);
|
|
#if DEVICE_MSAA
|
|
# if RSG_ORBIS
|
|
if (CRenderTargets::GetOffscreenBuffer1() == GBuffer::GetTarget(GBUFFER_RT_0))
|
|
{
|
|
// don't call FinishRendering() on GBUFFER0, causing another FMask decompression
|
|
static_cast<grcRenderTargetMSAA*>(FXTarget)->Resolve(CRenderTargets::GetOffscreenBuffer1_Resolved());
|
|
}else
|
|
# endif //RSG_ORBIS
|
|
{
|
|
CRenderTargets::ResolveOffscreenBuffer1();
|
|
}
|
|
FXTarget = CRenderTargets::GetOffscreenBuffer1_Resolved();
|
|
#else
|
|
FXTarget = CRenderTargets::GetOffscreenBuffer1();
|
|
#endif //DEVICE_MSAA
|
|
|
|
#if FXAA_CUSTOM_TUNING
|
|
PostFXShader->SetVar(fxaaBlurinessId, fxaaBluriness);
|
|
PostFXShader->SetVar(fxaaConsoleEdgeSharpnessId, fxaaConsoleEdgeSharpness);
|
|
PostFXShader->SetVar(fxaaConsoleEdgeThresholdId, fxaaConsoleEdgeThreshold);
|
|
PostFXShader->SetVar(fxaaConsoleEdgeThresholdMinId, fxaaConsoleEdgeThresholdMin);
|
|
|
|
PostFXShader->SetVar(fxaaQualitySubpixId, fxaaQualitySubpix);
|
|
PostFXShader->SetVar(fxaaEdgeThresholdId, fxaaEdgeThreshold);
|
|
PostFXShader->SetVar(fxaaEdgeThresholdMinId, fxaaEdgeThresholdMin);
|
|
#endif
|
|
|
|
#if USE_FXAA
|
|
PostFXShader->SetVar(FXAABackBuffer, FXTarget);
|
|
|
|
// rcpFrameId
|
|
float rcpWidth = 1.0f / (float)VideoResManager::GetSceneWidth();
|
|
float rcpHeight = 1.0f / (float)VideoResManager::GetSceneHeight();
|
|
PostFXShader->SetVar(rcpFrameId, Vector2(rcpWidth, rcpHeight));
|
|
#endif
|
|
PostFXShader->SetVar(TextureID_v1, g_currentExposureRT);
|
|
SetNonDepthFXStateBlocks();
|
|
|
|
PostFXPass eAATechnique;
|
|
switch ( g_AntiAliasingType )
|
|
{
|
|
case AA_FXAA_DEFAULT : eAATechnique = PS3_SWITCH( pp_AA_720p, FXAAPassToUse ); break; // PS3 uses a special hard-coded AA shader for 720p. See shader entry point for comments/justification.
|
|
case AA_FXAA_UI : eAATechnique = pp_UIAA; break;
|
|
default : eAATechnique = PS3_SWITCH( pp_AA_720p, FXAAPassToUse ); break;
|
|
}
|
|
|
|
#if FILM_EFFECT
|
|
if(g_EnableFilmEffect || PARAM_filmeffect.Get())
|
|
ApplyFilmEffect(eAATechnique, NULL, settings);
|
|
else
|
|
#endif //FILM_EFFECT
|
|
{
|
|
#if ENABLE_MLAA
|
|
if (MLAAEnabled)
|
|
{
|
|
g_MLAA.AntiAlias(UIRT,
|
|
#if RSG_ORBIS
|
|
CRenderTargets::GetDepthResolved(),
|
|
#else
|
|
CRenderTargets::GetDepthBufferResolved_ReadOnly(),
|
|
#endif
|
|
FXTarget, CRenderTargets::GetDepthResolved()
|
|
);
|
|
}
|
|
else
|
|
#endif // ENABLE_MLAA
|
|
{
|
|
#if USE_HQ_ANTIALIASING
|
|
if ( g_AntiAliasingType == AA_FXAA_HQ )
|
|
{
|
|
#if __PS3
|
|
PF_PUSH_MARKER("MULTI-TYPE FXAA");
|
|
Vector4 dummy;
|
|
dummy.Zero();
|
|
Vector4 range(g_AntiAliasingSwitchDistance, 0.f,0.f, 1.f);
|
|
|
|
CSprite2d::GetShader()->SetVar(g_HQAA_srcMapID, FXTarget);
|
|
|
|
CSprite2d::SetGeneralParams(range, dummy);
|
|
CTiledLighting::RenderTiles(UIRT, CSprite2d::GetShader(), g_HQAATiledTechnique, 0, "FXAA Sharp", false, false, false);
|
|
|
|
range.w=0.f;
|
|
CSprite2d::SetGeneralParams(range, dummy);
|
|
|
|
CTiledLighting::RenderTiles(UIRT, CSprite2d::GetShader(), g_HQAATiledTechnique, 1, "FXAA Soft", false, false, false);
|
|
|
|
range.y=1.f;
|
|
CSprite2d::SetGeneralParams(range, dummy);
|
|
CTiledLighting::RenderTiles(UIRT, CSprite2d::GetShader(), g_HQAATiledTechnique, 2, "FXAA Blit", false, false, false);
|
|
|
|
PF_POP_MARKER();
|
|
#else
|
|
grcTextureFactory::GetInstance().LockRenderTarget(0, UIRT, NULL);
|
|
|
|
CSprite2d hqaa;
|
|
hqaa.BeginCustomList(CSprite2d::CS_HIGHQUALITY_AA, FXTarget);
|
|
grcDrawSingleQuadf(-1.0, 1.0f, 1.0f, -1.0f, 0.0f, 0.0, 0.0, 1.0f, 1.0f,Color32(255, 255, 255, 255));
|
|
hqaa.EndCustomList();
|
|
|
|
grcTextureFactory::GetInstance().UnlockRenderTarget(0);
|
|
#endif
|
|
}
|
|
else
|
|
#endif // USE_HQ_ANTIALIASING
|
|
{
|
|
PostFXShader->SetVar(FXAABackBuffer, FXTarget);
|
|
PostFXBlit(UIRT, PostFXTechnique, eAATechnique, false, false, NULL,
|
|
#if __D3D11
|
|
NULL
|
|
#else
|
|
false
|
|
#endif
|
|
);
|
|
}
|
|
}
|
|
}
|
|
} // if(FXAAEnabled || MLAAEnabled)
|
|
#if DEVICE_MSAA
|
|
else if(GRCDEVICE.GetMSAA())
|
|
{
|
|
if (FXTarget != NULL)
|
|
{
|
|
grcRenderTargetMSAA* MSAATarget = static_cast<grcRenderTargetMSAA*>( FXTarget );
|
|
#if USE_NV_TXAA
|
|
if (TXAAEnabled)
|
|
{
|
|
grcRenderTarget* pTXAAOutRT = VideoResManager::IsSceneScaled() ? CRenderTargets::GetOffscreenBuffer_SingleSample(3) : UIRT;
|
|
|
|
ResolveTXAA(pTXAAOutRT, MSAATarget);
|
|
|
|
if(VideoResManager::IsSceneScaled())
|
|
{
|
|
PostFXShader->SetVar(TextureID_0, pTXAAOutRT);
|
|
PostFXBlit(UIRT, PostFXTechnique, pp_copy, false, false, NULL,
|
|
#if __D3D11
|
|
NULL
|
|
#else
|
|
false
|
|
#endif
|
|
);
|
|
}
|
|
}
|
|
else // Plain old MSAA resolve.
|
|
#endif
|
|
{
|
|
// We still want to resolve here, even for 4s1f EQAA (this is the one resolve we do for EQAA)
|
|
#if RSG_PC
|
|
if(VideoResManager::IsSceneScaled())
|
|
{
|
|
grcRenderTarget* pResolveRT = CRenderTargets::GetOffscreenBuffer_SingleSample(3);
|
|
MSAATarget->Resolve(pResolveRT);
|
|
|
|
PostFXShader->SetVar(TextureID_0, pResolveRT);
|
|
PostFXBlit(UIRT, PostFXTechnique, pp_copy, false, false, NULL,
|
|
#if __D3D11
|
|
NULL
|
|
#else
|
|
false
|
|
#endif
|
|
);
|
|
}
|
|
else
|
|
#endif
|
|
MSAATarget->Resolve( UIRT );
|
|
}
|
|
}
|
|
//FXTarget = NULL;
|
|
}
|
|
#endif // DEVICE_MSAA
|
|
else
|
|
{
|
|
UIRT = FXTarget;
|
|
}
|
|
|
|
// Depth buffer
|
|
#if RSG_PC || RSG_DURANGO
|
|
#if __D3D11
|
|
grcRenderTarget *depthRT = (GRCDEVICE.IsReadOnlyDepthAllowed()) ? CRenderTargets::GetDepthBuffer_ReadOnly() : CRenderTargets::GetDepthBufferCopy();
|
|
#else
|
|
grcRenderTarget *depthRT = CRenderTargets::GetDepthBufferCopy();
|
|
#endif
|
|
#else
|
|
grcRenderTarget *depthRT = CRenderTargets::GetDepthBuffer();
|
|
#endif
|
|
|
|
#if __D3D11 || RSG_ORBIS
|
|
grcRenderTarget *stencilRT = CRenderTargets::GetDepthBuffer_Stencil();
|
|
#endif
|
|
|
|
if (settings.m_fpvMotionBlurActive)
|
|
{
|
|
BANK_ONLY(SetDebugParams();)
|
|
|
|
// Copy to 0
|
|
SetSrcTextureAndSize(StencilCopyTextureId, stencilRT);
|
|
SetSrcTextureAndSize(TextureID_0, UIRT);
|
|
SetSrcTextureAndSize(TextureID_v0, UIRT);
|
|
SetSrcTextureAndSize(GBufferTextureIdDepth, depthRT);
|
|
PostFXBlit(fpvMotionBlurTarget[0], PostFXTechnique, pp_motion_blur_fpv, false, false);
|
|
|
|
// Composite
|
|
PostFXShader->SetVar(JitterTextureId, JitterTexture);
|
|
PostFXShader->SetVar(fpvMotionBlurWeightsId, settings.m_fpvMotionBlurWeights);
|
|
PostFXShader->SetVar(fpvMotionBlurVelocityId, settings.m_fpvMotionBlurVelocity);
|
|
PostFXShader->SetVar(fpvMotionBlurSizeId, settings.m_fpvMotionBlurSize);
|
|
SetSrcTextureAndSize(TextureID_0, fpvMotionBlurTarget[0]);
|
|
PostFXBlit(fpvMotionBlurTarget[1], PostFXTechnique, pp_motion_blur_fpv_ds, false, false);
|
|
|
|
// Final composite
|
|
Vec4V weights = Vec4V(Mag(settings.m_fpvMotionBlurVelocity).Getf(), 0.0f, 0.0f, 0.0f);
|
|
PostFXShader->SetVar(fpvMotionBlurWeightsId, weights);
|
|
|
|
PostFXShader->SetVar(JitterTextureId, JitterTexture);
|
|
PostFXShader->SetVar(fpvMotionBlurVelocityId, settings.m_fpvMotionBlurVelocity);
|
|
PostFXShader->SetVar(fpvMotionBlurSizeId, settings.m_fpvMotionBlurSize);
|
|
SetSrcTextureAndSize(TextureID_0, fpvMotionBlurTarget[1]);
|
|
SetSrcTextureAndSize(TextureID_v0, fpvMotionBlurTarget[1]);
|
|
PostFXBlit(UIRT, PostFXTechnique, pp_motion_blur_fpv_composite, false, false);
|
|
grcStateBlock::SetBlendState(grcStateBlock::BS_Normal);
|
|
}
|
|
|
|
#if DEVICE_MSAA && POSTFX_SEPARATE_LENS_DISTORTION_PASS
|
|
if (bSeparateLensDistortionPass)
|
|
{
|
|
#if RSG_PC
|
|
const float currentAspect = ((float)finalRT->GetWidth() / (float)finalRT->GetHeight());
|
|
const float maxAspect = 1.0f / 5.0f;
|
|
const float scaleCoef = Clamp(1.0f - Saturate((currentAspect * maxAspect) - (2.0f * maxAspect)), 0.5f, 1.0f);
|
|
#else
|
|
const float scaleCoef = 1.0f;
|
|
#endif
|
|
|
|
PostFXShader->SetVar(TextureID_0, UIRT);
|
|
PostFXShader->SetVar(TexelSizeId, Vector4(1.0f/finalRT->GetWidth(), 1.0f/finalRT->GetHeight(), scaleCoef, 0.f));
|
|
PostFXBlit(finalRT, PostFXTechnique, pp_lens_distortion, false, false);
|
|
}
|
|
|
|
const bool bNeedsBlurVignetting = (settings.m_blurVignettingParams.x > 0.0f);
|
|
if (bNeedsBlurVignetting)
|
|
{
|
|
ProcessBlurVignetting(finalRT, settings);
|
|
}
|
|
#endif // DEVICE_MSAA && POSTFX_SEPARATE_LENS_DISTORTION_PASS
|
|
|
|
#if __BANK
|
|
RenderDofDebug(pDOFLargeBlur, settings);
|
|
#endif
|
|
|
|
#if GTA_REPLAY
|
|
#if REPLAY_USE_PER_BLOCK_THUMBNAILS
|
|
//============================ Copy to the Replay thumbnail buffer ========================
|
|
CreateReplayThumbnail();
|
|
//=========================================================================================
|
|
#endif // REPLAY_USE_PER_BLOCK_THUMBNAILS
|
|
#endif // GTA_REPLAY
|
|
|
|
bool bDrawDamageOverlay = !settings.m_drawDamageOverlayAfterHud && (settings.m_damageEnabled[0] || settings.m_damageEnabled[1] || settings.m_damageEnabled[2] || settings.m_damageEnabled[3]);
|
|
if (bDrawDamageOverlay)
|
|
{
|
|
PostFXDamageOverlay(finalRT, PostFXTechnique, pp_DamageOverlay, settings);
|
|
}
|
|
|
|
// Draw preview border
|
|
if (CLiveManager::IsSystemUiShowing() == false && CPauseMenu::IsActive() == false && CPhoneMgr::CamGetState() && CPhotoManager::IsProcessingScreenshot() == false)
|
|
{
|
|
grcTextureFactory::GetInstance().LockRenderTarget(0, CRenderTargets::GetUIBackBuffer(), NULL);
|
|
PHONEPHOTOEDITOR.RenderBorder(true);
|
|
grcTextureFactory::GetInstance().UnlockRenderTarget(0);
|
|
}
|
|
|
|
//============================ Copy to the screenshot buffer ==============================
|
|
CPhotoManager::Execute(CRenderTargets::GetUIBackBuffer());
|
|
PHONEPHOTOEDITOR.RenderGalleryEdit();
|
|
//=========================================================================================
|
|
|
|
#if __XENON
|
|
// set the pixel shader threads to 112 -> vertex shader can only use 16 threads
|
|
GRCGPRALLOCATION->SetGPRAllocation(0);
|
|
#endif
|
|
|
|
grcStateBlock::SetRasterizerState(exitNonDepthFXRasterizerState);
|
|
grcStateBlock::SetBlendState(exitNonDepthFXBlendState);
|
|
grcStateBlock::SetDepthStencilState(exitNonDepthFXDepthStencilState);
|
|
CShaderLib::ResetScalarGlobals2();
|
|
}
|
|
|
|
|
|
grcTexture* GetValidBackBufferForSampling()
|
|
{
|
|
// Only need to copy on PC, the consoles will allow you to do Read/Modify/Write even if it's not guaranteed to be safe... unless
|
|
// we have multi-fragment MSAA, in which case the copy/resolve is necessary on the consoles too.
|
|
const bool bDoBackBufferCopy = RSG_PC ? true : ( MSAA_ONLY( GRCDEVICE.GetMSAA() > 1 ? true : ) false );
|
|
|
|
grcTexture* backBuffer;
|
|
|
|
if ( bDoBackBufferCopy )
|
|
{
|
|
ORBIS_ONLY( CRenderTargets::UnlockSceneRenderTargets() );
|
|
}
|
|
|
|
if ( bDoBackBufferCopy )
|
|
{
|
|
backBuffer = CRenderTargets::GetBackBufferCopy(true);
|
|
}
|
|
else
|
|
{
|
|
backBuffer = CRenderTargets::GetBackBuffer();
|
|
}
|
|
|
|
if ( bDoBackBufferCopy )
|
|
{
|
|
ORBIS_ONLY( CRenderTargets::LockSceneRenderTargets() );
|
|
}
|
|
|
|
return backBuffer;
|
|
}
|
|
|
|
|
|
void PostFX::DownSampleBackBuffer(int numDownSamples)
|
|
{
|
|
//Calling function should make sure they lock/unlock the render targets
|
|
#if !RSG_DURANGO
|
|
grcRenderTarget* DSBB2 = BloomBufferHalf0;
|
|
grcRenderTarget* DSBB4 = BloomBufferQuarter0;
|
|
grcRenderTarget* DSBB8 = BloomBufferEighth0;
|
|
grcRenderTarget* DSBB16 = BloomBufferSixteenth0;
|
|
#endif
|
|
|
|
if (numDownSamples < 1) return;
|
|
|
|
grcTexture* BackBuffer = GetValidBackBufferForSampling(); // don't call this more than once, on PC it will copy and resolve any MSAA each time
|
|
if (DSBB2 == NULL || BackBuffer == NULL)
|
|
{
|
|
Assertf(0, "DownSampleBackBuffer: Null backbuffer");
|
|
return;
|
|
}
|
|
|
|
PostFXShader->SetVar(TextureID_v1, grcTexture::NoneWhite);
|
|
|
|
SimpleBlitWrapper(DSBB2, BackBuffer, pp_passthrough);
|
|
|
|
if (DSBB4 && numDownSamples > 1)
|
|
{
|
|
SimpleBlitWrapper(DSBB4, DSBB2, pp_passthrough);
|
|
}
|
|
|
|
if (DSBB8 && numDownSamples > 2)
|
|
{
|
|
SimpleBlitWrapper(DSBB8, DSBB4, pp_passthrough);
|
|
}
|
|
|
|
if (DSBB16 && numDownSamples > 3)
|
|
{
|
|
SimpleBlitWrapper(DSBB16, DSBB8, pp_passthrough);
|
|
}
|
|
}
|
|
|
|
grcTexture* PostFX::GetDownSampledBackBuffer(int numDownSamples)
|
|
{
|
|
#if !RSG_DURANGO
|
|
grcRenderTarget* DSBB2 = BloomBufferHalf0;
|
|
grcRenderTarget* DSBB4 = BloomBufferQuarter0;
|
|
grcRenderTarget* DSBB8 = BloomBufferEighth0;
|
|
grcRenderTarget* DSBB16 = BloomBufferSixteenth0;
|
|
#endif
|
|
|
|
if (numDownSamples == 0)
|
|
return GetValidBackBufferForSampling();
|
|
if (numDownSamples == 1)
|
|
return DSBB2;
|
|
if (numDownSamples == 2)
|
|
return DSBB4;
|
|
if (numDownSamples == 3)
|
|
return DSBB8;
|
|
if (numDownSamples == 4)
|
|
return DSBB16;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
#if FILM_EFFECT
|
|
void PostFX::ApplyFilmEffect(int normalPass, grcRenderTarget* output, const PostFX::PostFXParamBlock::paramBlock& settings)
|
|
{
|
|
#if __BANK
|
|
if (IsTiledScreenCaptureOrPanorama())
|
|
{
|
|
return;
|
|
}
|
|
#endif // __BANK
|
|
|
|
//apply the normal pass into a special film effect rendertarget
|
|
SetNonDepthFXStateBlocks();
|
|
PostFXBlit(PreFilmEffect, PostFXTechnique, (PostFXPass)normalPass);
|
|
|
|
//render the film effect
|
|
PostFXShader->SetVar(TextureID_0, PreFilmEffect);
|
|
if(g_FilmNoise > 0.0f)
|
|
{
|
|
PostFXShader->SetVar(TextureID_1, g_pNoiseTexture);
|
|
PostFXShader->SetVar(NoiseParamsId, Vector4(NoiseEffectRandomValues.x, NoiseEffectRandomValues.y, g_FilmNoise, 1.0f));
|
|
}
|
|
|
|
if(g_FilmVignettingIntensity > 0.0f)
|
|
{
|
|
const float vignettingBias = 1.0f-g_FilmVignettingIntensity;
|
|
const float vignettingRadius = g_FilmVignettingRadius;
|
|
const float vignettingContrast = 1.0f + ((vignettingRadius-1.0f)*g_FilmVignettingContrast);
|
|
PostFXShader->SetVar(VignettingParamsId, Vector4(vignettingBias, vignettingRadius, sqrt(vignettingContrast), 0.0f));
|
|
PostFXShader->SetVar(VignettingColorId, settings.m_vignettingColour);
|
|
}
|
|
|
|
//apply the film effects to the output
|
|
SetNonDepthFXStateBlocks();
|
|
PostFXBlit(output, PostFXFilmEffectTechnique, pp_filmeffect);
|
|
}
|
|
#endif
|
|
|
|
#if USE_SCREEN_WATERMARK
|
|
|
|
bool PostFX::IsWatermarkEnabled()
|
|
{
|
|
if (PARAM_no_screen_watermark.Get())
|
|
return false;
|
|
|
|
bool waterMarkEnabled;
|
|
|
|
// draw watermark is there's an ongoing network session or we're in one of the MP menus
|
|
eFRONTEND_MENU_VERSION menuVersion = CPauseMenu::GetCurrentMenuVersion();
|
|
const bool bMenuNeedsWatermark = (menuVersion == FE_MENU_VERSION_MP_CHARACTER_CREATION) || (menuVersion == FE_MENU_VERSION_MP_CHARACTER_SELECT);
|
|
waterMarkEnabled = NetworkInterface::IsNetworkOpen() || CScriptHud::bUsingMissionCreator || bMenuNeedsWatermark BANK_ONLY(|| ms_watermarkParams.bForceWatermark);
|
|
|
|
#if WATERMARKED_BUILD
|
|
waterMarkEnabled = true;
|
|
#endif
|
|
|
|
return waterMarkEnabled;
|
|
}
|
|
|
|
void PostFX::UpdateScreenWatermark()
|
|
{
|
|
|
|
ms_watermarkParams.bEnabled = IsWatermarkEnabled();
|
|
|
|
if (ms_watermarkParams.bEnabled == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
float dayNightBalance = Lights::CalculateTimeFade(18.0f, 18.5f, 6.0f, 6.5f);
|
|
float curAlpha = Lerp(dayNightBalance, ms_watermarkParams.alphaDay, ms_watermarkParams.alphaNight);
|
|
ms_watermarkParams.textColor.SetAlpha((u8)(curAlpha*255.0f));
|
|
|
|
|
|
// get the gamer tag string
|
|
CPed* pPed = CGameWorld::FindLocalPlayer();
|
|
const char* pText = "INVALID";
|
|
|
|
if (pPed != NULL
|
|
&& pPed->GetPlayerInfo() != NULL
|
|
&& pPed->GetPlayerInfo()->m_GamerInfo.IsValid()
|
|
&& pPed->GetPlayerInfo()->m_GamerInfo.GetName() != NULL)
|
|
{
|
|
pText = pPed->GetPlayerInfo()->m_GamerInfo.GetName();
|
|
}
|
|
|
|
sprintf(&(ms_watermarkParams.text[0]), "%s", pText);
|
|
|
|
}
|
|
|
|
void PostFX::RenderScreenWatermark()
|
|
{
|
|
if (ms_watermarkParams.bEnabled == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// setup the text layout/format
|
|
Color32 textCol = ms_watermarkParams.textColor;
|
|
Vector2 textPos = ms_watermarkParams.textPos;
|
|
Vector2 textSize = Vector2(ms_watermarkParams.textSize, ms_watermarkParams.textSize);
|
|
textPos = CHudTools::CalculateHudPosition(textPos,textSize,'L','B');
|
|
bool useOutline = ms_watermarkParams.useOutline;
|
|
|
|
#if __BANK
|
|
const char* pStr = ms_watermarkParams.bUseDebugText ? &(ms_watermarkParams.debugText[0]) : &(ms_watermarkParams.text[0]);
|
|
#else
|
|
const char* pStr = &(ms_watermarkParams.text[0]);
|
|
#endif
|
|
|
|
if (strlen(pStr) > 12)
|
|
{
|
|
textSize *= 0.84f;
|
|
}
|
|
|
|
CTextLayout watermarkStringLayout;
|
|
watermarkStringLayout.SetOrientation(FONT_LEFT);
|
|
watermarkStringLayout.SetStyle(FONT_STYLE_CONDENSED);
|
|
watermarkStringLayout.SetColor(textCol);
|
|
watermarkStringLayout.SetScale(&textSize);
|
|
watermarkStringLayout.SetEdge(useOutline);
|
|
watermarkStringLayout.SetEdgeCutout(useOutline);
|
|
|
|
char watermarkString[RL_MAX_NAME_BUF_SIZE+1]={'\0'};
|
|
|
|
safecpy(watermarkString, pStr);
|
|
|
|
float charHeight = CTextFormat::GetCharacterHeight(watermarkStringLayout);
|
|
textPos.y -= charHeight*0.5f;
|
|
|
|
CRenderTargets::LockUIRenderTargets();
|
|
|
|
// override Scaleform blend state, we don't want to write alpha
|
|
sfScaleformManager* pScaleformMgr = CScaleformMgr::GetMovieMgr();
|
|
sfRendererBase& scRenderer = pScaleformMgr->GetRageRenderer();
|
|
scRenderer.OverrideBlendState(true);
|
|
|
|
grcBlendStateHandle prevBlendState = grcStateBlock::BS_Active;
|
|
grcStateBlock::SetBlendState(ms_watermarkBlendState);
|
|
|
|
// render watermark text
|
|
watermarkStringLayout.Render(&textPos, watermarkString);
|
|
|
|
//if we are using an outline, the first time we render the text we just render the outline
|
|
//with the main part of the text cut out. Then we render the text normal without the
|
|
//outline, otherwise it can look darker with the edge render along with the normal text
|
|
if(useOutline)
|
|
{
|
|
watermarkStringLayout.SetEdge(false);
|
|
watermarkStringLayout.SetEdgeCutout(false);
|
|
|
|
watermarkStringLayout.Render(&textPos, watermarkString);
|
|
}
|
|
|
|
#if DISPLAY_NETWORK_INFO
|
|
netIpAddress ip;
|
|
|
|
netHardware::GetPublicIpAddress(&ip);
|
|
char ipPubStr[netIpAddress::MAX_STRING_BUF_SIZE];
|
|
ip.Format(ipPubStr);
|
|
|
|
netHardware::GetLocalIpAddress(&ip);
|
|
char ipLocalStr[netIpAddress::MAX_STRING_BUF_SIZE];
|
|
ip.Format(ipLocalStr);
|
|
|
|
u8 macAddr[6];
|
|
netHardware::GetMacAddress(macAddr);
|
|
|
|
char netAddressString[255];
|
|
|
|
sprintf_s(netAddressString, "LIP %s EIP %s MAC %X:%X:%X:%X:%X:%X", ipLocalStr, ipPubStr, macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
|
|
|
|
Color32 netTextCol = ms_watermarkParams.netTextColor;
|
|
netTextCol.SetAlpha(textCol.GetAlpha());
|
|
Vector2 netTextPos = ms_watermarkParams.netTextPos;
|
|
Vector2 netTextSize = Vector2(ms_watermarkParams.netTextSize, ms_watermarkParams.netTextSize);
|
|
|
|
CTextLayout netAddressStringLayout = watermarkStringLayout;
|
|
|
|
netAddressStringLayout.SetColor(netTextCol);
|
|
netAddressStringLayout.SetScale(netTextSize);
|
|
|
|
charHeight = CTextFormat::GetCharacterHeight(netAddressStringLayout);
|
|
textPos.y -= charHeight*0.5f;
|
|
|
|
netAddressStringLayout.SetEdge(useOutline);
|
|
netAddressStringLayout.SetEdgeCutout(useOutline);
|
|
|
|
netAddressStringLayout.Render(&netTextPos, netAddressString);
|
|
|
|
//if we are using an outline, the first time we render the text we just render the outline
|
|
//with the main part of the text cut out. Then we render the text normal without the
|
|
//outline, otherwise it can look darker with the edge render along with the normal text
|
|
if(useOutline)
|
|
{
|
|
netAddressStringLayout.SetEdge(false);
|
|
netAddressStringLayout.SetEdgeCutout(false);
|
|
|
|
netAddressStringLayout.Render(&netTextPos, netAddressString);
|
|
}
|
|
#endif
|
|
|
|
CText::Flush();
|
|
|
|
// restore blend state
|
|
grcStateBlock::SetBlendState(prevBlendState);
|
|
scRenderer.OverrideBlendState(false);
|
|
|
|
CRenderTargets::UnlockUIRenderTargets();
|
|
|
|
#if USE_IMAGE_WATERMARKS
|
|
grcTexture *WatermarkTexture = g_TxdStore.Get(g_TxdSlot)->Lookup("bokeh_pent");
|
|
grcTexture *HiddenWatermarkTexture = g_TxdStore.Get(g_TxdSlot)->Lookup("bokeh_deca");
|
|
|
|
Vec2f watermarkPos = GetWatermarkPostion();
|
|
|
|
float alpha = ms_watermarkParams.textColor.GetAlpha() / 256.0f;
|
|
|
|
RenderWatermarkImage(WatermarkTexture, watermarkPos, true, alpha);
|
|
|
|
RenderWatermarkImage(HiddenWatermarkTexture, Vec2f(0.25f, 0.0f), false, 1.0f);
|
|
RenderWatermarkImage(HiddenWatermarkTexture, Vec2f(0.75f, 0.0f), false, 1.0f);
|
|
#endif
|
|
|
|
}
|
|
#endif // USE_SCREEN_WATERMARK
|
|
|
|
#if USE_IMAGE_WATERMARKS
|
|
void PostFX::RenderWatermarkImage(const grcTexture* watermark, const Vec2f& pos, bool scale, float alpha)
|
|
{
|
|
Assertf(watermark, "Error, null watermark texture");
|
|
|
|
if(watermark == NULL)
|
|
return;
|
|
|
|
float screenWidth = scale ? 1280.0f : (float)GRCDEVICE.GetWidth();
|
|
float screenHeight = scale ? 720.0f : (float)GRCDEVICE.GetHeight();
|
|
float textureWidth = (float)watermark->GetWidth();
|
|
float textureHeight = (float)watermark->GetHeight();
|
|
|
|
float scaleX = textureWidth * (1.0f / screenWidth);
|
|
float scaleY = textureHeight * (1.0f / screenHeight);
|
|
|
|
AssertVerify(PostFXShader->BeginDraw(grmShader::RMC_DRAW, false, PostFXTechnique));
|
|
#if POSTFX_UNIT_QUAD
|
|
PostFXShader->SetVar(quad::Position, FastQuad::Pack(-1.0f + pos.GetX() * 2,
|
|
1.0f - pos.GetY() * 2,
|
|
1.0f + pos.GetX() * 2 ,
|
|
-1.0f - pos.GetY() * 2));
|
|
PostFXShader->SetVar(quad::TexCoords, FastQuad::Pack(0.0f, 0.0f, 1.0f, 1.0f));
|
|
PostFXShader->SetVar(quad::Scale, Vector4(scaleX, scaleY, 1.0f, 1.0f));
|
|
PostFXShader->SetVar(quad::Alpha, alpha);
|
|
#endif
|
|
PostFXShader->SetVar(TextureID_0, watermark);
|
|
|
|
PostFXShader->Bind((int)pp_passthrough);
|
|
grcStateBlock::SetBlendState(imageWatermarkBlendState);
|
|
|
|
#if POSTFX_UNIT_QUAD
|
|
FastQuad::Draw(false);
|
|
#endif
|
|
|
|
PostFXShader->UnBind();
|
|
PostFXShader->EndDraw();
|
|
|
|
grcStateBlock::SetBlendState(nonDepthFXBlendState);
|
|
}
|
|
#endif // USE_IMAGE_WATERMARKS
|
|
|
|
void PostFX::UpdateVisualDataSettings()
|
|
{
|
|
if (g_visualSettings.GetIsLoaded())
|
|
{
|
|
g_filmicTonemapParams[TONEMAP_FILMIC_A_BRIGHT] = g_visualSettings.Get("Tonemapping.bright.filmic.A", 0.22f);
|
|
g_filmicTonemapParams[TONEMAP_FILMIC_B_BRIGHT] = g_visualSettings.Get("Tonemapping.bright.filmic.B", 0.3f);
|
|
g_filmicTonemapParams[TONEMAP_FILMIC_C_BRIGHT] = g_visualSettings.Get("Tonemapping.bright.filmic.C", 0.10f);
|
|
g_filmicTonemapParams[TONEMAP_FILMIC_D_BRIGHT] = g_visualSettings.Get("Tonemapping.bright.filmic.D", 0.20f);
|
|
g_filmicTonemapParams[TONEMAP_FILMIC_E_BRIGHT] = g_visualSettings.Get("Tonemapping.bright.filmic.E", 0.01f);
|
|
g_filmicTonemapParams[TONEMAP_FILMIC_F_BRIGHT] = g_visualSettings.Get("Tonemapping.bright.filmic.F", 0.30f);
|
|
g_filmicTonemapParams[TONEMAP_FILMIC_W_BRIGHT] = g_visualSettings.Get("Tonemapping.bright.filmic.W", 4.00f);
|
|
g_filmicTonemapParams[TONEMAP_FILMIC_EXPOSURE_BRIGHT] = g_visualSettings.Get("Tonemapping.bright.filmic.exposure", -2.0f);
|
|
|
|
g_filmicTonemapParams[TONEMAP_FILMIC_A_DARK] = g_visualSettings.Get("Tonemapping.dark.filmic.A", 0.22f);
|
|
g_filmicTonemapParams[TONEMAP_FILMIC_B_DARK] = g_visualSettings.Get("Tonemapping.dark.filmic.B", 0.3f);
|
|
g_filmicTonemapParams[TONEMAP_FILMIC_C_DARK] = g_visualSettings.Get("Tonemapping.dark.filmic.C", 0.10f);
|
|
g_filmicTonemapParams[TONEMAP_FILMIC_D_DARK] = g_visualSettings.Get("Tonemapping.dark.filmic.D", 0.20f);
|
|
g_filmicTonemapParams[TONEMAP_FILMIC_E_DARK] = g_visualSettings.Get("Tonemapping.dark.filmic.E", 0.01f);
|
|
g_filmicTonemapParams[TONEMAP_FILMIC_F_DARK] = g_visualSettings.Get("Tonemapping.dark.filmic.F", 0.30f);
|
|
g_filmicTonemapParams[TONEMAP_FILMIC_W_DARK] = g_visualSettings.Get("Tonemapping.dark.filmic.W", 4.00f);
|
|
g_filmicTonemapParams[TONEMAP_FILMIC_EXPOSURE_DARK] = g_visualSettings.Get("Tonemapping.dark.filmic.exposure", 1.0f);
|
|
|
|
float sniperSightEnabled = g_visualSettings.Get("misc.SniperRifleDof.Enabled", 0.0f);
|
|
g_sniperSightDefaultEnabled = sniperSightEnabled > 0.0f;
|
|
g_sniperSightDefaultDOFParams.x = g_visualSettings.Get("misc.SniperRifleDof.NearStart", 0.0f);
|
|
g_sniperSightDefaultDOFParams.y = g_visualSettings.Get("misc.SniperRifleDof.NearEnd", 0.0f);
|
|
g_sniperSightDefaultDOFParams.z = g_visualSettings.Get("misc.SniperRifleDof.FarStart", 0.0f);
|
|
g_sniperSightDefaultDOFParams.w = g_visualSettings.Get("misc.SniperRifleDof.FarEnd", 2180.0f);
|
|
|
|
PostFXParamBlock::UpdateVisualSettings();
|
|
g_sunExposureAdjust = g_visualSettings.Get("Adaptation.sun.exposure.tweak", 0.0f);
|
|
|
|
g_bloomThresholdMin = g_visualSettings.Get("bloom.threshold.min", 0.3f);
|
|
g_bloomThresholdPower = g_visualSettings.Get("bloom.threshold.power", 1.0f);
|
|
g_bloomThresholdExposureDiffMin = g_visualSettings.Get("bloom.threshold.expsoure.diff.min", 0.1f);
|
|
g_bloomThresholdExposureDiffMax = g_visualSettings.Get("bloom.threshold.expsoure.diff.max", 1.0f);
|
|
|
|
g_bloomLargeBlurBlendMult = g_visualSettings.Get("bloom.blurblendmult.large", 0.5f);
|
|
g_bloomMedBlurBlendMult = g_visualSettings.Get("bloom.blurblendmult.med", 0.5f);
|
|
g_bloomSmallBlurBlendMult = g_visualSettings.Get("bloom.blurblendmult.small", 1.0f);
|
|
|
|
g_bulletImpactOverlay.ms_screenSafeZoneLength = g_visualSettings.Get("misc.DamageOverlay.ScreenSafeZoneLength", 1.0f);
|
|
|
|
g_bulletImpactOverlay.ms_settings[0].rampUpDuration = (u32)g_visualSettings.Get("misc.DamageOverlay.RampUpDuration", 50);
|
|
g_bulletImpactOverlay.ms_settings[0].holdDuration = (u32)g_visualSettings.Get("misc.DamageOverlay.HoldDuration", 400);
|
|
g_bulletImpactOverlay.ms_settings[0].rampDownDuration = (u32)g_visualSettings.Get("misc.DamageOverlay.RampDownDuration", 100);
|
|
g_bulletImpactOverlay.ms_settings[0].colourBottom.x = g_visualSettings.Get("misc.DamageOverlay.ColorBottom.red", 0.54f);
|
|
g_bulletImpactOverlay.ms_settings[0].colourBottom.y = g_visualSettings.Get("misc.DamageOverlay.ColorBottom.green", 0.06f);
|
|
g_bulletImpactOverlay.ms_settings[0].colourBottom.z = g_visualSettings.Get("misc.DamageOverlay.ColorBottom.blue", 0.00f);
|
|
g_bulletImpactOverlay.ms_settings[0].colourTop.x = g_visualSettings.Get("misc.DamageOverlay.ColorTop.red", 0.54f);
|
|
g_bulletImpactOverlay.ms_settings[0].colourTop.y = g_visualSettings.Get("misc.DamageOverlay.ColorTop.green", 0.06f);
|
|
g_bulletImpactOverlay.ms_settings[0].colourTop.z = g_visualSettings.Get("misc.DamageOverlay.ColorTop.blue", 0.00f);
|
|
g_bulletImpactOverlay.ms_settings[0].colourBottomEndurance.x = g_visualSettings.Get("misc.DamageOverlay.colourBottomEndurance.red", 0.99f);
|
|
g_bulletImpactOverlay.ms_settings[0].colourBottomEndurance.y = g_visualSettings.Get("misc.DamageOverlay.colourBottomEndurance.green", 0.59f);
|
|
g_bulletImpactOverlay.ms_settings[0].colourBottomEndurance.z = g_visualSettings.Get("misc.DamageOverlay.colourBottomEndurance.blue", 0.32f);
|
|
g_bulletImpactOverlay.ms_settings[0].colourTopEndurance.x = g_visualSettings.Get("misc.DamageOverlay.colourTopEndurance.red", 0.99f);
|
|
g_bulletImpactOverlay.ms_settings[0].colourTopEndurance.y = g_visualSettings.Get("misc.DamageOverlay.colourTopEndurance.green", 0.59f);
|
|
g_bulletImpactOverlay.ms_settings[0].colourTopEndurance.z = g_visualSettings.Get("misc.DamageOverlay.colourTopEndurance.blue", 0.32f);
|
|
g_bulletImpactOverlay.ms_settings[0].globalAlphaBottom = g_visualSettings.Get("misc.DamageOverlay.GlobalAlphaBottom", 1.0f);
|
|
g_bulletImpactOverlay.ms_settings[0].globalAlphaTop = g_visualSettings.Get("misc.DamageOverlay.GlobalAlphaTop", 0.75f);
|
|
g_bulletImpactOverlay.ms_settings[0].spriteLength = g_visualSettings.Get("misc.DamageOverlay.SpriteLength", 0.25f);
|
|
g_bulletImpactOverlay.ms_settings[0].spriteBaseWidth = g_visualSettings.Get("misc.DamageOverlay.SpriteBaseWidth", 0.2f);
|
|
g_bulletImpactOverlay.ms_settings[0].spriteTipWidth = g_visualSettings.Get("misc.DamageOverlay.SpriteTipWidth", 0.05f);
|
|
g_bulletImpactOverlay.ms_settings[0].angleScalingMult = g_visualSettings.Get("misc.DamageOverlay.AngleScalingMult", 0.85f);
|
|
|
|
g_bulletImpactOverlay.ms_settings[1].rampUpDuration = (u32)g_visualSettings.Get("misc.DamageOverlay.FP.RampUpDuration", 50);
|
|
g_bulletImpactOverlay.ms_settings[1].holdDuration = (u32)g_visualSettings.Get("misc.DamageOverlay.FP.HoldDuration", 400);
|
|
g_bulletImpactOverlay.ms_settings[1].rampDownDuration = (u32)g_visualSettings.Get("misc.DamageOverlay.FP.RampDownDuration", 100);
|
|
g_bulletImpactOverlay.ms_settings[1].colourBottom.x = g_visualSettings.Get("misc.DamageOverlay.FP.ColorBottom.red", 0.54f);
|
|
g_bulletImpactOverlay.ms_settings[1].colourBottom.y = g_visualSettings.Get("misc.DamageOverlay.FP.ColorBottom.green", 0.06f);
|
|
g_bulletImpactOverlay.ms_settings[1].colourBottom.z = g_visualSettings.Get("misc.DamageOverlay.FP.ColorBottom.blue", 0.00f);
|
|
g_bulletImpactOverlay.ms_settings[1].colourTop.x = g_visualSettings.Get("misc.DamageOverlay.FP.ColorTop.red", 0.54f);
|
|
g_bulletImpactOverlay.ms_settings[1].colourTop.y = g_visualSettings.Get("misc.DamageOverlay.FP.ColorTop.green", 0.06f);
|
|
g_bulletImpactOverlay.ms_settings[1].colourTop.z = g_visualSettings.Get("misc.DamageOverlay.FP.ColorTop.blue", 0.00f);
|
|
g_bulletImpactOverlay.ms_settings[1].colourBottomEndurance.x = g_visualSettings.Get("misc.DamageOverlay.colourBottomEndurance.red", 0.99f);
|
|
g_bulletImpactOverlay.ms_settings[1].colourBottomEndurance.y = g_visualSettings.Get("misc.DamageOverlay.colourBottomEndurance.green", 0.59f);
|
|
g_bulletImpactOverlay.ms_settings[1].colourBottomEndurance.z = g_visualSettings.Get("misc.DamageOverlay.colourBottomEndurance.blue", 0.32f);
|
|
g_bulletImpactOverlay.ms_settings[1].colourTopEndurance.x = g_visualSettings.Get("misc.DamageOverlay.colourTopEndurance.red", 0.99f);
|
|
g_bulletImpactOverlay.ms_settings[1].colourTopEndurance.y = g_visualSettings.Get("misc.DamageOverlay.colourTopEndurance.green", 0.59f);
|
|
g_bulletImpactOverlay.ms_settings[1].colourTopEndurance.z = g_visualSettings.Get("misc.DamageOverlay.colourTopEndurance.blue", 0.32f);
|
|
g_bulletImpactOverlay.ms_settings[1].globalAlphaBottom = g_visualSettings.Get("misc.DamageOverlay.FP.GlobalAlphaBottom", 1.0f);
|
|
g_bulletImpactOverlay.ms_settings[1].globalAlphaTop = g_visualSettings.Get("misc.DamageOverlay.FP.GlobalAlphaTop", 0.75f);
|
|
g_bulletImpactOverlay.ms_settings[1].spriteLength = g_visualSettings.Get("misc.DamageOverlay.FP.SpriteLength", 0.25f);
|
|
g_bulletImpactOverlay.ms_settings[1].spriteBaseWidth = g_visualSettings.Get("misc.DamageOverlay.FP.SpriteBaseWidth", 0.2f);
|
|
g_bulletImpactOverlay.ms_settings[1].spriteTipWidth = g_visualSettings.Get("misc.DamageOverlay.FP.SpriteTipWidth", 0.05f);
|
|
g_bulletImpactOverlay.ms_settings[1].angleScalingMult = g_visualSettings.Get("misc.DamageOverlay.FP.AngleScalingMult", 0.85f);
|
|
|
|
#if BOKEH_SUPPORT
|
|
BokehBrightnessExposureMin = g_visualSettings.Get("bokeh.brightnessExposureMin", -3.0f);
|
|
BokehBrightnessExposureMax = g_visualSettings.Get("bokeh.brightnessExposureMax", 1.0f);
|
|
BokehBlurThresholdVal = g_visualSettings.Get("bokeh.cocThreshold", 0.05f);
|
|
bokehSizeMultiplier = g_visualSettings.Get("bokeh.sizeMultiplier", 1.5f);
|
|
BokehGlobalAlpha = g_visualSettings.Get("bokeh.globalAlpha", 1.0f);
|
|
BokehAlphaCutoff = g_visualSettings.Get("bokeh.alphaCutoff", 0.15f);
|
|
|
|
BokehShapeExposureRangeMin = g_visualSettings.Get("bokeh.shapeExposureRangeMin", -3.0f);
|
|
BokehShapeExposureRangeMax = g_visualSettings.Get("bokeh.shapeExposureRangeMax", 1.0f);
|
|
|
|
#endif // BOKEH_SUPPORT
|
|
|
|
g_DefaultMotionBlurEnabled = ((g_visualSettings.Get("defaultmotionblur.enabled", 0.0f)) > 0.0f);
|
|
g_DefaultMotionBlurStrength = g_visualSettings.Get("defaultmotionblur.strength", 0.04f);
|
|
|
|
fpvMotionBlurWeights = Vector3(
|
|
g_visualSettings.Get("fpv.motionblur.weight0", 1.0f),
|
|
g_visualSettings.Get("fpv.motionblur.weight1", 0.0f),
|
|
g_visualSettings.Get("fpv.motionblur.weight2", 0.8f),
|
|
g_visualSettings.Get("fpv.motionblur.weight3", 1.0f));
|
|
|
|
fpvMotionVelocityMaxSize = g_visualSettings.Get("fpv.motionblur.max.velocity", 32.0f),
|
|
|
|
#if ADAPTIVE_DOF
|
|
AdaptiveDepthOfField.UpdateVisualDataSettings();
|
|
#endif
|
|
}
|
|
}
|
|
|
|
// Update visual setting after reload. This should only be called from PostFX::UpdateVisualDataSettings()
|
|
void PostFX::PostFXParamBlock::UpdateVisualSettings()
|
|
{
|
|
PostFXParamBlock::ms_params[0].m_exposureCurveA = g_visualSettings.Get("Exposure.curve.scale", -1.0668907449987120E+02f);
|
|
PostFXParamBlock::ms_params[0].m_exposureCurveB = g_visualSettings.Get("Exposure.curve.power", 4.1897015173052825E-03f);
|
|
PostFXParamBlock::ms_params[0].m_exposureCurveOffset = g_visualSettings.Get("Exposure.curve.offset", 1.0460364172443734E+02f);
|
|
|
|
PostFXParamBlock::ms_params[1].m_exposureCurveA = PostFXParamBlock::ms_params[0].m_exposureCurveA;
|
|
PostFXParamBlock::ms_params[1].m_exposureCurveB = PostFXParamBlock::ms_params[0].m_exposureCurveB;
|
|
PostFXParamBlock::ms_params[1].m_exposureCurveOffset = PostFXParamBlock::ms_params[0].m_exposureCurveOffset;
|
|
|
|
PostFXParamBlock::ms_params[0].m_adaptionMinStepSize = g_visualSettings.Get("Adaptation.min.step.size", 0.15f);
|
|
PostFXParamBlock::ms_params[0].m_adaptionMaxStepSize = g_visualSettings.Get("Adaptation.max.step.size", 15.0f);
|
|
PostFXParamBlock::ms_params[0].m_adaptionStepMult = g_visualSettings.Get("Adaptation.step.size.mult", 9.0f);
|
|
PostFXParamBlock::ms_params[0].m_adaptionThreshold = g_visualSettings.Get("Adaptation.threshold", 0.0f);
|
|
|
|
PostFXParamBlock::ms_params[1].m_adaptionMinStepSize = PostFXParamBlock::ms_params[0].m_adaptionMinStepSize;
|
|
PostFXParamBlock::ms_params[1].m_adaptionMaxStepSize = PostFXParamBlock::ms_params[0].m_adaptionMaxStepSize;
|
|
PostFXParamBlock::ms_params[1].m_adaptionStepMult = PostFXParamBlock::ms_params[0].m_adaptionStepMult;
|
|
PostFXParamBlock::ms_params[1].m_adaptionThreshold = PostFXParamBlock::ms_params[0].m_adaptionThreshold;
|
|
}
|
|
|
|
void PostFX::SetLDR8bitHDR8bit()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
|
|
float packScalar8 = PostFX::GetPackScalar8bit();
|
|
|
|
const float toneMapScaler = 1.0f / packScalar8;
|
|
const float unToneMapScaler = packScalar8;
|
|
|
|
Vector4 scalers(
|
|
toneMapScaler,
|
|
unToneMapScaler,
|
|
toneMapScaler,
|
|
unToneMapScaler);
|
|
|
|
CShaderLib::SetGlobalToneMapScalers(scalers);
|
|
}
|
|
|
|
void PostFX::SetLDR16bitHDR16bit()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
Vector4 scalers(
|
|
1.0f,
|
|
1.0f,
|
|
1.0f,
|
|
1.0f);
|
|
|
|
CShaderLib::SetGlobalToneMapScalers(scalers);
|
|
}
|
|
|
|
#if __XENON
|
|
void PostFX::SetLDR8bitHDR10bit()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
|
|
float packScalar8 = PostFX::GetPackScalar8bit();
|
|
|
|
const float toneMapScaler8 = 1.0f / packScalar8;
|
|
const float unToneMapScaler8 = packScalar8;
|
|
|
|
float packScalar10 = PostFX::GetPackScalar10bit();
|
|
|
|
const float toneMapScaler10 = 1.0f / packScalar10;
|
|
const float unToneMapScaler10 = packScalar10;
|
|
|
|
Vector4 scalers(
|
|
toneMapScaler8,
|
|
unToneMapScaler8,
|
|
toneMapScaler10,
|
|
unToneMapScaler10);
|
|
|
|
CShaderLib::SetGlobalToneMapScalers(scalers);
|
|
}
|
|
|
|
void PostFX::SetLDR10bitHDR10bit()
|
|
{
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
|
|
float packScalar10 = PostFX::GetPackScalar10bit();
|
|
|
|
const float toneMapScaler = 1.0f / packScalar10;
|
|
const float unToneMapScaler = packScalar10;
|
|
|
|
Vector4 scalers(
|
|
toneMapScaler,
|
|
unToneMapScaler,
|
|
toneMapScaler,
|
|
unToneMapScaler);
|
|
|
|
CShaderLib::SetGlobalToneMapScalers(scalers);
|
|
}
|
|
#endif
|
|
|
|
void PostFX::SetLDR8bitHDR16bit()
|
|
{
|
|
#if DEBUG_HDR_BUFFER
|
|
SetLDR8bitHDR8bit();
|
|
#else
|
|
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
|
|
|
|
float packScalar8 = PostFX::GetPackScalar8bit();
|
|
|
|
const float toneMapScaler = 1.0f / packScalar8;
|
|
const float unToneMapScaler = packScalar8;
|
|
|
|
Vector4 scalers(
|
|
toneMapScaler,
|
|
unToneMapScaler,
|
|
1.0f,
|
|
1.0f);
|
|
|
|
CShaderLib::SetGlobalToneMapScalers(scalers);
|
|
#endif //DEBUG_HDR_BUFFER
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// PedKillOverlay
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
PostFX::PedKillOverlay::PedKillOverlay()
|
|
{
|
|
m_effectName = atHashString("PedGunKill", 0x9cfb4c6e);
|
|
m_disable = false;
|
|
}
|
|
|
|
void PostFX::PedKillOverlay::Trigger()
|
|
{
|
|
if( m_disable )
|
|
return;
|
|
|
|
// Don't trigger this if any effect stack is already running or else
|
|
// we might get weird blending/tc mods overriding each other
|
|
if (ANIMPOSTFXMGR.IsIdle() == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ANIMPOSTFXMGR.Start(m_effectName, 0U, false, false, false, 0U, AnimPostFXManager::kPedKill);
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void PostFX::ScreenBlurFade::Init()
|
|
{
|
|
m_state = (int)SBF_IDLE;
|
|
m_fFadeLevel = 0.0f;
|
|
m_fDuration = 250.0f;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void PostFX::ScreenBlurFade::UpdateOnLoadingScreen()
|
|
{
|
|
if (m_state == (int)SBF_IDLE)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// automatically turn effect off if it was fading out
|
|
if (m_state == (int)SBF_FADING_OUT && m_fFadeLevel == 1.0f)
|
|
{
|
|
Reset();
|
|
return;
|
|
}
|
|
|
|
m_fFadeLevel += (((float)fwTimer::GetTimeStepInMilliseconds())/m_fDuration);
|
|
if (m_fFadeLevel >= 1.0f)
|
|
{
|
|
m_fFadeLevel = 1.0f;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void PostFX::ScreenBlurFade::Update()
|
|
{
|
|
|
|
if (m_state == (int)SBF_IDLE)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// automatically turn effect off if it was fading out
|
|
if (m_state == (int)SBF_FADING_OUT && m_fFadeLevel == 1.0f)
|
|
{
|
|
Reset();
|
|
return;
|
|
}
|
|
|
|
m_fFadeLevel += (((float)fwTimer::GetTimeStepInMilliseconds())/m_fDuration);
|
|
if (m_fFadeLevel >= 1.0f)
|
|
{
|
|
m_fFadeLevel = 1.0f;
|
|
}
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void PostFX::ScreenBlurFade::Trigger(bool bFadeOut)
|
|
{
|
|
if (m_state != (int)SBF_IDLE && bFadeOut == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (bFadeOut && m_state != (int)SBF_FADING_IN)
|
|
{
|
|
return;
|
|
}
|
|
|
|
m_state = (int)(bFadeOut ? SBF_FADING_OUT : SBF_FADING_IN);
|
|
m_fFadeLevel = 0.0f;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void PostFX::BulletImpactOverlay::Entry::Reset()
|
|
{
|
|
m_firingWeaponPos.Zero();
|
|
m_fFadeLevel = 0.0f;
|
|
m_fIntensity = 0.0f;
|
|
m_startTime = 0;
|
|
m_bFrozen = false;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
PostFX::BulletImpactOverlay::Entry* PostFX::BulletImpactOverlay::GetFreeEntry()
|
|
{
|
|
for (int i = 0; i < NUM_ENTRIES; i++)
|
|
{
|
|
if (m_entries[i].m_startTime == 0)
|
|
{
|
|
return &m_entries[i];
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void PostFX::BulletImpactOverlay::Init()
|
|
{
|
|
|
|
for (int i = 0; i < NUM_ENTRIES; i++)
|
|
{
|
|
m_entries[i].Reset();
|
|
}
|
|
|
|
#if __BANK
|
|
m_bEnableDebugRender = false;
|
|
#endif
|
|
|
|
m_drawAfterHud = false;
|
|
|
|
// create the vertex declaration
|
|
grcVertexElement elem[] = {
|
|
grcVertexElement(0, grcVertexElement::grcvetPosition, 0, 12, grcFvf::grcdsFloat3),
|
|
grcVertexElement(0, grcVertexElement::grcvetColor, 0, 4, grcFvf::grcdsColor),
|
|
grcVertexElement(0, grcVertexElement::grcvetTexture, 0, 12, grcFvf::grcdsFloat3)
|
|
};
|
|
g_damageSliceDecl = GRCDEVICE.CreateVertexDeclaration(elem,sizeof(elem)/sizeof(grcVertexElement));
|
|
|
|
for (int i = 0; i < DOT_COUNT; i++)
|
|
{
|
|
ms_settings[i].rampUpDuration = 100;
|
|
ms_settings[i].rampDownDuration = 700;
|
|
ms_settings[i].holdDuration = 200;
|
|
ms_settings[i].spriteLength = 0.25f;
|
|
ms_settings[i].spriteBaseWidth = 0.2f;
|
|
ms_settings[i].spriteTipWidth = 0.05f;
|
|
ms_settings[i].globalAlphaBottom = 1.0f;
|
|
ms_settings[i].globalAlphaTop = 1.0f;
|
|
ms_settings[i].angleScalingMult = 0.85f;
|
|
}
|
|
|
|
m_disabled = false;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void PostFX::BulletImpactOverlay::RegisterBulletImpact(const Vector3& vWeaponPos, f32 damageIntensity, bool bIsEnduranceDamage)
|
|
{
|
|
if( m_disabled )
|
|
{
|
|
weaponDebugf3("BulletImpactOverlay::RegisterBulletImpact - m_disabled");
|
|
return;
|
|
}
|
|
|
|
Entry* pEntry = GetFreeEntry();
|
|
|
|
if (pEntry == NULL)
|
|
{
|
|
weaponDebugf3("BulletImpactOverlay::RegisterBulletImpact - pEntry == NULL");
|
|
return;
|
|
}
|
|
|
|
pEntry->m_firingWeaponPos = vWeaponPos;
|
|
pEntry->m_fFadeLevel = 0.0f;
|
|
pEntry->m_fIntensity = damageIntensity;
|
|
pEntry->m_startTime = 1;
|
|
pEntry->m_bIsEnduranceDamage = bIsEnduranceDamage;
|
|
weaponDebugf3("BulletImpactOverlay::RegisterBulletImpact - Triggered");
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void PostFX::BulletImpactOverlay::UpdateTiming(Entry* pEntry, const Settings& settings)
|
|
{
|
|
if (pEntry->m_startTime == 1)
|
|
{
|
|
pEntry->m_startTime = fwTimer::GetTimeInMilliseconds_NonScaledClipped();
|
|
}
|
|
|
|
if (pEntry->m_startTime != 0)
|
|
{
|
|
const u32 c_uCurrentTime = fwTimer::GetTimeInMilliseconds_NonScaledClipped();
|
|
float fInterp = 0.0f;
|
|
if (c_uCurrentTime < pEntry->m_startTime + settings.rampUpDuration)
|
|
{
|
|
// Ramping up
|
|
fInterp = (float)(c_uCurrentTime - pEntry->m_startTime) / (float)settings.rampUpDuration;
|
|
}
|
|
else if (c_uCurrentTime < pEntry->m_startTime + settings.rampUpDuration + settings.holdDuration)
|
|
{
|
|
fInterp = 1.0f;
|
|
}
|
|
else if (c_uCurrentTime < pEntry->m_startTime + settings.rampUpDuration + settings.holdDuration + settings.rampDownDuration)
|
|
{
|
|
fInterp = (float)(settings.rampDownDuration - (c_uCurrentTime - pEntry->m_startTime - settings.rampUpDuration - settings.holdDuration)) / (float)settings.rampDownDuration;
|
|
}
|
|
else
|
|
{
|
|
pEntry->Reset();
|
|
}
|
|
|
|
pEntry->m_fFadeLevel = fInterp;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void PostFX::Adaptation::Synchronise()
|
|
{
|
|
ms_bufferIndex ^= 1;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void PostFX::ApplyFXAA(grcRenderTarget *pDstRT, grcRenderTarget *pSrcRT, const Vector4 &scissorRect)
|
|
{
|
|
GRC_ALLOC_SCOPE_AUTO_PUSH_POP()
|
|
|
|
PostFXShader->SetVar(FXAABackBuffer, pSrcRT);
|
|
|
|
// rcpFrameId
|
|
const float rcpWidth = 1.0f / pSrcRT->GetWidth();
|
|
const float rcpHeight = 1.0f / pSrcRT->GetHeight();
|
|
|
|
PostFXShader->SetVar(rcpFrameId, Vector2(rcpWidth, rcpHeight));
|
|
|
|
SetNonDepthFXStateBlocks();
|
|
|
|
grcTextureFactory::GetInstance().LockRenderTarget(0, pDstRT, NULL);
|
|
|
|
GRCDEVICE.SetScissor((int)scissorRect.x, (int)scissorRect.y, (int)scissorRect.z, (int)scissorRect.w);
|
|
|
|
PostFXBlit(NULL, PostFXTechnique, FXAAPassToUse, false, false, NULL,
|
|
#if __D3D11 || RSG_ORBIS
|
|
false
|
|
#else
|
|
XENON_SWITCH(true, false)
|
|
#endif
|
|
);
|
|
|
|
grcResolveFlags resolveFlags;
|
|
resolveFlags.ClearColor = false;
|
|
resolveFlags.NeedResolve = XENON_SWITCH(true, false);
|
|
grcTextureFactory::GetInstance().UnlockRenderTarget(0, &resolveFlags);
|
|
}
|
|
|
|
#if PTFX_APPLY_DOF_TO_PARTICLES || APPLY_DOF_TO_ALPHA_DECALS
|
|
void PostFX::SetupBlendForDOF(grcBlendStateDesc &blendStateDesc, bool forAlphaPass)
|
|
{
|
|
blendStateDesc.IndependentBlendEnable = 1;
|
|
|
|
//use a different set of blend states for the alpha pass,
|
|
//as its rendered back to front its better just to use the last value thats written in
|
|
if(forAlphaPass)
|
|
{
|
|
//Setup blend state for particle depth
|
|
blendStateDesc.BlendRTDesc[1].BlendEnable = 1;
|
|
blendStateDesc.BlendRTDesc[1].DestBlend = grcRSV::BLEND_ZERO;
|
|
blendStateDesc.BlendRTDesc[1].SrcBlend = grcRSV::BLEND_ONE;
|
|
blendStateDesc.BlendRTDesc[1].BlendOp = grcRSV::BLENDOP_ADD;
|
|
blendStateDesc.BlendRTDesc[1].SrcBlendAlpha = grcRSV::BLEND_ONE;
|
|
blendStateDesc.BlendRTDesc[1].DestBlendAlpha = grcRSV::BLEND_ZERO;
|
|
blendStateDesc.BlendRTDesc[1].BlendOpAlpha = grcRSV::BLENDOP_ADD;
|
|
|
|
//Setup blend state for particle alpha
|
|
blendStateDesc.BlendRTDesc[2].BlendEnable = 1;
|
|
blendStateDesc.BlendRTDesc[2].DestBlend = grcRSV::BLEND_ZERO;
|
|
blendStateDesc.BlendRTDesc[2].SrcBlend = grcRSV::BLEND_ONE;
|
|
blendStateDesc.BlendRTDesc[2].BlendOp = grcRSV::BLENDOP_ADD;
|
|
blendStateDesc.BlendRTDesc[2].SrcBlendAlpha = grcRSV::BLEND_ONE;
|
|
blendStateDesc.BlendRTDesc[2].DestBlendAlpha = grcRSV::BLEND_ZERO;
|
|
blendStateDesc.BlendRTDesc[2].BlendOpAlpha = grcRSV::BLENDOP_ADD;
|
|
}
|
|
else
|
|
{
|
|
//Setup blend state for particle depth
|
|
blendStateDesc.BlendRTDesc[1].BlendEnable = 1;
|
|
blendStateDesc.BlendRTDesc[1].DestBlend = grcRSV::BLEND_ONE;
|
|
blendStateDesc.BlendRTDesc[1].SrcBlend = grcRSV::BLEND_ONE;
|
|
blendStateDesc.BlendRTDesc[1].BlendOp = grcRSV::BLENDOP_MAX;
|
|
blendStateDesc.BlendRTDesc[1].SrcBlendAlpha = grcRSV::BLEND_ONE;
|
|
blendStateDesc.BlendRTDesc[1].DestBlendAlpha = grcRSV::BLEND_ONE;
|
|
blendStateDesc.BlendRTDesc[1].BlendOpAlpha = grcRSV::BLENDOP_MAX;
|
|
|
|
//Setup blend state for particle alpha
|
|
blendStateDesc.BlendRTDesc[2].BlendEnable = 1;
|
|
blendStateDesc.BlendRTDesc[2].DestBlend = grcRSV::BLEND_ONE;
|
|
blendStateDesc.BlendRTDesc[2].SrcBlend = grcRSV::BLEND_INVSRCALPHA;
|
|
blendStateDesc.BlendRTDesc[2].BlendOp = grcRSV::BLENDOP_ADD;
|
|
blendStateDesc.BlendRTDesc[2].SrcBlendAlpha = grcRSV::BLEND_ONE;
|
|
blendStateDesc.BlendRTDesc[2].DestBlendAlpha = grcRSV::BLEND_INVSRCALPHA;
|
|
blendStateDesc.BlendRTDesc[2].BlendOpAlpha = grcRSV::BLENDOP_ADD;
|
|
}
|
|
}
|
|
#endif //PTFX_APPLY_DOF_TO_PARTICLES || APPLY_DOF_TO_ALPHA_DECALS
|
|
|
|
|
|
#if GTA_REPLAY
|
|
#if REPLAY_USE_PER_BLOCK_THUMBNAILS
|
|
|
|
void PostFX::CreateReplayThumbnail()
|
|
{
|
|
CReplayThumbnail::CreateReplayThumbnail();
|
|
}
|
|
|
|
#endif // REPLAY_USE_PER_BLOCK_THUMBNAILS
|
|
#endif // GTA_REPLAY
|