Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
SingleShadowMapGenerator.cpp
Go to the documentation of this file.
1
2
4
9
13
15
22
24
25namespace Divide {
26
27namespace
28{
30};
31
34{
35
36 Console::printfn(LOCALE_STR("LIGHT_CREATE_SHADOW_FB"), "Single Shadow Map");
37
38 g_shadowSettings = context.context().config().rendering.shadowMapping;
39 {
40 ShaderModuleDescriptor vertModule{ ShaderType::VERTEX, "baseVertexShaders.glsl", "FullScreenQuad" };
41 ShaderModuleDescriptor geomModule{ ShaderType::GEOMETRY, "blur.glsl", "GaussBlur" };
42 ShaderModuleDescriptor fragModule{ ShaderType::FRAGMENT, "blur.glsl", "GaussBlur.Layered" };
43
44 geomModule._defines.emplace_back( "verticalBlur uint(PushData0[1].x)" );
45 geomModule._defines.emplace_back( "layerCount int(PushData0[1].y)" );
46 geomModule._defines.emplace_back( "layerOffsetRead int(PushData0[1].z)" );
47 geomModule._defines.emplace_back( "layerOffsetWrite int(PushData0[1].w)" );
48
49 geomModule._defines.emplace_back( "layerOffsetWrite int(PushData0[1].w)" );
50
51 fragModule._defines.emplace_back( "LAYERED" );
52 fragModule._defines.emplace_back( "layer uint(PushData0[0].x)" );
53 fragModule._defines.emplace_back( "size PushData0[0].yz" );
54 fragModule._defines.emplace_back( "kernelSize int(PushData0[0].w)" );
55 fragModule._defines.emplace_back( "verticalBlur uint(PushData0[1].x)" );
56
57 ShaderProgramDescriptor shaderDescriptor = {};
58 shaderDescriptor._modules.push_back(vertModule);
59 shaderDescriptor._modules.push_back(geomModule);
60 shaderDescriptor._modules.push_back(fragModule);
61 shaderDescriptor._globalDefines.emplace_back(Util::StringFormat("GS_MAX_INVOCATIONS {}", Config::Lighting::MAX_SHADOW_CASTING_SPOT_LIGHTS));
62
63 ResourceDescriptor<ShaderProgram> blurDepthMapShader(Util::StringFormat("GaussBlur_{}_invocations", Config::Lighting::MAX_SHADOW_CASTING_SPOT_LIGHTS), shaderDescriptor );
64 blurDepthMapShader.waitForReady(true);
65
66 _blurDepthMapShader = CreateResource(blurDepthMapShader);
67 PipelineDescriptor pipelineDescriptor = {};
68 pipelineDescriptor._stateBlock = _context.get2DStateBlock();
69 pipelineDescriptor._shaderProgramHandle = _blurDepthMapShader;
71
72 _blurPipeline = _context.newPipeline( pipelineDescriptor );
73 }
74
75 _shaderConstants.data[0]._vec[1].y = 1.f;
76 _shaderConstants.data[0]._vec[1].z = 0.f;
77 _shaderConstants.data[0]._vec[1].w = 0.f;
78
79 std::array<vec2<F32>*, 12> blurSizeConstants = {
92 };
93
94 blurSizeConstants[0]->set( 1.f / g_shadowSettings.spot.shadowMapResolution );
95 for ( size_t i = 1u; i < blurSizeConstants.size(); ++i )
96 {
97 blurSizeConstants[i]->set((*blurSizeConstants[i - 1]) * 0.5f);
98 }
99
100 SamplerDescriptor sampler = {};
105 sampler._anisotropyLevel = 0u;
106
108 const auto& texDescriptor = Get(rt->getAttachment(RTAttachmentType::COLOUR)->texture())->descriptor();
109
110 //Draw FBO
111 {
112 RenderTargetDescriptor desc = {};
113 desc._resolution = rt->getResolution();
114
115 TextureDescriptor colourDescriptor{};
116 colourDescriptor._texType = TextureType::TEXTURE_2D_ARRAY;
117 colourDescriptor._dataType = texDescriptor._dataType;
118 colourDescriptor._baseFormat = texDescriptor._baseFormat;
119 colourDescriptor._layerCount = 1u;
120 colourDescriptor._mipMappingState = MipMappingState::OFF;
121
122 TextureDescriptor depthDescriptor{};
123 depthDescriptor._texType = TextureType::TEXTURE_2D_ARRAY;
124 depthDescriptor._dataType = GFXDataFormat::UNSIGNED_INT;
125 depthDescriptor._baseFormat = GFXImageFormat::RED;
126 depthDescriptor._packing = GFXImagePacking::DEPTH;
127 depthDescriptor._layerCount = 1u;
128 depthDescriptor._mipMappingState = MipMappingState::OFF;
129
130 desc._attachments =
131 {
134 };
135
136 desc._name = "Single_ShadowMap_Draw";
137 desc._msaaSamples = g_shadowSettings.spot.MSAASamples;
138
140 }
141
142 //Blur FBO
143 {
144 TextureDescriptor blurMapDescriptor{};
145 blurMapDescriptor._texType = TextureType::TEXTURE_2D_ARRAY;
146 blurMapDescriptor._dataType = texDescriptor._dataType;
147 blurMapDescriptor._baseFormat = texDescriptor._baseFormat;
148 blurMapDescriptor._layerCount = 1u;
149 blurMapDescriptor._mipMappingState = MipMappingState::OFF;
150
151 RenderTargetDescriptor desc = {};
152 desc._attachments =
153 {
155 };
156
157 desc._name = "Single_Blur";
158 desc._resolution = rt->getResolution();
159
161 }
162
164}
165
167{
169 {
171 }
173}
174
175void SingleShadowMapGenerator::render([[maybe_unused]] const Camera& playerCamera, Light& light, U16 lightIndex, GFX::CommandBuffer& bufferInOut, GFX::MemoryBarrierCommand& memCmdInOut)
176{
178
179 const vec3<F32> lightPos = light.positionCache();
180 const F32 farPlane = light.range() * 1.2f;
181
182 auto& shadowCameras = ShadowMap::shadowCameras(ShadowType::SINGLE);
183 const mat4<F32> viewMatrix = shadowCameras[0]->lookAt(lightPos, lightPos + light.directionCache() * farPlane);
184 const mat4<F32> projectionMatrix = shadowCameras[0]->setProjection(1.0f, 90.0f, vec2<F32>(0.01f, farPlane));
185 shadowCameras[0]->updateLookAt();
186
187 mat4<F32> lightVP = light.getShadowVPMatrix(0);
188 mat4<F32>::Multiply(projectionMatrix, viewMatrix, lightVP);
189 light.setShadowLightPos(0, lightPos);
190 light.setShadowFloatValue(0, shadowCameras[0]->snapshot()._zPlanes.max);
192
193 RenderPassParams params = {};
194 params._sourceNode = light.sgn();
197 params._passName = "SingleShadowMap";
198 params._maxLoD = -1;
199 params._refreshLightData = false;
204
205 auto cmd = GFX::EnqueueCommand<GFX::BeginDebugScopeCommand>(bufferInOut);
206 Util::StringFormat( cmd->_scopeName, "Single Shadow Pass Light: [ {} ]", lightIndex);
207 cmd->_scopeId = lightIndex;
208
209 _context.context().kernel().renderPassManager()->doCustomPass(shadowCameras[0], params, bufferInOut, memCmdInOut);
210
211 GFX::BlitRenderTargetCommand blitRenderTargetCommand = {};
212 blitRenderTargetCommand._source = _drawBufferDepth._targetID;
213 blitRenderTargetCommand._destination = ShadowMap::getShadowMap( _type )._targetID;
214 blitRenderTargetCommand._params.emplace_back( RTBlitEntry{
215 ._input = {
216 ._layerOffset = 0u,
217 ._index = 0u
218 },
219 ._output = {
220 ._layerOffset = light.getShadowArrayOffset(),
221 ._index = 0u
222 }
223 } );
224
225 GFX::EnqueueCommand(bufferInOut, blitRenderTargetCommand);
226
227 if ( g_shadowSettings.spot.enableBlurring )
228 {
229 blurTarget( light.getShadowArrayOffset(), bufferInOut );
230 }
231
232 GFX::EnqueueCommand<GFX::EndDebugScopeCommand>(bufferInOut);
233}
234
235void SingleShadowMapGenerator::blurTarget( const U16 layerOffset, GFX::CommandBuffer& bufferInOut )
236{
238 const RenderTarget* shadowMapRT = handle._rt;
239 const auto& shadowAtt = shadowMapRT->getAttachment( RTAttachmentType::COLOUR );
240
241 // Now we can either blur our target or just skip to mipmap computation
242 GFX::BeginRenderPassCommand beginRenderPassCmd{};
243 beginRenderPassCmd._descriptor._layeredRendering = true;
244
245 beginRenderPassCmd._clearDescriptor[to_base( RTColourAttachmentSlot::SLOT_0 )] = { DefaultColours::WHITE, true };
246 beginRenderPassCmd._descriptor._drawMask[to_base( RTColourAttachmentSlot::SLOT_0 )] = true;
247
248 // Blur horizontally
249 beginRenderPassCmd._target = _blurBuffer._targetID;
250 beginRenderPassCmd._name = "DO_SM_BLUR_PASS_HORIZONTAL";
251 GFX::EnqueueCommand(bufferInOut, beginRenderPassCmd);
252
253 GFX::EnqueueCommand<GFX::BindPipelineCommand>(bufferInOut)->_pipeline = _blurPipeline;
254 {
255 auto cmd = GFX::EnqueueCommand<GFX::BindShaderResourcesCommand>(bufferInOut);
256 cmd->_usage = DescriptorSetUsage::PER_DRAW;
258 Set( binding._data, shadowAtt->texture(), shadowAtt->_descriptor._sampler );
259 }
260
261 _shaderConstants.data[0]._vec[1].x = 0.f;
262 _shaderConstants.data[0]._vec[1].y = 1.f;
263 _shaderConstants.data[0]._vec[1].z = to_F32( layerOffset );
264 _shaderConstants.data[0]._vec[1].w = 0.f;
265
266 GFX::EnqueueCommand<GFX::SendPushConstantsCommand>(bufferInOut)->_fastData = _shaderConstants;
267
268 GFX::EnqueueCommand<GFX::DrawCommand>(bufferInOut)->_drawCommands.emplace_back();
269
270 GFX::EnqueueCommand<GFX::EndRenderPassCommand>(bufferInOut);
271
272 // Blur vertically
273 beginRenderPassCmd._target = handle._targetID;
274 beginRenderPassCmd._name = "DO_SM_BLUR_PASS_VERTICAL";
275 GFX::EnqueueCommand(bufferInOut, beginRenderPassCmd);
276
278 {
279 auto cmd = GFX::EnqueueCommand<GFX::BindShaderResourcesCommand>(bufferInOut);
280 cmd->_usage = DescriptorSetUsage::PER_DRAW;
282 Set( binding._data, blurAtt->texture(), blurAtt->_descriptor._sampler );
283 }
284
285
286 _shaderConstants.data[0]._vec[1].x = 1.f;
287 _shaderConstants.data[0]._vec[1].y = 1.f;
288 _shaderConstants.data[0]._vec[1].z = 0.f;
289 _shaderConstants.data[0]._vec[1].w = to_F32( layerOffset );
290
291 GFX::EnqueueCommand<GFX::SendPushConstantsCommand>( bufferInOut )->_fastData = _shaderConstants;
292
293 GFX::EnqueueCommand<GFX::DrawCommand>(bufferInOut)->_drawCommands.emplace_back();
294
295 GFX::EnqueueCommand<GFX::EndRenderPassCommand>(bufferInOut);
296
297}
298
300{
302 {
305 }
306}
307};
#define WAIT_FOR_CONDITION(...)
#define LOCALE_STR(X)
Definition: Localization.h:91
#define DIVIDE_UNEXPECTED_CALL()
#define PROFILE_SCOPE_AUTO(CATEGORY)
Definition: Profiler.h:87
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
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
RenderTargetHandle allocateRT(const RenderTargetDescriptor &descriptor)
Definition: GFXRTPool.cpp:17
bool deallocateRT(RenderTargetHandle &handle)
Definition: GFXRTPool.cpp:33
A light object placed in the scene at a certain position.
Definition: Light.h:58
void setShadowFloatValue(const U8 index, const F32 newValue) noexcept
Definition: Light.inl:60
void setShadowLightPos(const U8 index, const vec3< F32 > &newValue) noexcept
Definition: Light.inl:62
void setShadowVPMatrix(const U8 index, const mat4< F32 > &newValue) noexcept
Definition: Light.inl:58
const mat4< F32 > & getShadowVPMatrix(const U8 index) const noexcept
Definition: Light.inl:52
U16 getShadowArrayOffset() const noexcept
Definition: Light.inl:79
PlatformContext & context() noexcept
Kernel & kernel() noexcept
Configuration & config() noexcept
Handle< Texture > texture() const
RTAttachment * getAttachment(RTAttachmentType type, RTColourAttachmentSlot slot=RTColourAttachmentSlot::SLOT_0) const
bool updateSampleCount(U8 newSampleCount)
Change msaa sampel count for all attachments.
vec2< U16 > getResolution() const noexcept
const ShadowType _type
Definition: ShadowMap.h:83
static const RenderTargetHandle & getShadowMap(LightType type)
Definition: ShadowMap.cpp:495
static vector< Camera * > & shadowCameras(const ShadowType type) noexcept
Definition: ShadowMap.h:122
void render(const Camera &playerCamera, Light &light, U16 lightIndex, GFX::CommandBuffer &bufferInOut, GFX::MemoryBarrierCommand &memCmdInOut) override
void blurTarget(U16 layerOffset, GFX::CommandBuffer &bufferInOut)
Handle< ShaderProgram > _blurDepthMapShader
void updateMSAASampleCount(U8 sampleCount) override
vec4< T > _vec[4]
Definition: MathMatrices.h:709
static mat4< T > Multiply(const mat4< T > &matrixA, const mat4< T > &matrixB) noexcept
ret = A * B
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
vec2< T > xy
Definition: MathVectors.h:1366
vec2< T > zw
Definition: MathVectors.h:1366
constexpr U8 MAX_SHADOW_CASTING_SPOT_LIGHTS
Definition: config.h:153
FColour4 WHITE
Random stuff added for convenience.
Definition: Colours.cpp:8
FORCE_INLINE T * EnqueueCommand(CommandBuffer &buffer)
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
FORCE_INLINE void DestroyResource(Handle< T > &handle, const bool immediate=false)
static constexpr U32 RT_DEPTH_ATTACHMENT_IDX
Definition: RTAttachment.h:71
static const mat4< F32 > MAT4_BIAS_ZERO_ONE_Z
Definition: MathMatrices.h:720
uint8_t U8
constexpr F32 to_F32(const T value)
uint16_t U16
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)
ShadowType
Definition: ShadowMap.h:40
RTClearEntry DEFAULT_CLEAR_ENTRY
FORCE_INLINE T * Get(const Handle< T > handle)
constexpr auto to_base(const Type value) -> Type
U16 _layerOffset
struct Divide::Configuration::Rendering::ShadowMapping shadowMapping
struct Divide::Configuration::Rendering rendering
static NO_INLINE void printfn(const char *format, T &&... args)
DescriptorSetBindingData _data
PrimitiveTopology _primitiveTopology
Definition: Pipeline.h:48
Handle< ShaderProgram > _shaderProgramHandle
Definition: Pipeline.h:47
RenderStateBlock _stateBlock
Definition: Pipeline.h:46
vector< ShaderModuleDescriptor > _modules
BlitEntry _input
bool _layeredRendering
Set to true to bind all image layers to the render target (e.g. for Geometry Shader layered rendering...
const SceneGraphNode * _sourceNode
RTDrawDescriptor _targetDescriptorMainPass
RTClearDescriptor _clearDescriptorMainPass
InternalRTAttachmentDescriptors _attachments
Definition: RenderTarget.h:52
RenderTargetID _targetID
Definition: RenderTarget.h:47
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