4#include "EngineBuffers.h"
6#include "RenderTarget.h"
8#include "Services/Time.h"
9#include "Services/Random.h"
10#include "Systems/Core/LightSystem.h"
11#include "Systems/Core/FogSystem.h"
12#include "Systems/Core/EnvironmentSystem.h"
13#include "Tasks/RenderTask.h"
14#include "Systems/Core/CameraArraySystem.h"
16#include "Rendering/IBuffers.h"
17#include "Rendering/ICapabilities.h"
19void Cogs::Core::initializeEngineBuffers(IBuffers * buffers, ICapabilities* capabilites,
EngineBuffers & engineBuffers)
21 engineBuffers.viewBufferHandle = buffers->loadBuffer(
nullptr,
sizeof(
ViewBufferEntry) * 2, Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
22 engineBuffers.sceneBufferHandle = buffers->loadBuffer(
nullptr,
sizeof(
SceneParameters), Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
23 engineBuffers.lightBufferHandle = buffers->loadBuffer(
nullptr,
sizeof(
LightBuffer), Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
24 engineBuffers.objectBufferHandle = buffers->loadBuffer(
nullptr,
sizeof(
ObjectBuffer), Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
25 engineBuffers.shadowBufferHandle = buffers->loadBuffer(
nullptr,
sizeof(
ShadowBuffer), Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
27 engineBuffers.animationBuffer = buffers->loadBuffer(
nullptr,
sizeof(
AnimationBuffer), Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
29 buffers->annotate(engineBuffers.sceneBufferHandle,
"Engine:SceneParameters");
30 buffers->annotate(engineBuffers.lightBufferHandle,
"Engine:LightBuffer");
31 buffers->annotate(engineBuffers.objectBufferHandle,
"Engine:ObjectBuffer");
32 buffers->annotate(engineBuffers.shadowBufferHandle,
"Engine:ShadowBuffer");
33 buffers->annotate(engineBuffers.animationBuffer,
"Engine::AnimationBuffer");
35 if (capabilites && capabilites->getDeviceCapabilities().ConstantBufferRange) {
36 uint32_t alignment = capabilites->getDeviceCapabilities().ConstantBufferOffsetAlignment;
37 assert(alignment && ((alignment & (alignment - 1)) == 0) &&
"Constant buffer alignment is not a power of two");
39 engineBuffers.objectBatch.stride = uint32_t((
sizeof(
ObjectBuffer) + (alignment - 1))) & ~(alignment - 1);
40 engineBuffers.objectBatch.count = 128;
41 engineBuffers.objectBatch.bufferHandle = buffers->loadBuffer(
nullptr, engineBuffers.objectBatch.stride * engineBuffers.objectBatch.count, Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
42 buffers->annotate(engineBuffers.objectBatch.bufferHandle,
"Engine:ObjectBatchBuffer");
44 engineBuffers.objectBatch.count = 0;
56 if (passOptions.multiViews && viewportData->cameraArray) {
58 const CameraArrayData& camArrData = context->cameraArraySystem->getData(camArrComp);
61 assert(camArrData.viewBuffer.size() == passOptions.multiViews);
65 deviceContext->
updateBuffer(viewBufferHandle, camArrData.viewBuffer.data(),
sizeof(camArrData.viewBuffer[0]) * camArrData.viewBuffer.size());
76 auto& random = taskContext->context->
random;
78 updateViewBuffer(taskContext->context, viewBufferHandle, viewportData);
81 auto& sceneParameters = engineBuffers.sceneParameters;
83 static std::uniform_int_distribution<uint32_t> dist(0, 63);
84 glm::uvec4 offset(dist(random->mt), dist(random->mt), viewportData->blueNoiseOffset);
85 sceneParameters.blueNoiseOffset = offset;
87 sceneParameters.projectionMatrix = viewportData->projectionMatrix;
88 sceneParameters.viewMatrix = viewportData->viewMatrix;
89 sceneParameters.inverseViewMatrix = viewportData->inverseViewMatrix;
90 sceneParameters.worldToClipMatrix = sceneParameters.projectionMatrix * sceneParameters.viewMatrix;
91 sceneParameters.inverseProjectionMatrix = viewportData->inverseProjectionMatrix;
92 sceneParameters.viewFromViewportMatrix = viewportData->viewFromViewportMatrix;
93 sceneParameters.viewportFromViewMatrix = viewportData->viewportFromViewMatrix;
94 sceneParameters.viewportOrigin = viewportData->viewportOrigin;
95 sceneParameters.viewportSize = viewportData->viewportSize;
96 sceneParameters.viewportSizeRcp = 1.0f / viewportData->viewportSize;
99 if (viewportData->cameraArray && !passOptions.multiViews) {
101 const CameraArrayData& camArrData = taskContext->context->cameraArraySystem->getData(camArrComp);
102 const ViewBufferEntry &entry = camArrData.viewBuffer[renderTarget->depthLayerIndex];
103 sceneParameters.projectionMatrix = entry.clipFromView;
104 sceneParameters.worldToClipMatrix = entry.clipFromWorld;
105 sceneParameters.viewMatrix = entry.viewFromWorld;
106 sceneParameters.inverseProjectionMatrix = entry.viewFromClip;
107 sceneParameters.inverseViewMatrix = entry.worldFromView;
110 glm::dvec3 origin = taskContext->context->transformSystem->
getOrigin();
111 glm::vec3 originHigh = glm::vec3(origin);
112 glm::vec3 originLow = glm::vec3(origin - glm::dvec3(originHigh));
113 sceneParameters.originHigh = glm::vec4(originHigh, 0.f);
114 sceneParameters.originLow = glm::vec4(originLow, 0.f);
117 const bool reverseDepth = taskContext->context->
variables->get(
"renderer.reverseDepth",
false);
118 float depthClamp = viewportData->depthClamp;
120 depthClamp = 1.0f - depthClamp;
123 sceneParameters.shadowDepthClamp = 2.f * depthClamp - 1.f;
126 sceneParameters.shadowDepthClamp = depthClamp;
129 sceneParameters.animationTime =
static_cast<float>(taskContext->context->
time->getAnimationTime());
130 sceneParameters.exposure = viewportData->exposure;
132 const float aspect = viewportData->viewportSize.y == 0 ? 1.0f : viewportData->viewportSize.x / viewportData->viewportSize.y;
133 sceneParameters.projectionParameters.y = 2.0f * viewportData->nearDistance * glm::tan(0.5f * viewportData->fieldOfView);
134 sceneParameters.projectionParameters.x = aspect * sceneParameters.projectionParameters.y;
135 sceneParameters.projectionParameters.z = aspect;
136 sceneParameters.projectionParameters.w = viewportData->fieldOfView;
138 unsigned sceneFlags = 0;
139 if ((renderTarget == taskContext->defaultRenderTarget && taskContext->renderer->
getSettings().defaultRenderTargetExpectsSRGB) || renderTarget->expectsSRGB) {
140 sceneFlags |= COGS_SCENEFLAGS_OUTPUT_SRGB;
143 sceneFlags |= COGS_SCENEFLAGS_SUBMERGED;
145 sceneParameters.sceneFlags = sceneFlags;
146 sceneParameters.clientFlags = viewportData->clientFlags;
147 if (taskContext->context->environmentSystem) {
148 auto* envComp = taskContext->context->environmentSystem->getGlobalEnvironment();
150 auto& envData = taskContext->context->environmentSystem->getData(envComp);
151 sceneParameters.numEnvironmentIrradianceMips =
static_cast<float>(envData.irradianceLods);
152 sceneParameters.numEnvironmentRadianceMips =
static_cast<float>(envData.radianceLods);
156 static const std::array<glm::vec4, 6> noClipEquations = {
157 glm::vec4(0.f, 0.f, 0.f, 1.f), glm::vec4(0.f, 0.f, 0.f, 1.f),
158 glm::vec4(0.f, 0.f, 0.f, 1.f), glm::vec4(0.f, 0.f, 0.f, 1.f),
159 glm::vec4(0.f, 0.f, 0.f, 1.f), glm::vec4(0.f, 0.f, 0.f, 1.f)
161 std::memcpy(&sceneParameters.clippingPlanes, clipEquations ? clipEquations : &noClipEquations,
sizeof(std::array<glm::vec4, 6>));
163 taskContext->cameraData = viewportData;
178 LightSystem& lightSystem = *taskContext->context->lightSystem;
179 LightBuffer& lightParameters = engineBuffers.lightParameters;
180 lightParameters = {};
181 lightParameters.eyePosition = viewportData->inverseViewMatrix[3];
183 size_t numActiveLights = activeLights.lights.size();
184 for (
size_t i = 0; i < numActiveLights; i++) {
186 const LightData& lightData = lightSystem.getData(light);
187 lightParameters.lightPositions[i] = lightData.lightPosition;
188 lightParameters.lightDirections[i] = lightData.lightDirection;
189 lightParameters.lightColorIntensity[i] = lightData.lightColor;
190 lightParameters.lightColorIntensity[i].a = (light->
lightingLayer & viewportData->lightingMask) == 0 ? 0.f : light->
intensity;
191 lightParameters.lightParameters[i].r = lightData.shadowIntensityOffset;
192 lightParameters.lightParameters[i].a = light->
range;
194 lightParameters.numLights[0] =
static_cast<uint32_t
>(numActiveLights);
195 lightParameters.ambientColor = taskContext->renderer->
getSettings().ambientColor;
196 lightParameters.ambientIntensity = taskContext->renderer->
getSettings().ambientIntensity;
198 const FogComponent* globalFog = taskContext->context->fogSystem->getGlobalFog();
199 if (globalFog && globalFog->
enabled) {
200 lightParameters.fogEnabled = 1;
201 lightParameters.fogColor = globalFog->
color;
202 lightParameters.fogDistance = globalFog->
distance;
203 lightParameters.fogAmount = globalFog->
amount;
206 lightParameters.fogEnabled = 0;
210 lightParameters.seaFlags = 0;
211 lightParameters.flags = 0;
212 lightParameters.environmentBrightness = 1.0f;
213 lightParameters.skyMultiplier = 1.0f;
214 if (environmentComponent) {
215 lightParameters.environmentBrightness = environmentComponent->brightness;
216 lightParameters.skyMultiplier = environmentComponent->skyMultiplier;
217 lightParameters.flags = ((
HandleIsValid(environmentComponent->skyDome) ? 1 : 0) |
220 (
HandleIsValid(environmentComponent->subseaRadiance) ? 8 : 0) |
221 (
HandleIsValid(environmentComponent->ambientIrradiance) ? 16 : 0) |
224 if (environmentComponent->subseaSupport) {
225 lightParameters.seaFlags = environmentComponent->isSubmerged(viewportData);
226 if (lightParameters.seaFlags) {
227 lightParameters.fogEnabled = 2 + 4;
228 lightParameters.fogColor = glm::vec4(1, 0, 0, 1);
229 lightParameters.fogDistance = environmentComponent->subseaTurbidityDistance;
230 lightParameters.fogAmount = environmentComponent->subseaTurbidityAmount;
236 const glm::vec4 softShadowJitter[] = {
237 { -2.5f, -2.5f, 0.0f, 0.0f },
238 { -2.5f, -1.5f, -1.5f, 0.0f },
239 { -2.5f, -0.5f, 0.0f, -1.5f },
240 { -2.5f, 0.5f, 0.0f, 1.5f },
241 { -2.5f, 1.5f, 1.5f, 0.0f },
242 { -2.5f, 2.5f, -1.5f, -1.5f },
243 { -1.5f, -2.5f, -1.5f, 1.5f },
244 { -1.5f, -1.5f, 1.5f, -1.5f },
245 { -1.5f, -0.5f, 1.5f, 1.5f },
246 { -1.5f, 0.5f, 0.0f, 0.0f },
247 { -1.5f, 1.5f, 0.0f, 0.0f },
248 { -1.5f, 2.5f, 0.0f, 0.0f },
249 { -0.5f, -2.5f, 0.0f, 0.0f },
250 { -0.5f, -1.5f, 0.0f, 0.0f },
251 { -0.5f, -0.5f, 0.0f, 0.0f },
252 { -0.5f, 0.5f, 0.0f, 0.0f },
253 { -0.5f, 1.5f, 0.0f, 0.0f },
254 { -0.5f, 2.5f, 0.0f, 0.0f },
255 { 0.5f, -2.5f, 0.0f, 0.0f },
256 { 0.5f, -1.5f, 0.0f, 0.0f },
257 { 0.5f, -0.5f, 0.0f, 0.0f },
258 { 0.5f, 0.5f, 0.0f, 0.0f },
259 { 0.5f, 1.5f, 0.0f, 0.0f },
260 { 0.5f, 2.5f, 0.0f, 0.0f },
261 { 1.5f, -2.5f, 0.0f, 0.0f },
262 { 1.5f, -1.5f, 0.0f, 0.0f },
263 { 1.5f, -0.5f, 0.0f, 0.0f },
264 { 1.5f, 0.5f, 0.0f, 0.0f },
265 { 1.5f, 1.5f, 0.0f, 0.0f },
266 { 1.5f, 2.5f, 0.0f, 0.0f },
267 { 2.5f, -2.5f, 0.0f, 0.0f },
268 { 2.5f, -1.5f, 0.0f, 0.0f },
269 { 2.5f, -0.5f, 0.0f, 0.0f },
270 { 2.5f, 0.5f, 0.0f, 0.0f },
271 { 2.5f, 1.5f, 0.0f, 0.0f },
272 { 2.5f, 2.5f, 0.0f, 0.0f }
279 LightSystem& lightSystem = *taskContext->context->lightSystem;
281 ShadowBuffer& shadowParameters = engineBuffers.shadowBuffer;
282 shadowParameters = {};
283 static_assert(
sizeof(softShadowJitter) ==
sizeof(ShadowBuffer::softShadowJitter));
284 std::memcpy(&shadowParameters.softShadowJitter, &softShadowJitter,
sizeof(ShadowBuffer::softShadowJitter));
285 const bool reverseDepth = taskContext->context->
variables->get(
"renderer.reverseDepth",
false);
286 glm::mat4 viewportTransform;
287 switch (taskContext->device->
getType())
294 viewportTransform = glm::mat4(0.5f, 0.0f, 0.0f, 0.0f,
295 0.0f, 0.5f, 0.0f, 0.0f,
296 0.0f, 0.0f, 0.5f, 0.0f,
297 0.5f, 0.5f, 0.5f, 1.0f);
301 viewportTransform = glm::mat4(0.5f, 0.0f, 0.0f, 0.0f,
302 0.0f, 0.5f, 0.0f, 0.0f,
303 0.0f, 0.0f, 1.0f, 0.0f,
304 0.5f, 0.5f, 0.0f, 1.0f);
310 viewportTransform = glm::mat4(0.5f, 0.0f, 0.0f, 0.0f,
311 0.0f, -0.5f, 0.0f, 0.0f,
312 0.0f, 0.0f, 1.0f, 0.0f,
313 0.5f, 0.5f, 0.0f, 1.0f);
318 for (
size_t i = 0; i < activeLights.numDirectionalShadowLights; i++) {
320 const LightData& lightData = lightSystem.getData(light);
321 shadowParameters.cascadeOffsets[i].x = lightData.arrayOffset;
322 ShadowData& shadow = shadowParameters.shadowData[i];
323 shadow.shadowsEnabled = lightData.enabled && lightData.castShadows;
324 shadow.texelSize = 1.f / lightData.textureSize;
325 shadow.cascadeLine = lightData.cascadeLine;
326 shadow.nearSplits = *
reinterpret_cast<const glm::vec4*
>(lightData.nearDepths);
327 shadow.farSplits = *
reinterpret_cast<const glm::vec4*
>(lightData.farDepths);
329 shadow.numCascades = lightData.numViewports;
330 for (
size_t k = 0; k < lightData.numViewports; k++) {
331 shadow.lightMatrix[k] = viewportTransform * lightData.lightCameraData[k].viewProjection;
335 for (
size_t i = 0; i < activeLights.numPointShadowLights; i++) {
336 size_t o = activeLights.numDirectionalShadowLights + activeLights.numDirectionalLights + i;
338 const LightData& lightData = lightSystem.getData(light);
340 shadowParameters.cascadeOffsets[o].x = lightData.arrayOffset / 6;
342 ShadowData& shadow = shadowParameters.shadowData[o];
343 shadow.shadowsEnabled = lightData.enabled && lightData.castShadows;
344 shadow.texelSize = 1.f / lightData.textureSize;
345 shadow.cascadeLine = lightData.cascadeLine;
346 shadow.nearSplits = *
reinterpret_cast<const glm::vec4*
>(lightData.nearDepths);
347 shadow.farSplits = *
reinterpret_cast<const glm::vec4*
>(lightData.farDepths);
349 shadow.numCascades = lightData.numViewports;
350 for (
size_t k = 0; k < lightData.numViewports; k++) {
351 shadow.lightMatrix[k] = viewportTransform * lightData.lightCameraData[k].viewProjection;
360 auto device = taskContext->renderer->
getDevice();
365 if (!viewportData)
return;
367 updateViewportBuffer(taskContext, engineBuffers.sceneBufferHandle, engineBuffers.viewBufferHandle, renderTarget, viewportData, clipEquations);
369 updateLightBuffer(taskContext, viewportData);
371 deviceContext->
updateBuffer(engineBuffers.lightBufferHandle, &engineBuffers.lightParameters,
sizeof(
LightBuffer));
374 updateShadowBuffer(taskContext);
Multi-view: Render a set of related views into array texture layers.
A Context instance contains all the services, systems and runtime components needed to use Cogs.
class IRenderer * renderer
Renderer.
std::unique_ptr< class Random > random
Random Number service instance.
std::unique_ptr< class Variables > variables
Variables service instance.
std::unique_ptr< class Time > time
Time service instance.
Contains data to describe fog.
glm::vec4 color
Fog color.
float amount
Amount of fog to blend in.
float distance
Distance at which the fog is at its most dense.
bool enabled
If the fog should be enabled or disabled.
virtual IGraphicsDevice * getDevice()=0
Get the graphics device used by the renderer.
Defines a single light source and its behavior.
float intensity
Intensity of the light source.
float shadowSampleBias
Constant term shadow map sampling bias.
LightingLayers lightingLayer
The lighting layer the light belongs to.
float range
Falloff range.
Holds all LightComponent instances in the system.
ActiveLights & getActiveLights() override
Get the reference to the ActiveLights structure.
EngineBuffers & getEngineBuffers() override
Get the reference to the EngineBuffers structure.
IGraphicsDevice * getDevice() override
Get the graphics device used by the renderer.
const RenderSettings & getSettings() const override
Get the settings of the renderer.
Represents a graphics device used to manage graphics resources and issue drawing commands.
virtual ICapabilities * getCapabilities()=0
Get a pointer to the capability management interface used to query the graphics device capability fla...
virtual IContext * getImmediateContext()=0
Get a pointer to the immediate context used to issue commands to the graphics device.
virtual GraphicsDeviceType getType() const
Get the type of the graphics device.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
bool HandleIsValid(const ResourceHandle_t< T > &handle)
Check if the given resource is valid, that is not equal to NoHandle or InvalidHandle.
@ OpenGLES30
Graphics device using the OpenGLES 3.0 API.
@ OpenGL20
Graphics device using OpenGL, supporting at least OpenGL 2.0.
ComponentType * resolveComponent() const
Contains data describing a Camera instance and its derived data structured such as matrix data and vi...
Defines calculated light data.
bool DepthNegativeOneToOne
If true, min z depth=-1 otherwise it is min z depth = 0 (max z depth = 1).
virtual const GraphicsDeviceCapabilities & getDeviceCapabilities() const
Gets the device capabilities in a structure.
Represents a graphics device context which can receive rendering commands.
virtual void updateBuffer(BufferHandle bufferHandle, const void *data, size_t size)=0
Replace contents of buffer with new data.