91 s_availableSlices[slice] = {
true,
false };
130 desc.
_name =
"ReflectionEnvMap";
148 desc.
_name =
"PrefilteredEnvMap";
151 desc.
_name =
"IrradianceEnvMap";
152 desc.
_resolution.
set(s_IrradianceTextureSize, s_IrradianceTextureSize);
168 desc.
_name =
"BrdfLUT";
176 vertModule.
_variant =
"FullScreenQuad";
184 shaderDescriptor.
_modules.push_back(vertModule);
185 shaderDescriptor.
_modules.push_back(fragModule);
188 shadowPreviewShader.waitForReady(
true);
197 shaderDescriptor.
_modules.push_back(computeModule);
198 shaderDescriptor.
_globalDefines.emplace_back(
"imgSizeX PushData0[0].x" );
199 shaderDescriptor.
_globalDefines.emplace_back(
"imgSizeY PushData0[0].y" );
200 shaderDescriptor.
_globalDefines.emplace_back(
"layerIndex PushData0[0].z" );
203 shaderDescriptor.
_modules.back()._variant =
"Irradiance";
206 irradianceShader.waitForReady(
true);
210 shaderDescriptor.
_modules.back()._variant =
"LUT";
212 lutShader.waitForReady(
true);
216 shaderDescriptor.
_modules.back()._variant =
"PreFilter";
217 shaderDescriptor.
_globalDefines.emplace_back(
"mipLevel uint(PushData0[1].x)" );
218 shaderDescriptor.
_globalDefines.emplace_back(
"roughness PushData0[1].y" );
220 prefilterShader.waitForReady(
true);
264 s_computationQueue = {};
265 s_computationSet.clear();
289 [&position](
const auto& a,
const auto& b)
noexcept ->
bool {
290 return a->distanceSqTo(position) < b->distanceSqTo(position);
305 renderPassCmd->
_name =
"DO_REFLECTION_PROBE_CLEAR";
312 GFX::EnqueueCommand<GFX::EndRenderPassCommand>(bufferInOut);
332 GFX::EnqueueCommand<GFX::BindPipelineCommand>(bufferInOut)->_pipeline = pipelineCalcLut;
335 auto cmd = GFX::EnqueueCommand<GFX::BindShaderResourcesCommand>(bufferInOut);
340 GFX::EnqueueCommand<GFX::MemoryBarrierCommand>( bufferInOut )->_textureLayoutChanges.emplace_back(
TextureLayoutChange
352 GFX::EnqueueCommand<GFX::DispatchComputeCommand>(bufferInOut)->_computeGroupSize = { groupsX, groupsY, 1 };
354 GFX::EnqueueCommand<GFX::MemoryBarrierCommand>( bufferInOut )->_textureLayoutChanges.emplace_back(
TextureLayoutChange
362 computeMipMapsCommand.
_texture = brdfLutTexture;
373 GFX::EnqueueCommand<GFX::BeginDebugScopeCommand>(bufferInOut)->_scopeName =
"SkyLight Pass";
398 GFX::EnqueueCommand<GFX::EndDebugScopeCommand>(bufferInOut);
408 s_queuedLayer = s_computationQueue.front();
410 s_computationQueue.pop();
411 s_computationSet.erase(s_queuedLayer);
417 if constexpr ( !s_AlwaysProcessFullProbeRefreshPerFrame )
430 auto cmd = GFX::EnqueueCommand<GFX::BindShaderResourcesCommand>(bufferInOut);
455 if (s_computationSet.insert(layerID).second)
457 s_computationQueue.push(layerID);
472 auto scopeCmd = GFX::EnqueueCommand<GFX::BeginDebugScopeCommand>(bufferInOut );
473 Util::StringFormat( scopeCmd->_scopeName,
"Process environment map #{}-MipMapsSource", layerID);
477 computeMipMapsCommand.
_layerRange = { layerID, 1 };
482 GFX::EnqueueCommand<GFX::EndDebugScopeCommand>(bufferInOut);
512 auto scopeCmd = GFX::EnqueueCommand<GFX::BeginDebugScopeCommand>(bufferInOut);
518 const U16 width = sourceTex->width();
520 auto cmd = GFX::EnqueueCommand<GFX::BindShaderResourcesCommand>(bufferInOut);
533 const F32 maxMipLevel =
to_F32(std::log2(fWidth));
534 for (
F32 mipLevel = 0u; mipLevel <= maxMipLevel; ++mipLevel) {
537 const F32 roughness = mipLevel / maxMipLevel;
538 fastData.data[0]._vec[1].xy.set(mipLevel, roughness);
539 GFX::EnqueueCommand<GFX::SendPushConstantsCommand>(bufferInOut)->_fastData = fastData;
540 auto cmd = GFX::EnqueueCommand<GFX::BindShaderResourcesCommand>(bufferInOut);
543 GFX::EnqueueCommand<GFX::MemoryBarrierCommand>( bufferInOut )->_textureLayoutChanges.emplace_back(
TextureLayoutChange
554 const U16 mipWidth = width /
to_U16(std::pow(2.f, mipLevel));
555 GFX::EnqueueCommand<GFX::DispatchComputeCommand>(bufferInOut)->_computeGroupSize = { std::max(1u, mipWidth / 8u), std::max(1u, mipWidth / 8u), 1 };
557 GFX::EnqueueCommand<GFX::MemoryBarrierCommand>( bufferInOut )->_textureLayoutChanges.emplace_back(
TextureLayoutChange
566 computeMipMapsCommand.
_layerRange = { layerID, 1 };
571 GFX::EnqueueCommand<GFX::EndDebugScopeCommand>(bufferInOut);
581 auto scopeCmd = GFX::EnqueueCommand<GFX::BeginDebugScopeCommand>(bufferInOut);
588 GFX::EnqueueCommand<GFX::MemoryBarrierCommand>( bufferInOut )->_textureLayoutChanges.emplace_back(
TextureLayoutChange
595 auto cmd = GFX::EnqueueCommand<GFX::BindShaderResourcesCommand>(bufferInOut);
606 PushConstantsStruct& fastData = GFX::EnqueueCommand<GFX::SendPushConstantsCommand>(bufferInOut)->_fastData;
609 const U32 groupsX =
to_U32(std::ceil(s_IrradianceTextureSize /
to_F32(8)));
610 const U32 groupsY =
to_U32(std::ceil(s_IrradianceTextureSize /
to_F32(8)));
611 GFX::EnqueueCommand<GFX::DispatchComputeCommand>(bufferInOut)->_computeGroupSize = { groupsX, groupsY, 1 };
613 GFX::EnqueueCommand<GFX::MemoryBarrierCommand>( bufferInOut )->_textureLayoutChanges.emplace_back(
TextureLayoutChange
621 computeMipMapsCommand.
_layerRange = { layerID, 1 };
626 GFX::EnqueueCommand<GFX::EndDebugScopeCommand>(bufferInOut);
657 if (probe !=
nullptr) {
660 [probeGUID = probe->
getGUID()](
const auto& p)
noexcept { return p->getGUID() == probeGUID; }),
663 (*it)->poolIndex((*it)->poolIndex() - 1);
668 if (probe == _debugProbe)
670 _debugProbe =
nullptr;
681 const bool enableProbeDebugging = _debugProbe !=
nullptr;
683 const I16 probeID = enableProbeDebugging ? g_debugViewBase + _debugProbe->rtLayerIndex() : -1;
685 bool addSkyLightViews =
true, addProbeViews =
true;
687 if (view->_groupID == skyLightGroupID) {
688 addSkyLightViews =
false;
689 view->_enabled = enableSkyLightDebug;
690 }
else if (enableProbeDebugging && view->_groupID == probeID) {
691 addProbeViews =
false;
692 view->_enabled =
true;
694 view->_enabled =
false;
698 if (enableSkyLightDebug && addSkyLightViews)
702 if (enableProbeDebugging && addProbeViews)
710 for (
U32 i = 0u; i < 18u; ++i)
713 probeView->_cycleMips =
true;
736 Util::StringFormat( probeView->_name,
"Probe_{}_Filtered_face_{}", layerIndex, i % 6u );
740 Util::StringFormat( probeView->_name,
"Probe_{}_Irradiance_face_{}", layerIndex, i % 6u );
744 Util::StringFormat( probeView->_name,
"Probe_{}_Reference_face_{}", layerIndex, i % 6u );
747 probeView->_groupID = g_debugViewBase + layerIndex;
748 probeView->_enabled =
true;
760 for (
const auto& probe : probes)
762 if (probe->checkCollisionAndQueueUpdate(bSphere))
770 SkyLightNeedsRefresh(
true);
778 probePool.lockProbeList();
780 for (
const auto& probe : probes)
787 probePool.unlockProbeList();
788 SkyLightNeedsRefresh(
true);
798 s_debuggingSkyLight = state;
808 s_skyLightNeedsRefresh = state;
#define PROFILE_SCOPE_AUTO(CATEGORY)
#define PROFILE_SCOPE(NAME, CATEGORY)
void poolIndex(U16 index) noexcept
Rough around the edges Adapter pattern abstracting the actual rendering API and access to the GPU.
void generateCubeMap(RenderPassParams ¶ms, U16 arrayOffset, const vec3< F32 > &pos, vec2< F32 > zPlanes, GFX::CommandBuffer &commandsInOut, GFX::MemoryBarrierCommand &memCmdInOut, mat4< F32 > *viewProjectionOut=nullptr)
Generate a cube texture and store it in the provided RenderTarget.
GFXRTPool & renderTargetPool() noexcept
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...
bool removeDebugView(DebugView *view)
const RenderStateBlock & get2DStateBlock() const noexcept
DebugView * addDebugView(const std::shared_ptr< DebugView > &view)
RenderTarget * getRenderTarget(const RenderTargetID target) const
RenderTargetHandle allocateRT(const RenderTargetDescriptor &descriptor)
bool deallocateRT(RenderTargetHandle &handle)
FORCE_INLINE I64 getGUID() const noexcept
PlatformContext & context() noexcept
GFXDevice & gfx() noexcept
Configuration & config() noexcept
Handle< Texture > texture() const
RTAttachmentDescriptor _descriptor
RTAttachment * getAttachment(RTAttachmentType type, RTColourAttachmentSlot slot=RTColourAttachmentSlot::SLOT_0) const
Scene & parentScene() noexcept
void onNodeUpdated(const SceneGraphNode &node) noexcept
static RenderTargetHandle s_irradiance
static RenderTargetHandle ReflectionTarget() noexcept
static bool ProbesDirty() noexcept
void unlockProbeList() const noexcept
static U16 AllocateSlice(bool lock)
static void UpdateSkyLight(GFXDevice &context, GFX::CommandBuffer &bufferInOut, GFX::MemoryBarrierCommand &memCmdInOut)
void registerProbe(EnvironmentProbeComponent *probe)
SceneEnvironmentProbePool(Scene &parentScene) noexcept
static bool s_skyLightNeedsRefresh
static std::array< ProbeSlice, Config::MAX_REFLECTIVE_PROBES_PER_PASS > s_availableSlices
static Pipeline * s_pipelineCalcIrradiance
static RenderTargetHandle s_reflection
static Pipeline * s_pipelineCalcPrefiltered
static RenderTargetHandle s_brdfLUT
static Handle< ShaderProgram > s_lutComputeShader
const EnvironmentProbeList & getLocked() const noexcept
static bool DebuggingSkyLight() noexcept
static bool SkyLightNeedsRefresh() noexcept
static RenderTargetHandle BRDFLUTTarget() noexcept
const EnvironmentProbeList & sortAndGetLocked(const vec3< F32 > &position)
static void Prepare(GFX::CommandBuffer &bufferInOut)
static Handle< ShaderProgram > s_irradianceComputeShader
static Handle< ShaderProgram > s_previewShader
void createDebugView(U16 layerIndex)
static RenderTargetHandle IrradianceTarget() noexcept
static void PrefilterEnvMap(const U16 layerID, GFX::CommandBuffer &bufferInOut)
static void ProcessEnvironmentMapInternal(const U16 layerID, ComputationStages &stage, GFX::CommandBuffer &bufferInOut)
static bool s_lutTextureDirty
static void OnStartup(GFXDevice &context)
static U16 SkyProbeLayerIndex() noexcept
void lockProbeList() const noexcept
static RenderTargetHandle s_prefiltered
~SceneEnvironmentProbePool()
EnvironmentProbeList _envProbes
static bool s_probesDirty
static vector< DebugView_ptr > s_debugViews
static void ComputeIrradianceMap(const U16 layerID, GFX::CommandBuffer &bufferInOut)
static void OnTimeOfDayChange(const SceneEnvironmentProbePool &probePool) noexcept
static Handle< ShaderProgram > s_prefilterComputeShader
static RenderTargetHandle PrefilteredTarget() noexcept
static void OnShutdown(GFXDevice &context)
static bool s_debuggingSkyLight
void unregisterProbe(const EnvironmentProbeComponent *probe)
static void UnlockSlice(U16 slice) noexcept
static void ProcessEnvironmentMap(U16 layerID, bool highPriority)
void set(const T *v) noexcept
set the 2 components of the vector manually using a source pointer to a (large enough) array
void set(const T *v) noexcept
set the 3 components of the vector manually using a source pointer to a (large enough) array
constexpr bool IS_DEBUG_BUILD
constexpr U8 MAX_REFLECTIVE_NODES_IN_VIEW
constexpr U8 MAX_REFLECTIVE_PROBES_PER_PASS
Maximum number of environment probes we are allowed to update per frame.
FORCE_INLINE T * EnqueueCommand(CommandBuffer &buffer)
constexpr Optick::Category::Type GameLogic
constexpr Optick::Category::Type Graphics
Str StringFormat(const char *fmt, Args &&...args)
NO_DESTROY Mutex s_queueLock
static SceneEnvironmentProbePool::ComputationStages s_queuedStage
constexpr bool s_AlwaysRefreshSkyLight
constexpr U16 s_LUTTextureSize
constexpr U16 s_IrradianceTextureSize
constexpr I16 g_debugViewBase
NO_DESTROY eastl::queue< U16 > s_computationQueue
NO_DESTROY eastl::set< U16 > s_computationSet
constexpr bool s_AlwaysProcessFullProbeRefreshPerFrame
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)
static constexpr U32 RT_DEPTH_ATTACHMENT_IDX
constexpr U16 to_U16(const T value)
constexpr F32 to_F32(const T value)
void AddImageUsageFlag(PropertyDescriptor< Texture > &descriptor, const ImageUsage usage) noexcept
eastl::vector< Type > vector
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 U8 to_U8(const T value)
constexpr I16 to_I16(const T value)
RTClearEntry DEFAULT_CLEAR_ENTRY
vector< EnvironmentProbeComponent * > EnvironmentProbeList
static const vec3< F32 > VECTOR3_ZERO
FORCE_INLINE T * Get(const Handle< T > handle)
constexpr auto to_base(const Type value) -> Type
U8 maxAnisotropicFilteringLevel
U16 reflectionProbeResolution
struct Divide::Configuration::Rendering rendering
DescriptorSetBindingData _data
RTDrawDescriptor _descriptor
RTClearDescriptor _clearDescriptor
Handle< Texture > _texture
RenderStateBlock _stateBlock
vector< ShaderModuleDescriptor > _modules
ModuleDefines _globalDefines
SamplerDescriptor _sampler
RTClearDescriptor _clearDescriptorPrePass
RTDrawDescriptor _targetDescriptorPrePass
RTDrawDescriptor _targetDescriptorMainPass
RenderStagePass _stagePass
RTClearDescriptor _clearDescriptorMainPass
InternalRTAttachmentDescriptors _attachments
static RenderTargetID REFLECTION_CUBE
TextureMipSampling _mipSampling