Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
PostFX.cpp
Go to the documentation of this file.
1
2
3#include "Headers/PostFX.h"
5
11
14
19
21
23
24namespace Divide
25{
26
27 const char* PostFX::FilterName( const FilterType filter ) noexcept
28 {
29 switch ( filter )
30 {
31 case FilterType::FILTER_SS_ANTIALIASING: return "SS_ANTIALIASING";
32 case FilterType::FILTER_SS_REFLECTIONS: return "SS_REFLECTIONS";
33 case FilterType::FILTER_SS_AMBIENT_OCCLUSION: return "SS_AMBIENT_OCCLUSION";
34 case FilterType::FILTER_DEPTH_OF_FIELD: return "DEPTH_OF_FIELD";
35 case FilterType::FILTER_MOTION_BLUR: return "MOTION_BLUR";
36 case FilterType::FILTER_BLOOM: return "BLOOM";
37 case FilterType::FILTER_LUT_CORECTION: return "LUT_CORRECTION";
38 case FilterType::FILTER_UNDERWATER: return "UNDERWATER";
39 case FilterType::FILTER_NOISE: return "NOISE";
40 case FilterType::FILTER_VIGNETTE: return "VIGNETTE";
41 default: break;
42 }
43
44 return "Unknown";
45 };
46
48 : PlatformContextComponent( context )
49 , _preRenderBatch( context.gfx(), *this )
50 {
51 std::atomic_uint loadTasks = 0u;
52
53 context.paramHandler().setParam<bool>( _ID( "postProcessing.enableVignette" ), false );
54
55 std::ranges::fill(_postFXTarget._drawMask, false);
57
58 Console::printfn( LOCALE_STR( "START_POST_FX" ) );
59
60 _uniformData.set( _ID( "_noiseTile" ), PushConstantType::FLOAT, 0.1f );
61 _uniformData.set( _ID( "_noiseFactor" ), PushConstantType::FLOAT, 0.02f );
62 _uniformData.set( _ID( "_fadeActive" ), PushConstantType::BOOL, false );
63 _uniformData.set( _ID( "_zPlanes" ), PushConstantType::VEC2, vec2<F32>( 0.01f, 500.0f ) );
64
65 TextureDescriptor texDescriptor{};
66 texDescriptor._textureOptions._isNormalMap = true;
67 texDescriptor._textureOptions._useDDSCache = true;
68 texDescriptor._textureOptions._outputSRGB = false;
69 texDescriptor._textureOptions._alphaChannelTransparency = false;
70
71 ResourceDescriptor<Texture> textureWaterCaustics( "Underwater Normal Map", texDescriptor );
72 textureWaterCaustics.assetName( "terrain_water_NM.jpg" );
73 textureWaterCaustics.assetLocation( Paths::g_imagesLocation );
74 textureWaterCaustics.waitForReady( false );
75 _underwaterTexture = CreateResource( textureWaterCaustics, loadTasks );
76
77 texDescriptor._textureOptions._isNormalMap = false;
78 ResourceDescriptor<Texture> noiseTexture( "noiseTexture", texDescriptor );
79 noiseTexture.assetName( "bruit_gaussien.jpg" );
80 noiseTexture.assetLocation( Paths::g_imagesLocation );
81 noiseTexture.waitForReady( false );
82 _noise = CreateResource( noiseTexture, loadTasks );
83
84 ResourceDescriptor<Texture> borderTexture( "borderTexture", texDescriptor );
85 borderTexture.assetName( "vignette.jpeg" );
86 borderTexture.assetLocation( Paths::g_imagesLocation );
87 borderTexture.waitForReady( false );
88 _screenBorder = CreateResource( borderTexture, loadTasks );
89
90 _noiseTimer = 0.0;
91 _tickInterval = 1.0f / 24.0f;
94
95 ShaderModuleDescriptor vertModule = {};
97 vertModule._sourceFile = "baseVertexShaders.glsl";
98 vertModule._variant = "FullScreenQuad";
99
100 ShaderModuleDescriptor fragModule = {};
102 fragModule._sourceFile = "postProcessing.glsl";
103
104 ResourceDescriptor<ShaderProgram> postFXShader( "postProcessing" );
105 ShaderProgramDescriptor& postFXShaderDescriptor = postFXShader._propertyDescriptor;
106 postFXShaderDescriptor._modules.push_back( vertModule );
107 postFXShaderDescriptor._modules.push_back( fragModule );
108 _postProcessingShader = CreateResource( postFXShader, loadTasks );
109
110 PipelineDescriptor pipelineDescriptor;
111 pipelineDescriptor._stateBlock = context.gfx().get2DStateBlock();
112 pipelineDescriptor._shaderProgramHandle = _postProcessingShader;
114
115 _drawPipeline = context.gfx().newPipeline( pipelineDescriptor );
116 WAIT_FOR_CONDITION( loadTasks.load() == 0 );
117 }
118
120 {
121 // Destroy our post processing system
122 Console::printfn( LOCALE_STR( "STOP_POST_FX" ) );
127 }
128
129 void PostFX::updateResolution( const U16 newWidth, const U16 newHeight )
130 {
131 if ( (_resolutionCache.width == newWidth && _resolutionCache.height == newHeight) ||
132 newWidth < 1 || newHeight < 1 )
133 {
134 return;
135 }
136
137 _resolutionCache.set( newWidth, newHeight );
138
139 _preRenderBatch.reshape( newWidth, newHeight );
141 }
142
143 void PostFX::prePass( const PlayerIndex idx, const CameraSnapshot& cameraSnapshot, GFX::CommandBuffer& bufferInOut )
144 {
145 GFX::EnqueueCommand<GFX::BeginDebugScopeCommand>( bufferInOut )->_scopeName = "PostFX: PrePass";
146 GFX::EnqueueCommand<GFX::PushCameraCommand>( bufferInOut )->_cameraSnapshot = _setCameraCmd._cameraSnapshot;
147
148 _preRenderBatch.prePass( idx, cameraSnapshot, _filterStack | _overrideFilterStack, bufferInOut );
149
150 GFX::EnqueueCommand<GFX::PopCameraCommand>( bufferInOut );
151 GFX::EnqueueCommand<GFX::EndDebugScopeCommand>( bufferInOut );
152 }
153
154 void PostFX::apply( const PlayerIndex idx, const CameraSnapshot& cameraSnapshot, GFX::CommandBuffer& bufferInOut )
155 {
156 GFX::EnqueueCommand<GFX::BeginDebugScopeCommand>( bufferInOut )->_scopeName = "PostFX: Apply";
157 GFX::EnqueueCommand( bufferInOut, _setCameraCmd );
158
159 _preRenderBatch.execute( idx, cameraSnapshot, _filterStack | _overrideFilterStack, bufferInOut );
160
161 GFX::BeginRenderPassCommand beginRenderPassCmd{};
162 beginRenderPassCmd._target = RenderTargetNames::SCREEN;
163 beginRenderPassCmd._descriptor = _postFXTarget;
164 beginRenderPassCmd._name = "DO_POSTFX_PASS";
165 beginRenderPassCmd._clearDescriptor[to_base( RTColourAttachmentSlot::SLOT_0 )] = { VECTOR4_ZERO, true };
166 GFX::EnqueueCommand( bufferInOut, beginRenderPassCmd );
167 GFX::EnqueueCommand<GFX::BindPipelineCommand>( bufferInOut )->_pipeline = _drawPipeline;
168
169 if ( _filtersDirty )
170 {
175 _filtersDirty = false;
176 };
177
178 _uniformData.set( _ID( "_zPlanes" ), PushConstantType::VEC2, cameraSnapshot._zPlanes );
179 _uniformData.set( _ID( "_invProjectionMatrix" ), PushConstantType::VEC2, cameraSnapshot._invProjectionMatrix );
180
181 GFX::EnqueueCommand<GFX::SendPushConstantsCommand>( bufferInOut )->_uniformData = &_uniformData;
182 const auto& rtPool = context().gfx().renderTargetPool();
183 const auto& prbAtt = _preRenderBatch.getOutput( false )._rt->getAttachment( RTAttachmentType::COLOUR );
185 const auto& ssrDataAtt = rtPool.getRenderTarget( RenderTargetNames::SSR_RESULT )->getAttachment( RTAttachmentType::COLOUR );
186 const auto& velocityAtt = rtPool.getRenderTarget( RenderTargetNames::SCREEN )->getAttachment( RTAttachmentType::COLOUR, GFXDevice::ScreenTargets::VELOCITY );
187
188 const SamplerDescriptor defaultSampler =
189 {
191 ._wrapV = TextureWrap::REPEAT,
192 ._wrapW = TextureWrap::REPEAT
193 };
194
195 auto cmd = GFX::EnqueueCommand<GFX::BindShaderResourcesCommand>( bufferInOut );
196 cmd->_usage = DescriptorSetUsage::PER_DRAW;
197 {
199 Set( binding._data, velocityAtt->texture(), defaultSampler );
200 }
201 {
203 Set( binding._data, ssrDataAtt->texture(), defaultSampler );
204 }
205 {
207 Set( binding._data, linDepthDataAtt->texture(), defaultSampler );
208 }
209 {
211 Set( binding._data, _underwaterTexture, defaultSampler );
212 }
213 {
215 Set( binding._data, _noise, defaultSampler );
216 }
217 {
219 Set( binding._data, _screenBorder, defaultSampler );
220 }
221 {
223 Set( binding._data, prbAtt->texture(), prbAtt->_descriptor._sampler );
224 }
225 GFX::EnqueueCommand<GFX::DrawCommand>( bufferInOut )->_drawCommands.emplace_back();
226
228
229 GFX::EnqueueCommand<GFX::EndDebugScopeCommand>( bufferInOut );
230 }
231
232 void PostFX::idle( [[maybe_unused]] const Configuration& config, [[maybe_unused]] const U64 deltaTimeUSGame )
233 {
235
236 // Update states
238 {
239 _noiseTimer += Time::MicrosecondsToMilliseconds<D64>( deltaTimeUSGame );
241 {
242 _noiseTimer = 0.0;
243 _randomNoiseCoefficient = Random( 1000 ) * 0.001f;
244 _randomFlashCoefficient = Random( 1000 ) * 0.001f;
245 }
246
249 }
250 }
251
252 void PostFX::update( [[maybe_unused]] const U64 deltaTimeUSFixed, const U64 deltaTimeUSApp )
253 {
255
256 if ( _fadeActive )
257 {
258 _currentFadeTimeMS += Time::MicrosecondsToMilliseconds<D64>( deltaTimeUSApp );
259 F32 fadeStrength = to_F32( std::min( _currentFadeTimeMS / _targetFadeTimeMS, 1.0 ) );
260 if ( !_fadeOut )
261 {
262 fadeStrength = 1.0f - fadeStrength;
263 }
264
265 if ( fadeStrength > 0.99 )
266 {
268 {
269 if ( _fadeOutComplete )
270 {
273 }
274 }
275 else
276 {
277 _fadeWaitDurationMS -= Time::MicrosecondsToMilliseconds<D64>( deltaTimeUSApp );
278 }
279 }
280
281 _uniformData.set( _ID( "_fadeStrength" ), PushConstantType::FLOAT, fadeStrength );
282
283 _fadeActive = fadeStrength > EPSILON_D64;
284 if ( !_fadeActive )
285 {
286 _uniformData.set( _ID( "_fadeActive" ), PushConstantType::BOOL, false );
287 if ( _fadeInComplete )
288 {
291 }
292 }
293 }
294
295 _preRenderBatch.update( deltaTimeUSApp );
296 }
297
298 void PostFX::setFadeOut( const UColour3& targetColour, const D64 durationMS, const D64 waitDurationMS, DELEGATE<void> onComplete )
299 {
300 _uniformData.set( _ID( "_fadeColour" ), PushConstantType::VEC4, Util::ToFloatColour( targetColour ) );
301 _uniformData.set( _ID( "_fadeActive" ), PushConstantType::BOOL, true );
302 _targetFadeTimeMS = durationMS;
303 _currentFadeTimeMS = 0.0;
304 _fadeWaitDurationMS = waitDurationMS;
305 _fadeOut = true;
306 _fadeActive = true;
307 _fadeOutComplete = MOV( onComplete );
308 }
309
310 // clear any fading effect currently active over the specified time interval
311 // set durationMS to instantly clear the fade effect
312 void PostFX::setFadeIn( const D64 durationMS, DELEGATE<void> onComplete )
313 {
314 _targetFadeTimeMS = durationMS;
315 _currentFadeTimeMS = 0.0;
316 _fadeOut = false;
317 _fadeActive = true;
318 _uniformData.set( _ID( "_fadeActive" ), PushConstantType::BOOL, true );
319 _fadeInComplete = MOV( onComplete );
320 }
321
322 void PostFX::setFadeOutIn( const UColour3& targetColour, const D64 durationFadeOutMS, const D64 waitDurationMS )
323 {
324 if ( waitDurationMS > 0.0 )
325 {
326 setFadeOutIn( targetColour, waitDurationMS * 0.5, waitDurationMS * 0.5, durationFadeOutMS );
327 }
328 }
329
330 void PostFX::setFadeOutIn( const UColour3& targetColour, const D64 durationFadeOutMS, const D64 durationFadeInMS, const D64 waitDurationMS )
331 {
332 setFadeOut( targetColour, durationFadeOutMS, waitDurationMS, [this, durationFadeInMS]()
333 {
334 setFadeIn( durationFadeInMS );
335 } );
336 }
337
338};
#define WAIT_FOR_CONDITION(...)
#define LOCALE_STR(X)
Definition: Localization.h:91
#define MOV(...)
#define PROFILE_SCOPE_AUTO(CATEGORY)
Definition: Profiler.h:87
static Camera * GetUtilityCamera(const UtilityCamera type)
Definition: Camera.cpp:120
const CameraSnapshot & snapshot() const noexcept
Returns the internal camera snapshot data (eye, orientation, etc)
Definition: Camera.inl:43
GFXRTPool & renderTargetPool() noexcept
Definition: GFXDevice.inl:133
Pipeline * newPipeline(const PipelineDescriptor &descriptor)
Create and return a new graphics pipeline. This is only used for caching and doesn't use the object a...
Definition: GFXDevice.cpp:3074
const RenderStateBlock & get2DStateBlock() const noexcept
Definition: GFXDevice.inl:123
void setParam(HashType nameID, T &&value)
PlatformContext & context() noexcept
ParamHandler & paramHandler() noexcept
GFXDevice & gfx() noexcept
void setFadeOutIn(const UColour3 &targetColour, D64 durationFadeOutMS, D64 waitDurationMS)
Definition: PostFX.cpp:322
D64 _fadeWaitDurationMS
Definition: PostFX.h:161
F32 _randomNoiseCoefficient
Definition: PostFX.h:150
GFX::SetCameraCommand _setCameraCmd
Definition: PostFX.h:174
void update(U64 deltaTimeUSFixed, U64 deltaTimeUSApp)
Definition: PostFX.cpp:252
D64 _noiseTimer
Definition: PostFX.h:151
bool getFilterState(const FilterType filter) const noexcept
Definition: PostFX.h:111
vec2< U16 > _resolutionCache
Definition: PostFX.h:154
void idle(const Configuration &config, U64 deltaTimeUSGame)
Definition: PostFX.cpp:232
void setFadeOut(const UColour3 &targetColour, D64 durationMS, D64 waitDurationMS, DELEGATE< void > onComplete=DELEGATE< void >())
Definition: PostFX.cpp:298
DELEGATE< void > _fadeOutComplete
Definition: PostFX.h:164
U32 _overrideFilterStack
Definition: PostFX.h:168
~PostFX() override
Definition: PostFX.cpp:119
void prePass(PlayerIndex idx, const CameraSnapshot &cameraSnapshot, GFX::CommandBuffer &bufferInOut)
Definition: PostFX.cpp:143
void setFadeIn(D64 durationMS, DELEGATE< void > onComplete=DELEGATE< void >())
Definition: PostFX.cpp:312
PreRenderBatch _preRenderBatch
Definition: PostFX.h:144
D64 _targetFadeTimeMS
Definition: PostFX.h:160
Handle< Texture > _screenBorder
Definition: PostFX.h:146
U32 _filterStack
Definition: PostFX.h:167
D64 _tickInterval
Definition: PostFX.h:151
bool _fadeOut
Definition: PostFX.h:162
bool _fadeActive
Definition: PostFX.h:163
Pipeline * _drawPipeline
Definition: PostFX.h:172
D64 _currentFadeTimeMS
Definition: PostFX.h:159
UniformData _uniformData
Definition: PostFX.h:173
void apply(PlayerIndex idx, const CameraSnapshot &cameraSnapshot, GFX::CommandBuffer &bufferInOut)
Definition: PostFX.cpp:154
F32 _randomFlashCoefficient
Definition: PostFX.h:150
Handle< Texture > _underwaterTexture
Definition: PostFX.h:148
PostFX(PlatformContext &context)
Definition: PostFX.cpp:47
Handle< ShaderProgram > _postProcessingShader
Definition: PostFX.h:153
Handle< Texture > _noise
Definition: PostFX.h:147
RTDrawDescriptor _postFXTarget
Definition: PostFX.h:156
static const char * FilterName(FilterType filter) noexcept
Definition: PostFX.cpp:27
DELEGATE< void > _fadeInComplete
Definition: PostFX.h:165
bool _filtersDirty
Definition: PostFX.h:170
void updateResolution(U16 newWidth, U16 newHeight)
Definition: PostFX.cpp:129
void execute(PlayerIndex idx, const CameraSnapshot &cameraSnapshot, U32 filterStack, GFX::CommandBuffer &bufferInOut)
void prePass(PlayerIndex idx, const CameraSnapshot &cameraSnapshot, U32 filterStack, GFX::CommandBuffer &bufferInOut)
void update(U64 deltaTimeUS) noexcept
RenderTargetHandle getLinearDepthRT() const noexcept
RenderTargetHandle getOutput(bool hdr) const
void reshape(U16 width, U16 height)
RTAttachment * getAttachment(RTAttachmentType type, RTColourAttachmentSlot slot=RTColourAttachmentSlot::SLOT_0) const
void set(const T *v) noexcept
set the 2 components of the vector manually using a source pointer to a (large enough) array
Definition: MathVectors.h:335
FORCE_INLINE T * EnqueueCommand(CommandBuffer &buffer)
constexpr Optick::Category::Type GameLogic
Definition: Profiler.h:63
constexpr Optick::Category::Type Graphics
Definition: Profiler.h:60
FColour4 ToFloatColour(const UColour4 &byteColour) noexcept
Definition: MathHelper.cpp:268
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
DELEGATE_STD< Ret, Args... > DELEGATE
FORCE_INLINE void DestroyResource(Handle< T > &handle, const bool immediate=false)
constexpr D64 EPSILON_D64
constexpr F32 to_F32(const T value)
T Random()
Definition: MathHelper.inl:95
uint16_t U16
void Set(DescriptorSetBindingData &dataInOut, ShaderBuffer *buffer, const BufferRange range) noexcept
constexpr U64 _ID(const char *const str, const U64 value=val_64_const) noexcept
DescriptorSetBinding & AddBinding(DescriptorSet &setInOut, U8 slot, U16 stageVisibilityMask)
FORCE_INLINE Handle< T > CreateResource(const ResourceDescriptor< T > &descriptor, bool &wasInCache, std::atomic_uint &taskCounter)
double D64
static const vec4< F32 > VECTOR4_ZERO
Definition: MathVectors.h:1435
uint64_t U64
constexpr auto to_base(const Type value) -> Type
mat4< F32 > _invProjectionMatrix
static NO_INLINE void printfn(const char *format, T &&... args)
DescriptorSetBindingData _data
CameraSnapshot _cameraSnapshot
Definition: Commands.inl:155
static constexpr RTColourAttachmentSlot ALBEDO
Definition: GFXDevice.h:228
static constexpr RTColourAttachmentSlot VELOCITY
Definition: GFXDevice.h:229
PrimitiveTopology _primitiveTopology
Definition: Pipeline.h:48
Handle< ShaderProgram > _shaderProgramHandle
Definition: Pipeline.h:47
RenderStateBlock _stateBlock
Definition: Pipeline.h:46
vector< ShaderModuleDescriptor > _modules
ImageTools::ImportOptions _textureOptions
static RenderTargetID SCREEN
Definition: GFXDevice.h:197
static RenderTargetID SSR_RESULT
Definition: GFXDevice.h:203
PropertyDescriptor< T > _propertyDescriptor
Definition: Resource.h:151
TextureWrap _wrapU
Texture wrap mode (Or S-R-T)
void set(U64 bindingHash, PushConstantType type, const T &value)