Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
ShadowMap.cpp
Go to the documentation of this file.
1
2
3#include "Headers/ShadowMap.h"
7
12
14
18
24
26
27namespace Divide
28{
31 vector<std::unique_ptr<ShadowMapGenerator>> ShadowMap::s_shadowMapGenerators;
32
33 vector<DebugView_ptr> ShadowMap::s_debugViews;
34 std::array<RenderTargetHandle, to_base( ShadowType::COUNT )> ShadowMap::s_shadowMaps;
35 std::array<RenderTargetHandle, to_base( ShadowType::COUNT )> ShadowMap::s_shadowMapCaches;
36 Light* ShadowMap::s_shadowPreviewLight = nullptr;
37
40
42 : _context( context ),
43 _type( type )
44 {
45 }
46
48 {
49 switch ( type )
50 {
54 case LightType::COUNT: break;
55 }
56
57 return ShadowType::COUNT;
58 }
59
61 {
62 switch ( type )
63 {
67 case ShadowType::COUNT: break;
68 }
69
70 return LightType::COUNT;
71 }
72
74 {
75 for ( U8 t = 0; t < to_base( ShadowType::COUNT ); ++t )
76 {
77 const ShadowType type = static_cast<ShadowType>(t);
78 const U8 cameraCount = type == ShadowType::SINGLE ? 1 : type == ShadowType::CUBEMAP ? 6 : Config::Lighting::MAX_CSM_SPLITS_PER_LIGHT;
79
80 for ( U32 i = 0; i < cameraCount; ++i )
81 {
82 s_shadowCameras[t].emplace_back( Camera::CreateCamera( Util::StringFormat( "ShadowCamera_{}_{}", Names::shadowType[t], i ).c_str(), Camera::Mode::STATIC));
83 }
84 }
85
87
88 if ( !isPowerOfTwo( settings.csm.shadowMapResolution ) )
89 {
91 }
92 if ( !isPowerOfTwo( settings.spot.shadowMapResolution ) )
93 {
95 }
96 if ( !isPowerOfTwo( settings.point.shadowMapResolution ) )
97 {
99 }
100
101 SamplerDescriptor shadowMapSampler = {};
102 shadowMapSampler._wrapU = TextureWrap::CLAMP_TO_EDGE;
103 shadowMapSampler._wrapV = TextureWrap::CLAMP_TO_EDGE;
104 shadowMapSampler._wrapW = TextureWrap::CLAMP_TO_EDGE;
105
106 SamplerDescriptor shadowMapSamplerCache = {};
107 shadowMapSamplerCache._wrapU = TextureWrap::CLAMP_TO_EDGE;
108 shadowMapSamplerCache._wrapV = TextureWrap::CLAMP_TO_EDGE;
109 shadowMapSamplerCache._wrapW = TextureWrap::CLAMP_TO_EDGE;
110 shadowMapSamplerCache._magFilter = TextureFilter::LINEAR;
111 shadowMapSamplerCache._minFilter = TextureFilter::LINEAR;
112 shadowMapSamplerCache._mipSampling = TextureMipSampling::NONE;
113 shadowMapSamplerCache._anisotropyLevel = 0u;
114
115 s_shadowMapGenerators.resize(0u);
116
117 for ( U8 i = 0; i < to_U8( ShadowType::COUNT ); ++i )
118 {
119 switch ( static_cast<ShadowType>(i) )
120 {
121 case ShadowType::CSM:
123 {
124 const bool isCSM = i == to_U8( ShadowType::CSM );
125 if ( isCSM && !settings.csm.enabled )
126 {
127 continue;
128 }
129 if ( !isCSM && !settings.spot.enabled )
130 {
131 continue;
132 }
133
134 shadowMapSampler._anisotropyLevel = isCSM ? settings.csm.maxAnisotropicFilteringLevel : settings.spot.maxAnisotropicFilteringLevel;
135
136 // Default filters, LINEAR is OK for this
137 TextureDescriptor shadowMapDescriptor{};
138 shadowMapDescriptor._dataType = isCSM ? GFXDataFormat::FLOAT_32 : GFXDataFormat::FLOAT_16;
139 shadowMapDescriptor._texType = TextureType::TEXTURE_2D_ARRAY;
140 shadowMapDescriptor._baseFormat = GFXImageFormat::RG;
141 shadowMapDescriptor._packing = GFXImagePacking::UNNORMALIZED;
142 shadowMapDescriptor._mipMappingState = MipMappingState::MANUAL;
143 shadowMapDescriptor._layerCount = isCSM ? (Config::Lighting::MAX_SHADOW_CASTING_DIRECTIONAL_LIGHTS * Config::Lighting::MAX_CSM_SPLITS_PER_LIGHT) + 1u /* world AO*/
145
146 RenderTargetDescriptor desc = {};
147 desc._resolution.set( to_U16( isCSM ? settings.csm.shadowMapResolution : settings.spot.shadowMapResolution ) );
148 {
149 desc._attachments =
150 {
152 };
153
154 desc._name = isCSM ? "CSM_ShadowMap" : "Single_ShadowMap";
155 s_shadowMaps[i] = context.renderTargetPool().allocateRT( desc );
156 }
157 {
158 TextureDescriptor shadowMapCacheDescriptor = shadowMapDescriptor;
159 shadowMapCacheDescriptor._mipMappingState = MipMappingState::OFF;
160
161 desc._attachments =
162 {
163 InternalRTAttachmentDescriptor{ shadowMapCacheDescriptor, shadowMapSamplerCache, RTAttachmentType::COLOUR, RTColourAttachmentSlot::SLOT_0 }
164 };
165
166 desc._name = isCSM ? "CSM_ShadowMap_StaticCache" : "Single_ShadowMap_StaticCache";
167 s_shadowMapCaches[i] = context.renderTargetPool().allocateRT( desc );
168 }
169 if ( isCSM )
170 {
171 s_shadowMapGenerators.emplace_back(std::make_unique<CascadedShadowMapsGenerator>( context ) );
172 }
173 else
174 {
175 s_shadowMapGenerators.emplace_back(std::make_unique<SingleShadowMapGenerator>( context ));
176 }
177
178 s_shadowMapLifetime[i].resize( shadowMapDescriptor._layerCount );
179 } break;
181 {
182 if ( !settings.point.enabled )
183 {
184 continue;
185 }
186
187 TextureDescriptor colourMapDescriptor{};
188 colourMapDescriptor._texType = TextureType::TEXTURE_CUBE_ARRAY;
189 colourMapDescriptor._dataType = GFXDataFormat::FLOAT_16;
190 colourMapDescriptor._baseFormat = GFXImageFormat::RG;
191 colourMapDescriptor._packing = GFXImagePacking::UNNORMALIZED;
192 colourMapDescriptor._layerCount = Config::Lighting::MAX_SHADOW_CASTING_POINT_LIGHTS;
193 colourMapDescriptor._mipMappingState = MipMappingState::MANUAL;
194 shadowMapSampler._mipSampling = TextureMipSampling::NONE;
195 shadowMapSampler._anisotropyLevel = 0u;
196
197 TextureDescriptor depthDescriptor{};
199 depthDescriptor._dataType = GFXDataFormat::UNSIGNED_INT;
200 depthDescriptor._baseFormat = GFXImageFormat::RED;
201 depthDescriptor._packing = GFXImagePacking::DEPTH;
202 depthDescriptor._layerCount = colourMapDescriptor._layerCount;
203 depthDescriptor._mipMappingState = MipMappingState::MANUAL;
204
205 RenderTargetDescriptor desc = {};
206
207 desc._resolution.set( to_U16( settings.point.shadowMapResolution ) );
208 {
209 desc._name = "Cube_ShadowMap";
210 desc._attachments =
211 {
214 };
215 s_shadowMaps[i] = context.renderTargetPool().allocateRT( desc );
216 }
217 {
218 TextureDescriptor shadowMapCacheDescriptor = colourMapDescriptor;
219 shadowMapCacheDescriptor._mipMappingState = MipMappingState::OFF;
220
221 desc._attachments =
222 {
223 InternalRTAttachmentDescriptor{ shadowMapCacheDescriptor, shadowMapSamplerCache, RTAttachmentType::COLOUR, RTColourAttachmentSlot::SLOT_0 },
225 };
226
227 desc._name = "Cube_ShadowMap_StaticCache";
228 s_shadowMapCaches[i] = context.renderTargetPool().allocateRT( desc );
229 }
230
231 s_shadowMapGenerators.emplace_back(std::make_unique<CubeShadowMapGenerator>( context ));
232 s_shadowMapLifetime[i].resize( colourMapDescriptor._layerCount );
233 } break;
234 case ShadowType::COUNT: break;
235 }
236 }
237 }
238
240 {
241 for ( U8 t = 0u; t < to_base( ShadowType::COUNT ); ++t )
242 {
243 for ( auto& camera : s_shadowCameras[t] )
244 {
245 Camera::DestroyCamera( camera );
246 }
247 s_shadowCameras[t].clear();
248 }
249
250 s_debugViews.clear();
251
252 for ( RenderTargetHandle& handle : s_shadowMaps )
253 {
254 if ( !context.renderTargetPool().deallocateRT( handle ) )
255 {
257 }
258 handle._rt = nullptr;
259 }
260
261 for ( RenderTargetHandle& handle : s_shadowMapCaches )
262 {
263 if ( !context.renderTargetPool().deallocateRT( handle ) )
264 {
266 }
267 handle._rt = nullptr;
268 }
269
270 s_shadowMapGenerators.resize( 0 );
271 }
272
274 {
276 for (LayerLifetimeMask& lifetimeMask : s_shadowMapLifetime)
277 {
278 for ( auto& mast : lifetimeMask )
279 {
280 mast._lifetime = MAX_SHADOW_FRAME_LIFETIME;
281 mast._lightGUID = -1;
282 }
283 }
284 }
285
287 {
289 for ( U32 i = 0u; i < to_base( ShadowType::COUNT ); ++i )
290 {
291 s_shadowPassIndex[i] = 0u;
292 }
293 for ( LayerLifetimeMask& lifetimePerType : s_shadowMapLifetime )
294 {
295 for ( ShadowLayerData& lifetime : lifetimePerType )
296 {
297 if ( lifetime._lifetime < MAX_SHADOW_FRAME_LIFETIME )
298 {
299 ++lifetime._lifetime;
300 }
301 }
302 }
303 }
304
306 {
307 auto cmd = GFX::EnqueueCommand<GFX::BindShaderResourcesCommand>( bufferInOut );
308 cmd->_usage = DescriptorSetUsage::PER_FRAME;
309
310 for ( U8 i = 0u; i < to_base( ShadowType::COUNT ); ++i )
311 {
313 if ( sm._rt == nullptr )
314 {
315 continue;
316 }
317
318 const ShadowType shadowType = static_cast<ShadowType>(i);
319 const U8 bindSlot = LightPool::GetShadowBindSlotOffset( shadowType );
321 DescriptorSetBinding& binding = AddBinding( cmd->_set, bindSlot, ShaderStageVisibility::FRAGMENT );
322 Set( binding._data, shadowTexture->texture(), shadowTexture->_descriptor._sampler );
323 }
324
326 Set( binding._data, LightPool::ShadowBuffer(), { 0u, 1u } );
327 }
328
330 {
332 return freeShadowMapOffsetLocked( light );
333 }
334
336 {
337 const U16 layerOffset = light.getShadowArrayOffset();
338 if ( layerOffset == U16_MAX )
339 {
340 return true;
341 }
342
343 const U32 layerRequirement = getLightLayerRequirements( light );
344 const ShadowType sType = getShadowTypeForLightType( light.getLightType() );
345
346 LayerLifetimeMask& lifetimeMask = s_shadowMapLifetime[to_U32( sType )];
347 for ( U32 i = layerOffset; i < layerOffset + layerRequirement; ++i )
348 {
349 lifetimeMask[i]._lifetime = MAX_SHADOW_FRAME_LIFETIME;
350 lifetimeMask[i]._lightGUID = -1;
351 }
352
353 return true;
354 }
355
357 {
358 const U32 layerCount = getLightLayerRequirements( light );
359 if ( layerCount == 0u ) [[unlikely]]
360 {
361 return false;
362 }
363
364 const U16 crtArrayOffset = light.getShadowArrayOffset();
365
366 const ShadowType shadowType = getShadowTypeForLightType( light.getLightType() );
367
369 LayerLifetimeMask& lifetimeMask = s_shadowMapLifetime[to_U32( shadowType )];
370 if ( crtArrayOffset != U16_MAX ) [[likely]]
371 {
372 bool valid = true;
373 for ( U16 i = 0u; i < layerCount; ++i )
374 {
375 if ( lifetimeMask[crtArrayOffset + i]._lightGUID == light.getGUID() )
376 {
377 lifetimeMask[crtArrayOffset + i]._lifetime = 0u;
378 }
379 else
380 {
381 valid = false;
382 }
383
384 }
385 if ( valid ) [[likely]]
386 {
387 return true;
388 }
389 else
390 {
392 }
393 }
394
395 // Common case. Broken out for ease of debugging
396 if ( layerCount == 1u )
397 {
398 for ( U16 i = 0u; i < lifetimeMask.size(); ++i )
399 {
400 if ( lifetimeMask[i]._lifetime >= MAX_SHADOW_FRAME_LIFETIME )
401 {
402 lifetimeMask[i]._lifetime = 0u;
403 lifetimeMask[i]._lightGUID = light.getGUID();
404 light.setShadowArrayOffset( i );
405 return true;
406 }
407 }
408 }
409 else
410 {
411 // Really only happens for directional lights due to the way CSM is laid out
412 const U16 availableLayers = to_U16( lifetimeMask.size() );
413 bool found = false;
414 for ( U16 i = 0u; i < availableLayers - layerCount; ++i )
415 {
416 for ( U16 j = i; j < i + layerCount; ++j )
417 {
418 if ( lifetimeMask[j]._lifetime < MAX_SHADOW_FRAME_LIFETIME )
419 {
420 found = false;
421 break;
422 }
423
424 found = true;
425 }
426 if ( found )
427 {
428 for ( U16 j = i; j < i + layerCount; ++j )
429 {
430 lifetimeMask[j]._lifetime = 0u;
431 lifetimeMask[j]._lightGUID = light.getGUID();
432 }
433 light.setShadowArrayOffset( i );
434 return true;
435 }
436 }
437 }
438
439 return false;
440 }
441
443 {
444 switch ( light.getLightType() )
445 {
446 case LightType::DIRECTIONAL: return to_U32( static_cast<const DirectionalLightComponent&>(light).csmSplitCount() );
447 case LightType::SPOT:
448 case LightType::POINT: return 1u;
449 case LightType::COUNT: break;
450 }
451
452 return 0u;
453 }
454
456 {
457 if ( !commitLayerRange( light ) )
458 {
459 // If we don't have enough resources available, something went terribly wrong as we limit shadow casting lights per-type
460 // and allocate enough slices for the worst case -Ionut
462 return false;
463 }
464
465 return true;
466 }
467
468 bool ShadowMap::generateShadowMaps( const Camera& playerCamera, Light& light, GFX::CommandBuffer& bufferInOut, GFX::MemoryBarrierCommand& memCmdInOut )
469 {
471
472 const U8 shadowTypeIdx = to_base( getShadowTypeForLightType( light.getLightType() ) );
473 if ( s_shadowMapGenerators[shadowTypeIdx] == nullptr ) [[unlikely]]
474 {
475 // If we don't have enough resources available, something went terribly wrong as we limit shadow casting lights per-type
476 // and allocate enough slices for the worst case -Ionut
478 return false;
479 }
480
481 if ( markShadowMapsUsed( light ) ) [[likely]]
482 {
483 s_shadowMapGenerators[shadowTypeIdx]->render( playerCamera, light, s_shadowPassIndex[shadowTypeIdx]++, bufferInOut, memCmdInOut );
484 return true;
485 }
486
487 return false;
488 }
489
490 void ShadowMap::generateWorldAO( const Camera& playerCamera, GFX::CommandBuffer& bufferInOut,GFX::MemoryBarrierCommand& memCmdInOut )
491 {
492 static_cast<CascadedShadowMapsGenerator*>(s_shadowMapGenerators[to_base( ShadowType::CSM )].get())->generateWorldAO( playerCamera , bufferInOut, memCmdInOut );
493 }
494
496 {
497 return getShadowMap( getShadowTypeForLightType( type ) );
498 }
499
501 {
503 }
505 {
506 return s_shadowMaps[to_base( type )];
507 }
508
510 {
511 return s_shadowMapCaches[to_base( type )];
512 }
513
514 void ShadowMap::setMSAASampleCount( const ShadowType type, const U8 sampleCount )
515 {
516 if ( s_shadowMapGenerators[to_base( type )] != nullptr )
517 {
518 s_shadowMapGenerators[to_base( type )]->updateMSAASampleCount( sampleCount );
519 }
520 }
521
523 {
524 if ( light == s_shadowPreviewLight )
525 {
526 return;
527 }
528
529 // Remove old views
530 if ( !s_debugViews.empty() )
531 {
532 for ( const DebugView_ptr& view : s_debugViews )
533 {
534 context.removeDebugView( view.get() );
535 }
536 s_debugViews.clear();
537 }
538
539 s_shadowPreviewLight = light;
540
541 // Add new views if needed
542 if ( light != nullptr && light->castsShadows() )
543 {
544 ShaderModuleDescriptor vertModule = {};
545 vertModule._moduleType = ShaderType::VERTEX;
546 vertModule._sourceFile = "baseVertexShaders.glsl";
547 vertModule._variant = "FullScreenQuad";
548
549 ShaderModuleDescriptor fragModule = {};
551 fragModule._sourceFile = "fbPreview.glsl";
552
553 switch ( light->getLightType() )
554 {
556 {
557
558 fragModule._variant = "Layered.LinearDepth";
559
560 ShaderProgramDescriptor shaderDescriptor = {};
561 shaderDescriptor._modules.push_back( vertModule );
562 shaderDescriptor._modules.push_back( fragModule );
563
564 ResourceDescriptor<ShaderProgram> shadowPreviewShader( "fbPreview.Layered.LinearDepth", shaderDescriptor );
565 shadowPreviewShader.waitForReady( true );
566 Handle<ShaderProgram> previewShader = CreateResource( shadowPreviewShader );
567 const U8 splitCount = static_cast<DirectionalLightComponent&>(*light).csmSplitCount();
568
569 constexpr I16 Base = 2;
570 for ( U8 i = 0; i < splitCount; ++i )
571 {
572 DebugView_ptr shadow = std::make_shared<DebugView>( to_I16( I16_MAX - 1 - splitCount + i ) );
575 shadow->_shader = previewShader;
576 shadow->_shaderData.set( _ID( "layer" ), PushConstantType::INT, i + light->getShadowArrayOffset() );
577 shadow->_groupID = Base + to_I16( light->shadowPropertyIndex() );
578 shadow->_enabled = true;
579 Util::StringFormat( shadow->_name, "CSM_{}", i + light->getShadowArrayOffset() );
580 s_debugViews.push_back( shadow );
581 }
582 } break;
583 case LightType::SPOT:
584 {
585 constexpr I16 Base = 22;
586 fragModule._variant = "Layered.LinearDepth";
587
588 ShaderProgramDescriptor shaderDescriptor = {};
589 shaderDescriptor._modules.push_back( vertModule );
590 shaderDescriptor._modules.push_back( fragModule );
591
592 ResourceDescriptor<ShaderProgram> shadowPreviewShader( "fbPreview.Layered.LinearDepth", shaderDescriptor );
593 shadowPreviewShader.waitForReady( true );
594
595 DebugView_ptr shadow = std::make_shared<DebugView>( to_I16( I16_MAX - 1 ) );
598 shadow->_shader = CreateResource( shadowPreviewShader );
599 shadow->_shaderData.set( _ID( "layer" ), PushConstantType::INT, light->getShadowArrayOffset() );
600 shadow->_enabled = true;
601 shadow->_groupID = Base + to_I16( light->shadowPropertyIndex() );
602 Util::StringFormat( shadow->_name, "SM_{}", light->getShadowArrayOffset() );
603 s_debugViews.push_back( shadow );
604 }break;
605 case LightType::POINT:
606 {
607 constexpr I16 Base = 222;
608 fragModule._variant = "Cube.Shadow";
609
610 ShaderProgramDescriptor shaderDescriptor = {};
611 shaderDescriptor._modules.push_back( vertModule );
612 shaderDescriptor._modules.back()._defines.emplace_back( "SPLAT_R_CHANNEL" );
613 shaderDescriptor._modules.push_back( fragModule );
614
615 ResourceDescriptor<ShaderProgram> shadowPreviewShader( "fbPreview.Cube.Shadow", shaderDescriptor );
616 shadowPreviewShader.waitForReady( true );
617 Handle<ShaderProgram> previewShader = CreateResource( shadowPreviewShader );
618
619 for ( U8 i = 0u; i < 6u; ++i )
620 {
621 DebugView_ptr shadow = std::make_shared<DebugView>( to_I16( I16_MAX - 1 - 6 + i ) );
624 shadow->_shader = previewShader;
625 shadow->_shaderData.set( _ID( "layer" ), PushConstantType::INT, light->getShadowArrayOffset() );
626 shadow->_shaderData.set( _ID( "face" ), PushConstantType::INT, i );
627 shadow->_groupID = Base + to_I16( light->shadowPropertyIndex() );
628 shadow->_enabled = true;
629 Util::StringFormat( shadow->_name, "CubeSM_{}_face_{}", light->getShadowArrayOffset(), i );
630 s_debugViews.push_back( shadow );
631 }
632 } break;
633 case LightType::COUNT: break;
634 }
635
636 for ( const DebugView_ptr& view : s_debugViews )
637 {
638 context.addDebugView( view );
639 }
640 }
641 }
642} //namespace Divide
#define DIVIDE_UNEXPECTED_CALL()
#define PROFILE_SCOPE_AUTO(CATEGORY)
Definition: Profiler.h:87
static Camera * CreateCamera(const Str< 256 > &cameraName, Mode cameraMode)
Definition: Camera.cpp:147
static bool DestroyCamera(Camera *&camera)
Definition: Camera.cpp:175
Rough around the edges Adapter pattern abstracting the actual rendering API and access to the GPU.
Definition: GFXDevice.h:215
GFXRTPool & renderTargetPool() noexcept
Definition: GFXDevice.inl:133
bool removeDebugView(DebugView *view)
Definition: GFXDevice.cpp:2770
DebugView * addDebugView(const std::shared_ptr< DebugView > &view)
Definition: GFXDevice.cpp:2740
RenderTargetHandle allocateRT(const RenderTargetDescriptor &descriptor)
Definition: GFXRTPool.cpp:17
bool deallocateRT(RenderTargetHandle &handle)
Definition: GFXRTPool.cpp:33
FORCE_INLINE I64 getGUID() const noexcept
Definition: GUIDWrapper.h:51
A light object placed in the scene at a certain position.
Definition: Light.h:58
const LightType & getLightType() const noexcept
Get the light type. (see LightType enum)
Definition: Light.inl:46
void setShadowArrayOffset(const U16 offset) noexcept
Definition: Light.inl:64
U16 getShadowArrayOffset() const noexcept
Definition: Light.inl:79
static U8 GetShadowBindSlotOffset(const ShadowType type) noexcept
Get the appropriate shadow bind slot for every light's shadow.
Definition: LightPool.h:156
static ShaderBuffer * ShadowBuffer()
Definition: LightPool.h:193
PlatformContext & context() noexcept
Configuration & config() noexcept
Handle< Texture > texture() const
RTAttachmentDescriptor _descriptor
Definition: RTAttachment.h:128
RTAttachment * getAttachment(RTAttachmentType type, RTColourAttachmentSlot slot=RTColourAttachmentSlot::SLOT_0) const
ShadowMapGenerator(GFXDevice &context, ShadowType type) noexcept
Definition: ShadowMap.cpp:41
static void setDebugViewLight(GFXDevice &context, Light *light)
Definition: ShadowMap.cpp:522
static bool freeShadowMapOffset(const Light &light)
Definition: ShadowMap.cpp:329
static bool generateShadowMaps(const Camera &playerCamera, Light &light, GFX::CommandBuffer &bufferInOut, GFX::MemoryBarrierCommand &memCmdInOut)
Definition: ShadowMap.cpp:468
static Light * s_shadowPreviewLight
Definition: ShadowMap.h:144
static constexpr U8 MAX_SHADOW_FRAME_LIFETIME
Definition: ShadowMap.h:90
static std::array< RenderTargetHandle, to_base(ShadowType::COUNT)> s_shadowMapCaches
Definition: ShadowMap.h:141
static vector< DebugView_ptr > s_debugViews
Definition: ShadowMap.h:142
static void setMSAASampleCount(ShadowType type, U8 sampleCount)
Definition: ShadowMap.cpp:514
static std::array< RenderTargetHandle, to_base(ShadowType::COUNT)> s_shadowMaps
Definition: ShadowMap.h:140
static const RenderTargetHandle & getShadowMapCache(LightType type)
Definition: ShadowMap.cpp:500
static std::array< ShadowCameraPool, to_base(ShadowType::COUNT)> s_shadowCameras
Definition: ShadowMap.h:147
static vector< std::unique_ptr< ShadowMapGenerator > > s_shadowMapGenerators
Definition: ShadowMap.h:138
static ShadowType getShadowTypeForLightType(LightType type) noexcept
Definition: ShadowMap.cpp:47
static bool freeShadowMapOffsetLocked(const Light &light)
Definition: ShadowMap.cpp:335
static bool commitLayerRange(Light &light)
Definition: ShadowMap.cpp:356
static const RenderTargetHandle & getShadowMap(LightType type)
Definition: ShadowMap.cpp:495
static void reset()
Definition: ShadowMap.cpp:273
vector< Camera * > ShadowCameraPool
Definition: ShadowMap.h:145
vector< ShadowLayerData > LayerLifetimeMask
Definition: ShadowMap.h:135
static void initShadowMaps(GFXDevice &context)
Definition: ShadowMap.cpp:73
static void resetShadowMaps()
Definition: ShadowMap.cpp:286
static void destroyShadowMaps(GFXDevice &context)
Definition: ShadowMap.cpp:239
static void generateWorldAO(const Camera &playerCamera, GFX::CommandBuffer &bufferInOut, GFX::MemoryBarrierCommand &memCmdInOut)
Definition: ShadowMap.cpp:490
static Mutex s_shadowMapUsageLock
Definition: ShadowMap.h:136
static U32 getLightLayerRequirements(const Light &light)
Definition: ShadowMap.cpp:442
static bool markShadowMapsUsed(Light &light)
Definition: ShadowMap.cpp:455
static std::array< U16, to_base(ShadowType::COUNT)> s_shadowPassIndex
Definition: ShadowMap.h:146
static LightType getLightTypeForShadowType(ShadowType type) noexcept
Definition: ShadowMap.cpp:60
static void bindShadowMaps(GFX::CommandBuffer &bufferInOut)
Definition: ShadowMap.cpp:305
static std::array< LayerLifetimeMask, to_base(ShadowType::COUNT)> s_shadowMapLifetime
Definition: ShadowMap.h:137
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
constexpr U8 MAX_SHADOW_CASTING_POINT_LIGHTS
Definition: config.h:152
constexpr U8 MAX_SHADOW_CASTING_SPOT_LIGHTS
Definition: config.h:153
constexpr U8 MAX_CSM_SPLITS_PER_LIGHT
Used for CSM or PSSM to determine the maximum number of frustum splits.
Definition: config.h:159
constexpr U8 MAX_SHADOW_CASTING_DIRECTIONAL_LIGHTS
How many lights (in order as passed to the shader for the node) should cast shadows.
Definition: config.h:151
static const char * shadowType[]
Definition: ShadowMap.h:48
constexpr Optick::Category::Type Graphics
Definition: Profiler.h:60
Str StringFormat(const char *fmt, Args &&...args)
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
std::lock_guard< mutex > LockGuard
Definition: SharedMutex.h:55
constexpr U32 nextPOW2(U32 n) noexcept
Definition: MathHelper.inl:207
constexpr U32 to_U32(const T value)
std::mutex Mutex
Definition: SharedMutex.h:40
constexpr U16 to_U16(const T value)
uint8_t U8
int16_t I16
DirectionalLightComponent(SceneGraphNode *sgn, PlatformContext &context)
constexpr I16 I16_MAX
constexpr U16 U16_MAX
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)
constexpr bool isPowerOfTwo(const T x) noexcept
LightType
The different types of lights supported.
constexpr U8 to_U8(const T value)
constexpr I16 to_I16(const T value)
ShadowType
Definition: ShadowMap.h:40
uint32_t U32
constexpr auto to_base(const Type value) -> Type
Divide::Configuration::Rendering::ShadowMapping::CSMSettings csm
struct Divide::Configuration::Rendering::ShadowMapping shadowMapping
struct Divide::Configuration::Rendering rendering
DescriptorSetBindingData _data
vector< ShaderModuleDescriptor > _modules
SamplerDescriptor _sampler
Definition: RTAttachment.h:64
InternalRTAttachmentDescriptors _attachments
Definition: RenderTarget.h:52
TextureFilter _minFilter
Texture filtering mode.
TextureWrap _wrapU
Texture wrap mode (Or S-R-T)
U8 _anisotropyLevel
The value must be in the range [0...255] and is automatically clamped by the max HW supported level.
TextureMipSampling _mipSampling