Cogs.Core
DeferredLightingTask.cpp
1#include "DeferredLightingTask.h"
2
3#include "Rendering/IGraphicsDevice.h"
4#include "Rendering/IContext.h"
5#include "Rendering/CommandGroupAnnotation.h"
6
7#include "Context.h"
8#include "Renderer/Renderer.h"
9#include "Renderer/RenderTarget.h"
10#include "Renderer/RenderStateUpdater.h"
11#include "Services/Variables.h"
12#include "Systems/Core/LightSystem.h"
13#include "Systems/Core/EnvironmentSystem.h"
14#include "Utilities/Parsing.h"
15
16using namespace Cogs;
17
18bool Cogs::Core::DeferredLightingTask::setupEffect(RenderTaskContext * context)
19{
20 auto device = context->renderer->getDevice();
21 auto deviceContext = device->getImmediateContext();
22 CommandGroupAnnotation annotation(deviceContext, "DeferredLightingTask::initialize");
23
25 desc.vs = "Engine/FullscreenV3T2VS.hlsl";
26 desc.ps = "Engine/DeferredLightingPS.hlsl";
27 desc.definitions.push_back({ "COGS_FORWARD_SHADOWS_ENABLED", "1" });
28 desc.definitions.push_back({ "COGS_NUM_DIRECTIONAL_SHADOW_LIGHTS", std::to_string(context->renderer->getActiveLights().numDirectionalShadowLights) });
29 desc.definitions.push_back({ "COGS_NUM_DIRECTIONAL_LIGHTS", std::to_string(context->renderer->getActiveLights().numDirectionalLights) });
30 desc.definitions.push_back({ "COGS_NUM_POINT_SHADOW_LIGHTS", std::to_string(context->renderer->getActiveLights().numPointShadowLights) });
31 desc.definitions.push_back({ "COGS_NUM_POINT_LIGHTS", std::to_string(context->renderer->getActiveLights().numPointLights) });
32
33 auto softShadows = parseEnum<SoftShadows>(context->context->variables->get("shadows.softShadows", "Default"));
34 switch (softShadows) {
35 case SoftShadows::High:
36 desc.definitions.push_back({ "COGS_SOFT_SHADOWS_HIGH", "1" });
37 break;
38 case SoftShadows::Low:
39 desc.definitions.push_back({ "COGS_SOFT_SHADOWS_LOW", "1" });
40 break;
41 default:
42 break;
43 }
44 if (auto ec = context->context->environmentSystem->getGlobalEnvironment(); ec != nullptr) {
45 if (ec->subseaSupport) {
46 desc.definitions.push_back({ "COGS_SUBSEA_SUPPORT", "1" });
47 }
48 if (ec->imageBasedLighting) {
49 desc.definitions.push_back({ "COGS_IMAGE_BASED_LIGHTING", "1" });
50 }
51 }
52 if(context->context->variables->get("renderer.reverseDepth", false)){
53 desc.definitions.push_back({ "COGS_REVERSE_DEPTH", "1" });
54 }
55 effect = context->renderer->getEffectCache().loadEffect(context, desc);
56 if (HandleIsValid(effect->handle) && (effectPrev != effect)) {
57 initializeGlobalBindings(context, effect, bindings);
58 }
59 effectPrev = effect;
60 return HandleIsValid(effect->handle);
61}
62
63void Cogs::Core::DeferredLightingTask::cleanup(RenderTaskContext * context)
64{
65 context->renderer->getEffectCache().release(context, effect);
66}
67
68void Cogs::Core::DeferredLightingTask::apply(RenderTaskContext * context)
69{
70 RenderInstrumentationScope(context->device->getImmediateContext(), SCOPE_RENDERING, "DeferredLightingTask::apply");
71
72 RenderTarget* deferredRenderTarget = input.get(RenderResourceType::RenderTarget)->renderTarget;
73 RenderTarget* renderTarget = output.get(RenderResourceType::RenderTarget)->renderTarget;
74
75 IGraphicsDevice* device = context->renderer->getDevice();
76 IContext* deviceContext = device->getImmediateContext();
77 if (!setupEffect(context)) {
78 return;
79 }
80
81 deviceContext->setEffect(effect->handle);
82
83 deviceContext->setRenderTarget(renderTarget->renderTargetHandle, DepthStencilHandle::NoHandle);
84
85 deviceContext->setViewport(
86 0,
87 0,
88 context->renderer->getSize().x,
89 context->renderer->getSize().y);
90
91 deviceContext->setDepthStencilState(context->states->noTestDepthStencilStateHandle);
92 deviceContext->setRasterizerState(context->states->defaultRasterizerStateHandle);
93 deviceContext->setBlendState(context->states->blendStates[size_t(BlendMode::None)].handle);
94
95 deviceContext->setEffect(effect->handle);
96
97 applyGlobalBindings(context, bindings);
98
99 const char * textureName[] = {
100 "colorTexture",
101 "emissiveTexture",
102 "specularTexture",
103 "normalTexture",
104 "depthTexture"
105 };
106
107 deviceContext->setTexture("colorTexture", 0, deferredRenderTarget->get("Color"));
108 deviceContext->setTexture("emissiveTexture", 1, deferredRenderTarget->get("Emissive"));
109 deviceContext->setTexture("specularTexture", 2, deferredRenderTarget->get("Specular"));
110 deviceContext->setTexture("normalTexture", 3, deferredRenderTarget->get("Normals"));
111 deviceContext->setTexture("depthTexture", 4, deferredRenderTarget->depth->textureHandle);
112
113 deviceContext->setVertexBuffers(nullptr, 0, nullptr, nullptr);
116 deviceContext->draw(PrimitiveType::TriangleList, 0, 3);
117
118 for (size_t i = 0; i < 5; ++i) {
119 deviceContext->setTexture(textureName[i], 0, Cogs::TextureHandle::NoHandle);
120 }
121}
122
123void Cogs::Core::DeferredLightingTask::initializeGlobalBindings(RenderTaskContext * context, CachedEffect * effect, GlobalBinding & bindings)
124{
125 auto effects = context->device->getEffects();
126
127 bindings.shadowBufferBinding = effects->getConstantBufferBinding(effect->handle, "ShadowBuffer");
128
129 bindings.shadowArrayBinding = effects->getTextureBinding(effect->handle, "cascadedShadowMap", 1);
130 bindings.shadowArrayBinding_1 = effects->getTextureBinding(effect->handle, "cascadedShadowMap_1", 1);
131 bindings.shadowCubeArrayBinding = effects->getTextureBinding(effect->handle, "cubeShadowMap", 2);
132 bindings.shadowCubeArrayBinding_1 = effects->getTextureBinding(effect->handle, "cubeShadowMap_1", 2);
133 bindings.shadowSamplerBinding = effects->getSamplerStateBinding(effect->handle, "cascadedShadowSampler", 2);
134
135 bindings.linearSampler = effects->getSamplerStateBinding(effect->handle, "linearSampler", 0);
136 bindings.radianceSamplerBinding = effects->getSamplerStateBinding(effect->handle, "environmentRadianceSampler", 0);
137 bindings.irradianceSamplerBinding = effects->getSamplerStateBinding(effect->handle, "environmentIrradianceSampler", 0);
138 bindings.ambientIrradianceSamplerBinding = effects->getSamplerStateBinding(effect->handle, "ambientIrradianceSampler", 0);
139
140 bindings.lightBufferBinding = effects->getConstantBufferBinding(effect->handle, "LightBuffer");
141 bindings.sceneBufferBinding = effects->getConstantBufferBinding(effect->handle, "SceneBuffer");
142}
143
144void Cogs::Core::DeferredLightingTask::applyGlobalBindings(RenderTaskContext * context, GlobalBinding & bindings)
145{
146 auto deviceContext = context->device->getImmediateContext();
147 auto engineBuffers = context->engineBuffers;
148
149 if (HandleIsValid(bindings.sceneBufferBinding)) {
150 deviceContext->setConstantBuffer(bindings.sceneBufferBinding, engineBuffers->sceneBufferHandle);
151 }
152
153 if (HandleIsValid(bindings.lightBufferBinding)) {
154 deviceContext->setConstantBuffer(bindings.lightBufferBinding, engineBuffers->lightBufferHandle);
155 }
156
157 auto shadowsEnabled = context->context->variables->get("renderer.shadowsEnabled", false);
158 auto lightSystem = context->context->lightSystem;
159
160 if (shadowsEnabled) {
161 if (HandleIsValid(bindings.shadowBufferBinding)) {
162 deviceContext->setConstantBuffer(bindings.shadowBufferBinding, engineBuffers->shadowBufferHandle);
163
164 if (HandleIsValid(bindings.shadowArrayBinding)) {
165 auto shadowTexture = context->resources->getRenderTexture(lightSystem->cascadeArray);
166
167 if (shadowTexture) {
168 deviceContext->setTexture(bindings.shadowArrayBinding, shadowTexture->textureHandle);
169 }
170 }
171 if (HandleIsValid(bindings.shadowArrayBinding_1)) {
172 auto shadowTexture = context->resources->getRenderTexture(lightSystem->cascadeArray);
173
174 if (shadowTexture) {
175 deviceContext->setTexture(bindings.shadowArrayBinding_1, shadowTexture->textureHandle);
176 }
177 }
178
179 if (HandleIsValid(bindings.shadowCubeArrayBinding)) {
180 auto shadowTexture = context->resources->getRenderTexture(lightSystem->cubeArray);
181
182 if (shadowTexture) {
183 deviceContext->setTexture(bindings.shadowCubeArrayBinding, shadowTexture->textureHandle);
184 }
185 }
186 if (HandleIsValid(bindings.shadowCubeArrayBinding_1)) {
187 auto shadowTexture = context->resources->getRenderTexture(lightSystem->cubeArray);
188
189 if (shadowTexture) {
190 deviceContext->setTexture(bindings.shadowCubeArrayBinding_1, shadowTexture->textureHandle);
191 }
192 }
193 }
194
195 if (HandleIsValid(bindings.shadowSamplerBinding)) {
196 deviceContext->setSamplerState(bindings.shadowSamplerBinding, context->states->shadowSampler);
197 }
198 }
199 if (HandleIsValid(bindings.radianceSamplerBinding)) {
200 deviceContext->setSamplerState(bindings.radianceSamplerBinding, context->states->defaultSampler);
201 }
202 if (HandleIsValid(bindings.irradianceSamplerBinding)) {
203 deviceContext->setSamplerState(bindings.irradianceSamplerBinding, context->states->defaultSampler);
204 }
205 if (HandleIsValid(bindings.ambientIrradianceSamplerBinding)) {
206 deviceContext->setSamplerState(bindings.ambientIrradianceSamplerBinding, context->states->defaultSampler);
207 }
208 if (HandleIsValid(bindings.brdfLUTSamplerBinding)) {
209 deviceContext->setSamplerState(bindings.brdfLUTSamplerBinding, context->states->defaultSampler);
210 }
211 if (HandleIsValid(bindings.linearSampler)) {
212 deviceContext->setSamplerState(bindings.linearSampler, context->states->defaultSampler);
213 }
214}
Represents a graphics device used to manage graphics resources and issue drawing commands.
virtual IContext * getImmediateContext()=0
Get a pointer to the immediate context used to issue commands to the graphics device.
bool HandleIsValid(const ResourceHandle_t< T > &handle)
Check if the given resource is valid, that is not equal to NoHandle or InvalidHandle.
@ None
No blending enabled for opaque shapes, defaults to Blend for transparent shapes.
Contains all Cogs related functionality.
Definition: FieldSetter.h:23
RAII-helper for pushCommandGroupAnnotation/pushCommandGroupAnnotation.
Contains an effect description used to load a single effect.
Definition: IEffects.h:55
static const Handle_t NoHandle
Represents a handle to nothing.
Definition: Common.h:77
Represents a graphics device context which can receive rendering commands.
Definition: IContext.h:43
virtual void setTexture(const StringView &name, unsigned int unit, TextureHandle textureHandle)=0
Sets the texture slot given by unit with the given name to contain the given texture.
virtual void setRasterizerState(const RasterizerStateHandle handle)=0
Set the current rasterizer state.
virtual void setBlendState(const BlendStateHandle handle, const float *constant=nullptr)=0
Set the current blend state.
virtual void setInputLayout(const InputLayoutHandle inputLayoutHandle)=0
Sets the current input layout.
virtual void setIndexBuffer(IndexBufferHandle bufferHandle, uint32_t stride=4, uint32_t offset=0)=0
Sets the current index buffer.
virtual void setDepthStencilState(const DepthStencilStateHandle handle)=0
Set the current depth stencil state.
virtual void setConstantBuffer(const StringView &name, const BufferHandle bufferHandle, const uint32_t offset=0, const uint32_t size=~0u)=0
Sets a constant buffer to be bound to the given name and slot.
virtual void setViewport(const float x, const float y, const float width, const float height)=0
Sets the current viewport to the given location and dimensions.
virtual void draw(PrimitiveType::EPrimitiveType primitiveType, const size_t startVertex, const size_t numVertexes)=0
Draws non-indexed, non-instanced primitives.
virtual void setSamplerState(const StringView &name, unsigned int unit, SamplerStateHandle samplerStateHandle)=0
Sets the sampler slot given by unit with the given name to contain the given sampler state.
virtual void setVertexBuffers(const VertexBufferHandle *vertexBufferHandles, const size_t count, const uint32_t *strides, const uint32_t *offsets)=0
Sets the current vertex buffers.
virtual void setEffect(EffectHandle handle)=0
Set the current effect.
virtual void setRenderTarget(const RenderTargetHandle handle, const DepthStencilHandle depthStencilHandle)=0
Sets the current render target and an associated depth stencil target.
@ TriangleList
List of triangles.
Definition: Common.h:116