51 I8 frustumPlaneCache = -1;
64 bufferDescriptor.
_name =
"LIGHT_DATA";
73 bufferDescriptor.
_name =
"LIGHT_SHADOW";
79 bufferDescriptor.
_name =
"LIGHT_SCENE";
88 vertModule.
_sourceFile =
"lightImpostorShader.glsl";
92 geomModule.
_sourceFile =
"lightImpostorShader.glsl";
96 fragModule.
_sourceFile =
"lightImpostorShader.glsl";
99 shaderDescriptor.
_modules.push_back( vertModule );
100 shaderDescriptor.
_modules.push_back( geomModule );
101 shaderDescriptor.
_modules.push_back( fragModule );
103 std::atomic_uint loadingTasks = 0u;
105 lightImpostorShader.waitForReady(
false );
109 iconImage.assetLocation( Paths::g_imagesLocation );
110 iconImage.assetName(
"lightIcons.png" );
111 iconImage.waitForReady(
false );
132 :
FrameListener(
"LightPool", context.kernel().frameListenerMgr(), 231 )
135 , _shadowPassTimer( Time::ADD_TIMER(
"Shadow Pass Timer" ) )
153 if ( !lightList.empty() )
196 _lights[lightTypeIdx].emplace_back( &light );
242 U32 totalShadowLightCount = 0u;
248 for (
Light* light : sortedLights )
250 const LightType lType = light->getLightType();
255 if ( !light->enabled() || !light->castsShadows() )
257 const U16 crtShadowIOffset = light->getShadowArrayOffset();
258 if ( crtShadowIOffset !=
U16_MAX )
264 light->setShadowArrayOffset(
U16_MAX );
289 light->shadowPropertyIndex( shadowIndex );
299 layerRange.
_offset = std::min( layerRange.
_offset, light->getShadowArrayOffset() );
308 layerRange.
_count = std::max( layerRange.
_count,
to_U16( light->getShadowArrayOffset() + 1u ) );
316 layerRange.
_count = std::max( layerRange.
_count,
to_U16( light->getShadowArrayOffset() + 1u ) );
339 light->cleanShadowProperties();
341 shadowsGenerated[
to_base( lType )] =
true;
365 const LightList::const_iterator it =
findLight( lightGUID, type );
377 const U8 stageIndex =
to_U8( stage );
383 SpotLightComponent* spot =
nullptr;
385 lightCount.fill( 0 );
387 for (
Light* light : lights )
389 const LightType type = light->getLightType();
392 if (
_lightTypeState[typeIndex] && light->enabled() && light->range() > 0.f )
404 spot =
static_cast<SpotLightComponent*
>(light);
408 light->getDiffuseColour( tempColour );
413 temp.
_options.
xyz = { typeIndex, light->shadowPropertyIndex(), isSpot ?
to_I32( spot->coneSlantHeight() ) : 0 };
415 ++lightCount[typeIndex];
427 const U8 stageIndex =
to_U8( stage );
430 sortedLights.resize( 0 );
436 sortedLights.insert( cend( sortedLights ), cbegin(
_lights[i] ), cend(
_lights[i] ) );
441 const auto lightSortCbk = [&eyePos](
Light* a,
Light* b )
noexcept
449 if ( sortedLights.size() > LightList::kMaxSize )
451 std::sort( std::execution::par_unseq, begin( sortedLights ), end( sortedLights ), lightSortCbk );
455 eastl::sort( begin( sortedLights ), end( sortedLights ), lightSortCbk );
460 sortedLights.insert( begin( sortedLights ), cbegin( dirLights ), cend( dirLights ) );
469 const size_t stageIndex =
to_size( stage );
482 if ( !sortedLights.empty() )
484 crtData.
_ambientColour.
rgb = { 0.05f * sortedLights.front()->getDiffuseColour() };
508 return light->staticShadowsDirty() || light->dynamicShadowsDirty();
517 if ( volume._volume.collision( lightBounds ) )
519 if ( volume._staticSource )
521 light->staticShadowsDirty(
true );
525 light->dynamicShadowsDirty(
true );
527 if ( light->staticShadowsDirty() && light->dynamicShadowsDirty() )
534 return light->staticShadowsDirty() || light->dynamicShadowsDirty();
541 constexpr U16 k_parallelSortThreshold = 16u;
543 const auto lightUpdateFunc = [playerCamera](
const LightList& lightList )
545 for (
Light* light : lightList )
547 light->updateBoundingVolume( playerCamera );
552 if (
_lights.size() > k_parallelSortThreshold )
554 std::for_each( std::execution::par_unseq, std::cbegin(
_lights ), std::cend(
_lights ), lightUpdateFunc );
560 lightUpdateFunc(list);
576 if ( !lightImpostorsEnabled() )
586 ._anisotropyLevel = 0u
590 if ( totalLightCount > 0u )
596 GFX::EnqueueCommand<GFX::BindPipelineCommand>( bufferInOut )->_pipeline =
_context.
gfx().
newPipeline( pipelineDescriptor );
598 auto cmd = GFX::EnqueueCommand<GFX::BindShaderResourcesCommand>( bufferInOut );
605 GFX::EnqueueCommand<GFX::DrawCommand>( bufferInOut )->_drawCommands.back()._drawCount =
to_U16( totalLightCount );
#define WAIT_FOR_CONDITION(...)
#define PROFILE_SCOPE_AUTO(CATEGORY)
#define PROFILE_SCOPE(NAME, CATEGORY)
const Frustum & getFrustum() const noexcept
Returns the most recent/up-to-date frustum.
const CameraSnapshot & snapshot() const noexcept
Returns the internal camera snapshot data (eye, orientation, etc)
ShaderBuffer_uptr newSB(const ShaderBufferDescriptor &descriptor)
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...
FORCE_INLINE I64 getGUID() const noexcept
A light object placed in the scene at a certain position.
F32 distanceSquared(const vec3< F32 > &pos) const noexcept
Get the distance squared from this light to the specified position.
const LightType & getLightType() const noexcept
Get the light type. (see LightType enum)
void debugLight(Light *light)
nullptr = disabled
std::array< LightData, to_base(RenderStage::COUNT)> _sortedLightProperties
SharedMutex _movedSceneVolumesLock
U32 uploadLightList(RenderStage stage, const LightList &lights, const mat4< F32 > &viewMatrix)
void drawLightImpostors(GFX::CommandBuffer &bufferInOut) const
Light * getLight(I64 lightGUID, LightType type) const
void uploadLightData(RenderStage stage, const CameraSnapshot &cameraSnapshot, GFX::MemoryBarrierCommand &memCmdInOut)
void preRenderAllPasses(const Camera *playerCamera)
static Handle< ShaderProgram > s_lightImpostorShader
void generateShadowMaps(const Camera &playerCamera, GFX::CommandBuffer &bufferInOut, GFX::MemoryBarrierCommand &memCmdInOut)
static ShaderBuffer_uptr s_lightBuffer
std::array< LightProperties, Config::Lighting::MAX_ACTIVE_LIGHTS_PER_FRAME > LightData
static bool IsLightInViewFrustum(const Frustum &frustum, const Light *light) noexcept
void sortLightData(RenderStage stage, const CameraSnapshot &cameraSnapshot)
std::array< SceneData, to_base(RenderStage::COUNT)> _sortedSceneProperties
LightList::const_iterator findLight(const I64 GUID, const LightType type) const
ShadowProperties _shadowBufferData
void onVolumeMoved(const BoundingSphere &volume, bool staticSource)
std::array< LightList, to_base(LightType::COUNT)> _lights
LightPool(Scene &parentScene, PlatformContext &context)
bool frameEnded(const FrameEvent &evt) override
frameEnded is called after the buffers have been swapped
Time::ProfileTimer & _shadowPassTimer
bool removeLight(const Light &light)
remove a light from the manager
bool isShadowCacheInvalidated(const vec3< F32 > &cameraPosition, Light *light)
static ShaderBuffer_uptr s_shadowBuffer
static ShaderBuffer_uptr s_sceneBuffer
eastl::fixed_vector< Light *, 32u, true > LightList
static void DestroyStaticData()
std::array< bool, to_base(LightType::COUNT)> _lightTypeState
static void InitStaticData(PlatformContext &context)
static std::array< U8, to_base(ShadowType::COUNT)> s_shadowLocation
std::array< LightList, to_base(RenderStage::COUNT)> _sortedLights
bool addLight(Light &light)
Add a new light to the manager.
static Handle< Texture > s_lightIconsTexture
std::array< U32, to_base(RenderStage::COUNT)> _sortedLightPropertiesCount
std::array< LightCountPerType, to_base(RenderStage::COUNT)> _activeLightCount
bool frameStarted(const FrameEvent &evt) override
LightList::const_iterator findLightLocked(const I64 GUID, const LightType type) const
eastl::fixed_vector< MovingVolume, Config::MAX_VISIBLE_NODES, true > _movedSceneVolumes
PlatformContext & context() noexcept
PlatformContext & _context
GFXDevice & gfx() noexcept
Handle< Texture > texture() const
RTAttachment * getAttachment(RTAttachmentType type, RTColourAttachmentSlot slot=RTColourAttachmentSlot::SLOT_0) const
static void setDebugViewLight(GFXDevice &context, Light *light)
static bool freeShadowMapOffset(const Light &light)
static bool generateShadowMaps(const Camera &playerCamera, Light &light, GFX::CommandBuffer &bufferInOut, GFX::MemoryBarrierCommand &memCmdInOut)
static const RenderTargetHandle & getShadowMap(LightType type)
static void resetShadowMaps()
static void generateWorldAO(const Camera &playerCamera, GFX::CommandBuffer &bufferInOut, GFX::MemoryBarrierCommand &memCmdInOut)
static bool markShadowMapsUsed(Light &light)
static void bindShadowMaps(GFX::CommandBuffer &bufferInOut)
void set(const T *v) noexcept
set the 4 components of the vector manually using a source pointer to a (large enough) array
constexpr T DegreesToRadians(T angleDegrees) noexcept
Return the radian equivalent of the given degree value.
constexpr U8 MAX_SHADOW_CASTING_POINT_LIGHTS
constexpr U8 MAX_SHADOW_CASTING_SPOT_LIGHTS
constexpr U16 MAX_ACTIVE_LIGHTS_PER_FRAME
Maximum number of lights we process per frame. We need this upper bound for pre-allocating arrays and...
constexpr U8 MAX_SHADOW_CASTING_LIGHTS
Maximum number of shadow casting lights processed per frame.
constexpr U8 MAX_CSM_SPLITS_PER_LIGHT
Used for CSM or PSSM to determine the maximum number of frustum splits.
constexpr U8 MAX_SHADOW_CASTING_DIRECTIONAL_LIGHTS
How many lights (in order as passed to the shader for the node) should cast shadows.
constexpr U8 MAX_FRAMES_IN_FLIGHT
Maximum number of active frames until we start waiting on a fence/sync.
FORCE_INLINE T * EnqueueCommand(CommandBuffer &buffer)
constexpr Optick::Category::Type Scene
constexpr Optick::Category::Type Graphics
FORCE_INLINE I32 GetMaxLights(const LightType type) noexcept
Handle console commands that start with a forward slash.
std::lock_guard< mutex > LockGuard
constexpr U32 to_U32(const T value)
FORCE_INLINE void DestroyResource(Handle< T > &handle, const bool immediate=false)
constexpr U16 to_U16(const T value)
DirectionalLightComponent(SceneGraphNode *sgn, PlatformContext &context)
std::shared_lock< mutex > SharedLock
void Set(DescriptorSetBindingData &dataInOut, ShaderBuffer *buffer, const BufferRange range) noexcept
DescriptorSetBinding & AddBinding(DescriptorSet &setInOut, U8 slot, U16 stageVisibilityMask)
FORCE_INLINE Handle< T > CreateResource(const ResourceDescriptor< T > &descriptor, bool &wasInCache, std::atomic_uint &taskCounter)
LightType
The different types of lights supported.
void efficient_clear(eastl::fixed_vector< T, nodeCount, bEnableOverflow, OverflowAllocator > &fixed_vector)
constexpr U8 to_U8(const T value)
constexpr size_t to_size(const T value)
constexpr I32 to_I32(const T value)
static const vec3< F32 > VECTOR3_ZERO
constexpr auto to_base(const Type value) -> Type
BufferUpdateUsage _updateUsage
BufferUsageType _usageType
BufferUpdateFrequency _updateFrequency
size_t _elementSize
Buffer primitive size in bytes.
static NO_INLINE void errorfn(const char *format, T &&... args)
DescriptorSetBindingData _data
Handle< Texture > _texture
vec4< F32 > _lightDetails
std::array< vec4< F32 >, 6 > _lightPosition
light's position in world space. w - csm split distances (or whatever else might be needed)
std::array< mat4< F32 >, 6 > _lightVP
light viewProjection matrices
std::array< vec4< F32 >, Config::Lighting::MAX_CSM_SPLITS_PER_LIGHT > _position
std::array< mat4< F32 >, Config::Lighting::MAX_CSM_SPLITS_PER_LIGHT > _vpMatrix
vec4< F32 > _ambientColour
std::array< PointShadowProperties, Config::Lighting::MAX_SHADOW_CASTING_POINT_LIGHTS > _pointLights
std::array< SpotShadowProperties, Config::Lighting::MAX_SHADOW_CASTING_SPOT_LIGHTS > _spotLights
std::array< CSMShadowProperties, Config::Lighting::MAX_SHADOW_CASTING_DIRECTIONAL_LIGHTS > _dirLights
bufferPtr data() const noexcept
Handle< ShaderProgram > _shaderProgramHandle
vector< ShaderModuleDescriptor > _modules
PropertyDescriptor< T > _propertyDescriptor
TextureMipSampling _mipSampling
BufferParams _bufferParams