1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "render_node_default_camera_controller.h"
17
18 #if (CORE3D_VALIDATION_ENABLED == 1)
19 #include <cinttypes>
20 #include <string>
21 #endif
22
23 #include <3d/render/default_material_constants.h>
24 #include <3d/render/intf_render_data_store_default_camera.h>
25 #include <3d/render/intf_render_data_store_default_light.h>
26 #include <3d/render/intf_render_data_store_default_material.h>
27 #include <3d/render/intf_render_data_store_default_scene.h>
28 #include <base/containers/string.h>
29 #include <base/math/matrix_util.h>
30 #include <core/log.h>
31 #include <render/datastore/intf_render_data_store.h>
32 #include <render/datastore/intf_render_data_store_manager.h>
33 #include <render/datastore/intf_render_data_store_pod.h>
34 #include <render/device/intf_gpu_resource_manager.h>
35 #include <render/nodecontext/intf_render_node_context_manager.h>
36 #include <render/nodecontext/intf_render_node_graph_share_manager.h>
37 #include <render/nodecontext/intf_render_node_parser_util.h>
38 #include <render/nodecontext/intf_render_node_util.h>
39 #include <render/render_data_structures.h>
40
41 // NOTE: do not include in header
42 #include "render_light_helper.h"
43
44 namespace {
45 #include <render/shaders/common/render_post_process_common.h>
46 } // namespace
47
48 CORE3D_BEGIN_NAMESPACE()
49 using namespace BASE_NS;
50 using namespace RENDER_NS;
51
52 namespace {
53 constexpr float CUBE_MAP_LOD_COEFF { 8.0f };
54 constexpr string_view POD_DATA_STORE_NAME { "RenderDataStorePod" };
55
ValidateRenderCamera(RenderCamera & camera)56 void ValidateRenderCamera(RenderCamera& camera)
57 {
58 if (camera.renderPipelineType == RenderCamera::RenderPipelineType::DEFERRED) {
59 if (camera.flags & RenderCamera::CameraFlagBits::CAMERA_FLAG_MSAA_BIT) {
60 camera.flags = camera.flags & (~RenderCamera::CameraFlagBits::CAMERA_FLAG_MSAA_BIT);
61 #if (CORE3D_VALIDATION_ENABLED == 1)
62 CORE_LOG_ONCE_I("valid_r_c_" + to_string(camera.id),
63 "MSAA flag with deferred pipeline dropped (cam id %" PRIu64 ")", camera.id);
64 #endif
65 }
66 }
67 #if (CORE3D_VALIDATION_ENABLED == 1)
68 if (camera.id == RenderSceneDataConstants::INVALID_ID) {
69 CORE_LOG_ONCE_I("valid_r_c_id" + to_string(camera.id), "Invalid camera id (cam id %" PRIu64 ")", camera.id);
70 }
71 #endif
72 }
73
GetValidColorFormat(const IRenderNodeGpuResourceManager & gpuResourceMgr,const Format format)74 Format GetValidColorFormat(const IRenderNodeGpuResourceManager& gpuResourceMgr, const Format format)
75 {
76 Format outFormat = format;
77 const auto formatProperties = gpuResourceMgr.GetFormatProperties(format);
78 if (((formatProperties.optimalTilingFeatures & CORE_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) == 0) ||
79 ((formatProperties.optimalTilingFeatures & CORE_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)) {
80 outFormat = Format::BASE_FORMAT_R8G8B8A8_SRGB;
81 #if (CORE3D_VALIDATION_ENABLED == 1)
82 CORE_LOG_W("CORE_VALIDATION: not supported camera color format %u, using BASE_FORMAT_R8G8B8A8_SRGB", outFormat);
83 #endif
84 }
85 return outFormat;
86 }
87
GetValidDepthFormat(const IRenderNodeGpuResourceManager & gpuResourceMgr,const Format format)88 Format GetValidDepthFormat(const IRenderNodeGpuResourceManager& gpuResourceMgr, const Format format)
89 {
90 Format outFormat = format;
91 const auto formatProperties = gpuResourceMgr.GetFormatProperties(format);
92 if ((formatProperties.optimalTilingFeatures & CORE_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0) {
93 outFormat = Format::BASE_FORMAT_D32_SFLOAT;
94 #if (CORE3D_VALIDATION_ENABLED == 1)
95 CORE_LOG_W("CORE_VALIDATION: not supported camera depth format %u, using BASE_FORMAT_D32_SFLOAT", outFormat);
96 #endif
97 }
98 return outFormat;
99 }
100
101 constexpr GpuImageDesc OUTPUT_DEFAULT_DESC { CORE_IMAGE_TYPE_2D, CORE_IMAGE_VIEW_TYPE_2D, BASE_FORMAT_R8G8B8A8_SRGB,
102 CORE_IMAGE_TILING_OPTIMAL,
103 CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | CORE_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | CORE_IMAGE_USAGE_SAMPLED_BIT,
104 CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0U, CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, 1U, 1U, 1U, 1U, 1U,
105 CORE_SAMPLE_COUNT_1_BIT, ComponentMapping {} };
106 constexpr GpuImageDesc COLOR_DEFAULT_DESC { CORE_IMAGE_TYPE_2D, CORE_IMAGE_VIEW_TYPE_2D,
107 BASE_FORMAT_R16G16B16A16_SFLOAT, CORE_IMAGE_TILING_OPTIMAL,
108 CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | CORE_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | CORE_IMAGE_USAGE_SAMPLED_BIT,
109 CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0U, CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, 1U, 1U, 1U, 1U, 1U,
110 CORE_SAMPLE_COUNT_1_BIT, ComponentMapping {} };
111 constexpr GpuImageDesc VELOCITY_NORMAL_DEFAULT_DESC { CORE_IMAGE_TYPE_2D, CORE_IMAGE_VIEW_TYPE_2D,
112 BASE_FORMAT_R16G16B16A16_SFLOAT, CORE_IMAGE_TILING_OPTIMAL,
113 CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | CORE_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
114 CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, 0U,
115 CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, 1U, 1U, 1U, 1U, 1U, CORE_SAMPLE_COUNT_1_BIT, ComponentMapping {} };
116 constexpr GpuImageDesc HISTORY_DEFAULT_DESC { CORE_IMAGE_TYPE_2D, CORE_IMAGE_VIEW_TYPE_2D,
117 BASE_FORMAT_B10G11R11_UFLOAT_PACK32, CORE_IMAGE_TILING_OPTIMAL,
118 CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | CORE_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | CORE_IMAGE_USAGE_SAMPLED_BIT,
119 CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0U, CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, 1U, 1U, 1U, 1U, 1U,
120 CORE_SAMPLE_COUNT_1_BIT, ComponentMapping {} };
121 constexpr GpuImageDesc BASE_COLOR_DEFAULT_DESC { CORE_IMAGE_TYPE_2D, CORE_IMAGE_VIEW_TYPE_2D, BASE_FORMAT_R8G8B8A8_SRGB,
122 CORE_IMAGE_TILING_OPTIMAL,
123 CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | CORE_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
124 CORE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
125 CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, 0U,
126 CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, 1U, 1U, 1U, 1U, 1U, CORE_SAMPLE_COUNT_1_BIT, ComponentMapping {} };
127 constexpr GpuImageDesc MATERIAL_DEFAULT_DESC { CORE_IMAGE_TYPE_2D, CORE_IMAGE_VIEW_TYPE_2D, BASE_FORMAT_R8G8B8A8_UNORM,
128 CORE_IMAGE_TILING_OPTIMAL,
129 CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | CORE_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
130 CORE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
131 CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, 0U,
132 CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, 1U, 1U, 1U, 1U, 1U, CORE_SAMPLE_COUNT_1_BIT, ComponentMapping {} };
133
134 constexpr GpuImageDesc DEPTH_DEFAULT_DESC { CORE_IMAGE_TYPE_2D, CORE_IMAGE_VIEW_TYPE_2D, BASE_FORMAT_D32_SFLOAT,
135 CORE_IMAGE_TILING_OPTIMAL,
136 CORE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | CORE_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
137 CORE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
138 CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, 0U,
139 CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, 1U, 1U, 1U, 1U, 1U, CORE_SAMPLE_COUNT_1_BIT, ComponentMapping {} };
140
141 constexpr GpuImageDesc CUBEMAP_DEFAULT_DESC { CORE_IMAGE_TYPE_2D, CORE_IMAGE_VIEW_TYPE_CUBE,
142 BASE_FORMAT_B10G11R11_UFLOAT_PACK32, CORE_IMAGE_TILING_OPTIMAL,
143 CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | CORE_IMAGE_USAGE_SAMPLED_BIT, CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
144 CORE_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, 256U, 256U, 1U, 9U, 6U,
145 CORE_SAMPLE_COUNT_1_BIT, ComponentMapping {} };
146
ValidateColorDesc(const IRenderNodeGpuResourceManager & gpuResourceMgr,const GpuImageDesc & input,const bool bilinearSampling,GpuImageDesc & desc)147 void ValidateColorDesc(const IRenderNodeGpuResourceManager& gpuResourceMgr, const GpuImageDesc& input,
148 const bool bilinearSampling, GpuImageDesc& desc)
149 {
150 desc.imageType = input.imageType;
151 desc.imageViewType = input.imageViewType;
152 desc.imageTiling = input.imageTiling;
153 if (desc.format == BASE_FORMAT_UNDEFINED) {
154 desc.format = input.format;
155 }
156 if (desc.usageFlags == 0) {
157 desc.usageFlags = input.usageFlags;
158 }
159 if (desc.memoryPropertyFlags == 0) {
160 desc.memoryPropertyFlags = input.memoryPropertyFlags;
161 }
162 if (desc.createFlags == 0) {
163 desc.createFlags = input.createFlags;
164 }
165 if (desc.engineCreationFlags == 0) {
166 desc.engineCreationFlags = input.engineCreationFlags;
167 }
168 desc.width = Math::max(desc.width, input.width);
169 desc.height = Math::max(desc.height, input.height);
170 desc.depth = Math::max(desc.depth, input.depth);
171
172 desc.mipCount = Math::max(desc.mipCount, input.mipCount);
173 desc.layerCount = Math::max(desc.layerCount, input.layerCount);
174
175 if ((desc.layerCount == 1U) && (desc.imageViewType == CORE_IMAGE_VIEW_TYPE_2D_ARRAY)) {
176 desc.imageViewType = CORE_IMAGE_VIEW_TYPE_2D;
177 } else if ((desc.layerCount > 1U) && (desc.imageViewType == CORE_IMAGE_VIEW_TYPE_2D)) {
178 desc.imageViewType = CORE_IMAGE_VIEW_TYPE_2D_ARRAY;
179 }
180 if (desc.sampleCountFlags == 0) {
181 desc.sampleCountFlags = CORE_SAMPLE_COUNT_1_BIT;
182 }
183
184 if (bilinearSampling) {
185 desc.format = GetValidColorFormat(gpuResourceMgr, desc.format);
186 }
187 }
188
GetImageViewType(const uint32_t layerCount,const ImageViewType imageViewType)189 ImageViewType GetImageViewType(const uint32_t layerCount, const ImageViewType imageViewType)
190 {
191 if ((layerCount == 1U) && (imageViewType == CORE_IMAGE_VIEW_TYPE_2D_ARRAY)) {
192 return CORE_IMAGE_VIEW_TYPE_2D;
193 } else if ((layerCount > 1U) && (imageViewType == CORE_IMAGE_VIEW_TYPE_2D)) {
194 return CORE_IMAGE_VIEW_TYPE_2D_ARRAY;
195 }
196 return imageViewType;
197 }
198
ValidateDepthDesc(const IRenderNodeGpuResourceManager & gpuResourceMgr,const GpuImageDesc & input,GpuImageDesc & desc)199 void ValidateDepthDesc(
200 const IRenderNodeGpuResourceManager& gpuResourceMgr, const GpuImageDesc& input, GpuImageDesc& desc)
201 {
202 desc.imageType = input.imageType;
203 desc.imageViewType = input.imageViewType;
204 desc.imageTiling = input.imageTiling;
205 if (desc.format == BASE_FORMAT_UNDEFINED) {
206 desc.format = input.format;
207 }
208 if (desc.usageFlags == 0) {
209 desc.usageFlags = input.usageFlags;
210 }
211 if (desc.memoryPropertyFlags == 0) {
212 desc.memoryPropertyFlags = input.memoryPropertyFlags;
213 }
214 if (desc.createFlags == 0) {
215 desc.createFlags = input.createFlags;
216 }
217 if (desc.engineCreationFlags == 0) {
218 desc.engineCreationFlags = input.engineCreationFlags;
219 }
220 desc.width = Math::max(desc.width, input.width);
221 desc.height = Math::max(desc.height, input.height);
222 desc.depth = Math::max(desc.depth, input.depth);
223
224 desc.mipCount = Math::max(desc.mipCount, input.mipCount);
225 desc.layerCount = Math::max(desc.layerCount, input.layerCount);
226
227 if ((desc.layerCount == 1U) && (desc.imageViewType == CORE_IMAGE_VIEW_TYPE_2D_ARRAY)) {
228 desc.imageViewType = CORE_IMAGE_VIEW_TYPE_2D;
229 } else if ((desc.layerCount > 1U) && (desc.imageViewType == CORE_IMAGE_VIEW_TYPE_2D)) {
230 desc.imageViewType = CORE_IMAGE_VIEW_TYPE_2D_ARRAY;
231 }
232 if (desc.sampleCountFlags == 0) {
233 desc.sampleCountFlags = CORE_SAMPLE_COUNT_1_BIT;
234 }
235
236 desc.format = GetValidDepthFormat(gpuResourceMgr, desc.format);
237 }
238
239 struct CreatedTargetHandles {
240 RenderHandle color;
241 RenderHandle depth;
242 RenderHandle colorResolve;
243 RenderHandle colorMsaa;
244 RenderHandle depthMsaa;
245 RenderHandle baseColor;
246 RenderHandle velNor;
247 RenderHandle material;
248 };
249
FillCreatedTargets(const RenderNodeDefaultCameraController::CreatedTargets & targets)250 CreatedTargetHandles FillCreatedTargets(const RenderNodeDefaultCameraController::CreatedTargets& targets)
251 {
252 return CreatedTargetHandles {
253 targets.outputColor.GetHandle(),
254 targets.depth.GetHandle(),
255 targets.colorResolve.GetHandle(),
256 targets.colorMsaa.GetHandle(),
257 targets.depthMsaa.GetHandle(),
258 targets.baseColor.GetHandle(),
259 targets.velocityNormal.GetHandle(),
260 targets.material.GetHandle(),
261 };
262 }
263
GetPacked64(const uint64_t value)264 inline constexpr Math::UVec2 GetPacked64(const uint64_t value)
265 {
266 return { static_cast<uint32_t>(value >> 32) & 0xFFFFffff, static_cast<uint32_t>(value & 0xFFFFffff) };
267 }
268
CreateBaseColorTarget(IRenderNodeGpuResourceManager & gpuResourceMgr,const RenderCamera & camera,const string_view us,const string_view customCamRngId,const RenderNodeDefaultCameraController::CameraResourceSetup & cameraResourceSetup,RenderNodeDefaultCameraController::CreatedTargets & targets)269 void CreateBaseColorTarget(IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderCamera& camera,
270 const string_view us, const string_view customCamRngId,
271 const RenderNodeDefaultCameraController::CameraResourceSetup& cameraResourceSetup,
272 RenderNodeDefaultCameraController::CreatedTargets& targets)
273 {
274 #if (CORE3D_VALIDATION_ENABLED == 1)
275 CORE_LOG_I("CORE3D_VALIDATION: creating camera base color target %s", customCamRngId.data());
276 #endif
277 GpuImageDesc desc = cameraResourceSetup.inputImageDescs.output;
278 desc.width = camera.renderResolution.x;
279 desc.height = camera.renderResolution.y;
280 desc.imageViewType = GetImageViewType(desc.layerCount, desc.imageViewType);
281 targets.outputColor =
282 gpuResourceMgr.Create(us + DefaultMaterialCameraConstants::CAMERA_COLOR_PREFIX_NAME + customCamRngId, desc);
283 targets.imageDescs.output = desc;
284 }
285
CreateVelocityTarget(IRenderNodeGpuResourceManager & gpuResourceMgr,const RenderCamera & camera,const GpuImageDesc & targetDesc,const string_view us,const string_view customCameraRngId,const RenderNodeDefaultCameraController::CameraResourceSetup & cameraResourceSetup,RenderNodeDefaultCameraController::CreatedTargets & createdTargets)286 void CreateVelocityTarget(IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderCamera& camera,
287 const GpuImageDesc& targetDesc, const string_view us, const string_view customCameraRngId,
288 const RenderNodeDefaultCameraController::CameraResourceSetup& cameraResourceSetup,
289 RenderNodeDefaultCameraController::CreatedTargets& createdTargets)
290 {
291 const bool createVelocity = (camera.renderPipelineType == RenderCamera::RenderPipelineType::DEFERRED) ||
292 (camera.renderPipelineType == RenderCamera::RenderPipelineType::FORWARD);
293 if (createVelocity) {
294 GpuImageDesc desc = cameraResourceSetup.inputImageDescs.velocityNormal;
295 desc.width = targetDesc.width;
296 desc.height = targetDesc.height;
297 desc.layerCount = targetDesc.layerCount;
298 desc.imageViewType = GetImageViewType(desc.layerCount, desc.imageViewType);
299 // patch even RNG given flags
300 if (camera.flags & RenderCamera::CAMERA_FLAG_OUTPUT_VELOCITY_NORMAL_BIT) {
301 desc.usageFlags |= CORE_IMAGE_USAGE_SAMPLED_BIT;
302 // we cannot have transient and lazy allocation
303 desc.usageFlags &= (~CORE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT);
304 desc.memoryPropertyFlags &= (~CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT);
305 }
306 #if (CORE3D_VALIDATION_ENABLED == 1)
307 createdTargets.velocityNormal = gpuResourceMgr.Create(
308 us + DefaultMaterialCameraConstants::CAMERA_COLOR_PREFIX_NAME + "VEL_NOR" + customCameraRngId, desc);
309 #else
310 createdTargets.velocityNormal = gpuResourceMgr.Create(createdTargets.velocityNormal, desc);
311 #endif
312 // store
313 createdTargets.imageDescs.velocityNormal = desc;
314 }
315 }
316
CreateDeferredTargets(IRenderNodeGpuResourceManager & gpuResourceMgr,const RenderCamera & camera,const GpuImageDesc & targetDesc,const string_view us,const string_view customCameraRngId,const RenderNodeDefaultCameraController::CameraResourceSetup & cameraResourceSetup,RenderNodeDefaultCameraController::CreatedTargets & createdTargets)317 void CreateDeferredTargets(IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderCamera& camera,
318 const GpuImageDesc& targetDesc, const string_view us, const string_view customCameraRngId,
319 const RenderNodeDefaultCameraController::CameraResourceSetup& cameraResourceSetup,
320 RenderNodeDefaultCameraController::CreatedTargets& createdTargets)
321 {
322 if (camera.renderPipelineType == RenderCamera::RenderPipelineType::DEFERRED) {
323 GpuImageDesc desc = cameraResourceSetup.inputImageDescs.baseColor;
324 desc.width = targetDesc.width;
325 desc.height = targetDesc.height;
326 desc.layerCount = targetDesc.layerCount;
327 desc.imageViewType = GetImageViewType(desc.layerCount, desc.imageViewType);
328 #if (CORE3D_VALIDATION_ENABLED == 1)
329 createdTargets.baseColor = gpuResourceMgr.Create(
330 us + DefaultMaterialCameraConstants::CAMERA_COLOR_PREFIX_NAME + "BC_" + customCameraRngId, desc);
331 #else
332 createdTargets.baseColor = gpuResourceMgr.Create(createdTargets.baseColor, desc);
333 #endif
334 // store
335 createdTargets.imageDescs.baseColor = desc;
336
337 // create material
338 desc = cameraResourceSetup.inputImageDescs.material;
339 desc.width = targetDesc.width;
340 desc.height = targetDesc.height;
341 desc.layerCount = targetDesc.layerCount;
342 #if (CORE3D_VALIDATION_ENABLED == 1)
343 createdTargets.material = gpuResourceMgr.Create(
344 us + DefaultMaterialCameraConstants::CAMERA_COLOR_PREFIX_NAME + "MAT_" + customCameraRngId, desc);
345 #else
346 createdTargets.material = gpuResourceMgr.Create(createdTargets.material, desc);
347 #endif
348 // store
349 createdTargets.imageDescs.material = desc;
350 }
351 }
352
CreateHistoryTargets(IRenderNodeGpuResourceManager & gpuResourceMgr,const RenderCamera & camera,const GpuImageDesc & targetDesc,const string_view us,const string_view customCameraRngId,const RenderNodeDefaultCameraController::CameraResourceSetup & cameraResourceSetup,RenderNodeDefaultCameraController::CreatedTargets & createdTargets)353 void CreateHistoryTargets(IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderCamera& camera,
354 const GpuImageDesc& targetDesc, const string_view us, const string_view customCameraRngId,
355 const RenderNodeDefaultCameraController::CameraResourceSetup& cameraResourceSetup,
356 RenderNodeDefaultCameraController::CreatedTargets& createdTargets)
357 {
358 if (camera.flags & RenderCamera::CameraFlagBits::CAMERA_FLAG_HISTORY_BIT) {
359 GpuImageDesc desc = cameraResourceSetup.inputImageDescs.history;
360 desc.width = targetDesc.width;
361 desc.height = targetDesc.height;
362 desc.layerCount = targetDesc.layerCount;
363 desc.imageViewType = GetImageViewType(desc.layerCount, desc.imageViewType);
364 #if (CORE3D_VALIDATION_ENABLED == 1)
365 createdTargets.history[0u] = gpuResourceMgr.Create(
366 us + DefaultMaterialCameraConstants::CAMERA_COLOR_PREFIX_NAME + "HIS0_" + customCameraRngId, desc);
367 createdTargets.history[1u] = gpuResourceMgr.Create(
368 us + DefaultMaterialCameraConstants::CAMERA_COLOR_PREFIX_NAME + "HIS1_" + customCameraRngId, desc);
369 #else
370 createdTargets.history[0u] = gpuResourceMgr.Create(createdTargets.history[0u], desc);
371 createdTargets.history[1u] = gpuResourceMgr.Create(createdTargets.history[1u], desc);
372 #endif
373
374 // store
375 createdTargets.imageDescs.history = desc;
376 }
377 }
378
CreateColorTargets(IRenderNodeGpuResourceManager & gpuResourceMgr,const RenderCamera & camera,const GpuImageDesc & targetDesc,const string_view us,const string_view customCamRngId,const RenderNodeDefaultCameraController::CameraResourceSetup & cameraResourceSetup,RenderNodeDefaultCameraController::CreatedTargets & createdTargets)379 void CreateColorTargets(IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderCamera& camera,
380 const GpuImageDesc& targetDesc, const string_view us, const string_view customCamRngId,
381 const RenderNodeDefaultCameraController::CameraResourceSetup& cameraResourceSetup,
382 RenderNodeDefaultCameraController::CreatedTargets& createdTargets)
383 {
384 #if (CORE3D_VALIDATION_ENABLED == 1)
385 CORE_LOG_I("CORE3D_VALIDATION: creating camera color targets %s", customCamRngId.data());
386 #endif
387 // This (re-)creates all the needed color targets
388 GpuImageDesc desc = cameraResourceSetup.inputImageDescs.color;
389 desc.width = targetDesc.width;
390 desc.height = targetDesc.height;
391 desc.layerCount = targetDesc.layerCount;
392 desc.imageViewType = GetImageViewType(desc.layerCount, desc.imageViewType);
393 if (camera.flags & RenderCamera::CAMERA_FLAG_MSAA_BIT) {
394 const bool directBackbufferResolve =
395 camera.renderPipelineType == RenderCamera::RenderPipelineType::LIGHT_FORWARD;
396
397 GpuImageDesc msaaDesc = desc;
398 if (directBackbufferResolve) {
399 msaaDesc.format = targetDesc.format;
400 }
401 msaaDesc.engineCreationFlags |= CORE_ENGINE_IMAGE_CREATION_RESET_STATE_ON_FRAME_BORDERS;
402 msaaDesc.sampleCountFlags = CORE_SAMPLE_COUNT_4_BIT;
403 msaaDesc.usageFlags = CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | CORE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
404 msaaDesc.memoryPropertyFlags =
405 CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
406
407 #if (CORE3D_VALIDATION_ENABLED == 1)
408 createdTargets.colorMsaa = gpuResourceMgr.Create(
409 us + DefaultMaterialCameraConstants::CAMERA_COLOR_PREFIX_NAME + "MSAA_" + customCamRngId, msaaDesc);
410 #else
411 createdTargets.colorMsaa = gpuResourceMgr.Create(createdTargets.colorMsaa, msaaDesc);
412 #endif
413 }
414
415 if (camera.renderPipelineType != RenderCamera::RenderPipelineType::LIGHT_FORWARD) {
416 #if (CORE3D_VALIDATION_ENABLED == 1)
417 createdTargets.colorResolve = gpuResourceMgr.Create(
418 us + DefaultMaterialCameraConstants::CAMERA_COLOR_PREFIX_NAME + "RESL_" + customCamRngId, desc);
419 #else
420 createdTargets.colorResolve = gpuResourceMgr.Create(createdTargets.colorResolve, desc);
421 #endif
422 }
423
424 CreateVelocityTarget(gpuResourceMgr, camera, targetDesc, us, customCamRngId, cameraResourceSetup, createdTargets);
425 CreateDeferredTargets(gpuResourceMgr, camera, targetDesc, us, customCamRngId, cameraResourceSetup, createdTargets);
426
427 CreateHistoryTargets(gpuResourceMgr, camera, targetDesc, us, customCamRngId, cameraResourceSetup, createdTargets);
428 }
429
CreateDepthTargets(IRenderNodeGpuResourceManager & gpuResourceMgr,const RenderCamera & camera,const GpuImageDesc & targetDesc,const string_view us,const string_view customCamRngId,RenderNodeDefaultCameraController::CameraResourceSetup & cameraResourceSetup,RenderNodeDefaultCameraController::CreatedTargets & createdTargets)430 void CreateDepthTargets(IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderCamera& camera,
431 const GpuImageDesc& targetDesc, const string_view us, const string_view customCamRngId,
432 RenderNodeDefaultCameraController::CameraResourceSetup& cameraResourceSetup,
433 RenderNodeDefaultCameraController::CreatedTargets& createdTargets)
434 {
435 #if (CORE3D_VALIDATION_ENABLED == 1)
436 CORE_LOG_I("CORE3D_VALIDATION: creating camera depth targets %s", customCamRngId.data());
437 #endif
438 // this (re-)creates all the needed depth targets
439 // we support cameras without depth targets (default depth is created if no msaa)
440 GpuImageDesc desc = cameraResourceSetup.inputImageDescs.depth;
441 desc.width = targetDesc.width;
442 desc.height = targetDesc.height;
443 desc.layerCount = targetDesc.layerCount;
444 desc.imageViewType = GetImageViewType(desc.layerCount, desc.imageViewType);
445 if (camera.flags & RenderCamera::CAMERA_FLAG_MSAA_BIT) {
446 GpuImageDesc msaaDesc = desc;
447 msaaDesc.engineCreationFlags |= CORE_ENGINE_IMAGE_CREATION_RESET_STATE_ON_FRAME_BORDERS;
448 msaaDesc.sampleCountFlags = CORE_SAMPLE_COUNT_4_BIT;
449 // If MSAA targets have input attachment bit they are not created as renderbuffers and
450 // EXT_multisample_render_to_texture supports only depth with renderbuffers.
451 msaaDesc.usageFlags = CORE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | CORE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
452 msaaDesc.memoryPropertyFlags =
453 CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
454 #if (CORE3D_VALIDATION_ENABLED == 1)
455 createdTargets.depthMsaa = gpuResourceMgr.Create(
456 us + DefaultMaterialCameraConstants::CAMERA_DEPTH_PREFIX_NAME + "MSAA_" + customCamRngId, msaaDesc);
457 #else
458 createdTargets.depthMsaa = gpuResourceMgr.Create(createdTargets.depthMsaa, msaaDesc);
459 #endif
460 }
461 const bool createBasicDepth = (((camera.flags & RenderCamera::CAMERA_FLAG_MSAA_BIT) == 0) ||
462 ((camera.flags & RenderCamera::CAMERA_FLAG_OUTPUT_DEPTH_BIT) != 0)) &&
463 (!RenderHandleUtil::IsValid(camera.depthTarget.GetHandle()));
464 if (createBasicDepth) {
465 if (camera.flags & RenderCamera::CAMERA_FLAG_OUTPUT_DEPTH_BIT) {
466 desc.usageFlags |= CORE_IMAGE_USAGE_SAMPLED_BIT;
467 // we cannot have transient and lazy allocation
468 desc.usageFlags &= (~CORE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT);
469 desc.memoryPropertyFlags &= (~CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT);
470 }
471 createdTargets.depth =
472 gpuResourceMgr.Create(us + DefaultMaterialCameraConstants::CAMERA_DEPTH_PREFIX_NAME + customCamRngId, desc);
473 }
474
475 // store
476 createdTargets.imageDescs.depth = desc;
477 }
478
ColorTargetsRecreationNeeded(const RenderCamera & camera,const RenderNodeDefaultCameraController::CameraResourceSetup & camRes,const GpuImageDesc & desc)479 bool ColorTargetsRecreationNeeded(const RenderCamera& camera,
480 const RenderNodeDefaultCameraController::CameraResourceSetup& camRes, const GpuImageDesc& desc)
481 {
482 constexpr RenderCamera::Flags importantFlags { RenderCamera::CAMERA_FLAG_HISTORY_BIT |
483 RenderCamera::CAMERA_FLAG_OUTPUT_DEPTH_BIT |
484 RenderCamera::CAMERA_FLAG_OUTPUT_VELOCITY_NORMAL_BIT };
485 const RenderCamera::Flags newFlags = camera.flags & importantFlags;
486 const RenderCamera::Flags oldFlags = camRes.camFlags & importantFlags;
487 const bool creationFlagsChanged = newFlags != oldFlags;
488 const bool pipelineChanged = (camera.renderPipelineType != camRes.pipelineType);
489 const bool resChanged = ((desc.width != camRes.outResolution.x) || (desc.height != camRes.outResolution.y));
490 // NOTE: currently compares only the output not the color i.e. the intermediate
491 const bool formatChanged = (!RenderHandleUtil::IsValid(camRes.colorTarget))
492 ? (desc.format != camRes.inputImageDescs.output.format)
493 : false;
494 const bool multiviewChanged = (camera.multiViewCameraCount > 0U) != camRes.isMultiview;
495
496 bool changed = false;
497 if (creationFlagsChanged || pipelineChanged || resChanged || formatChanged || multiviewChanged) {
498 changed = true;
499 }
500 return changed;
501 }
502
DepthTargetsRecreationNeeded(const RenderCamera & camera,const RenderNodeDefaultCameraController::CameraResourceSetup & camRes,const GpuImageDesc & desc)503 bool DepthTargetsRecreationNeeded(const RenderCamera& camera,
504 const RenderNodeDefaultCameraController::CameraResourceSetup& camRes, const GpuImageDesc& desc)
505 {
506 constexpr RenderCamera::Flags importantFlags { RenderCamera::CAMERA_FLAG_OUTPUT_DEPTH_BIT };
507 const bool formatChanged =
508 (!RenderHandleUtil::IsValid(camRes.depthTarget)) ? (desc.format != camRes.inputImageDescs.depth.format) : false;
509 const bool resChanged = ((desc.width != camRes.outResolution.x) || (desc.height != camRes.outResolution.y));
510 const RenderCamera::Flags newFlags = camera.flags & importantFlags;
511 const RenderCamera::Flags oldFlags = camRes.camFlags & importantFlags;
512 const bool creationFlagsChanged = newFlags != oldFlags;
513 const bool multiviewChanged = (camera.multiViewCameraCount > 0U) != camRes.isMultiview;
514
515 bool changed = false;
516 if (formatChanged || resChanged || creationFlagsChanged || multiviewChanged) {
517 changed = true;
518 }
519 return changed;
520 }
521 } // namespace
522
InitNode(IRenderNodeContextManager & renderNodeContextMgr)523 void RenderNodeDefaultCameraController::InitNode(IRenderNodeContextManager& renderNodeContextMgr)
524 {
525 renderNodeContextMgr_ = &renderNodeContextMgr;
526 SetDefaultGpuImageDescs();
527 ParseRenderNodeInputs();
528
529 const auto& renderNodeGraphData = renderNodeContextMgr_->GetRenderNodeGraphData();
530 stores_ = RenderNodeSceneUtil::GetSceneRenderDataStores(
531 renderNodeContextMgr, renderNodeGraphData.renderNodeGraphDataStoreName);
532
533 currentScene_ = {};
534 currentScene_.customCamRngName = jsonInputs_.customCameraName;
535
536 // id checked first for custom camera
537 if (jsonInputs_.customCameraId != INVALID_CAM_ID) {
538 currentScene_.customCameraId = jsonInputs_.customCameraId;
539 } else if (!jsonInputs_.customCameraName.empty()) {
540 currentScene_.customCameraName = jsonInputs_.customCameraName;
541 }
542
543 camRes_.backendType = renderNodeContextMgr_->GetRenderNodeGraphData().renderingConfiguration.renderBackend;
544 defaultCubemap_ = renderNodeContextMgr_->GetGpuResourceManager().GetImageHandle(
545 DefaultMaterialGpuResourceConstants::CORE_DEFAULT_SKYBOX_CUBEMAP);
546
547 const auto& renderDataStoreMgr = renderNodeContextMgr_->GetRenderDataStoreManager();
548 const auto* dataStoreScene =
549 static_cast<IRenderDataStoreDefaultScene*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameScene));
550 const auto* dataStoreCamera =
551 static_cast<IRenderDataStoreDefaultCamera*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameCamera));
552 const auto* dataStoreLight =
553 static_cast<IRenderDataStoreDefaultLight*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameLight));
554
555 if (dataStoreScene && dataStoreCamera && dataStoreLight) {
556 UpdateCurrentScene(*dataStoreScene, *dataStoreCamera, *dataStoreLight);
557 CreateResources();
558 RegisterOutputs();
559 CreateBuffers();
560 }
561 }
562
PreExecuteFrame()563 void RenderNodeDefaultCameraController::PreExecuteFrame()
564 {
565 const auto& renderDataStoreMgr = renderNodeContextMgr_->GetRenderDataStoreManager();
566 const auto* dataStoreScene =
567 static_cast<IRenderDataStoreDefaultScene*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameScene));
568 const auto* dataStoreCamera =
569 static_cast<IRenderDataStoreDefaultCamera*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameCamera));
570 const auto* dataStoreLight =
571 static_cast<IRenderDataStoreDefaultLight*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameLight));
572
573 if (dataStoreScene && dataStoreCamera && dataStoreLight) {
574 UpdateCurrentScene(*dataStoreScene, *dataStoreCamera, *dataStoreLight);
575 CreateResources();
576 RegisterOutputs();
577 }
578 }
579
ExecuteFrame(IRenderCommandList & cmdList)580 void RenderNodeDefaultCameraController::ExecuteFrame(IRenderCommandList& cmdList)
581 {
582 UpdateBuffers();
583 }
584
UpdateCurrentScene(const IRenderDataStoreDefaultScene & dataStoreScene,const IRenderDataStoreDefaultCamera & dataStoreCamera,const IRenderDataStoreDefaultLight & dataStoreLight)585 void RenderNodeDefaultCameraController::UpdateCurrentScene(const IRenderDataStoreDefaultScene& dataStoreScene,
586 const IRenderDataStoreDefaultCamera& dataStoreCamera, const IRenderDataStoreDefaultLight& dataStoreLight)
587 {
588 const auto scene = dataStoreScene.GetScene();
589 uint32_t cameraIdx = scene.cameraIndex;
590 if (currentScene_.customCameraId != INVALID_CAM_ID) {
591 cameraIdx = dataStoreCamera.GetCameraIndex(currentScene_.customCameraId);
592 } else if (!(currentScene_.customCameraName.empty())) {
593 cameraIdx = dataStoreCamera.GetCameraIndex(currentScene_.customCameraName);
594 }
595
596 if (const auto cameras = dataStoreCamera.GetCameras(); cameraIdx < (uint32_t)cameras.size()) {
597 // store current frame camera
598 currentScene_.camera = cameras[cameraIdx];
599 }
600
601 currentScene_.cameraIdx = cameraIdx;
602 currentScene_.sceneTimingData = { scene.sceneDeltaTime, scene.deltaTime, scene.totalTime,
603 *reinterpret_cast<const float*>(&scene.frameIndex) };
604
605 ValidateRenderCamera(currentScene_.camera);
606
607 UpdatePostProcessConfiguration();
608 }
609
RegisterOutputs()610 void RenderNodeDefaultCameraController::RegisterOutputs()
611 {
612 if ((currentScene_.customCameraId == INVALID_CAM_ID) && currentScene_.customCameraName.empty()) {
613 return;
614 }
615
616 const CreatedTargetHandles cth = FillCreatedTargets(createdTargets_);
617 const RenderHandle colorTarget = RenderHandleUtil::IsValid(camRes_.colorTarget) ? camRes_.colorTarget : cth.color;
618 const RenderHandle depthTarget = RenderHandleUtil::IsValid(camRes_.depthTarget) ? camRes_.depthTarget : cth.depth;
619
620 IRenderNodeGraphShareManager& shrMgr = renderNodeContextMgr_->GetRenderNodeGraphShareManager();
621 shrMgr.RegisterRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_OUTPUT, colorTarget);
622 shrMgr.RegisterGlobalRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_OUTPUT, colorTarget);
623
624 // color is output always, depth usually (not with MSAA if not forced)
625 // colorResolve is used with msaa and hdr, the output is the 32 bit srgb color usually
626 const RenderHandle regDepth = RenderHandleUtil::IsValid(cth.depth) ? cth.depth : depthTarget;
627 const RenderHandle regColor = RenderHandleUtil::IsValid(cth.colorResolve) ? cth.colorResolve : colorTarget;
628 if (RenderHandleUtil::IsValid(regDepth)) {
629 shrMgr.RegisterRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_DEPTH, regDepth);
630 shrMgr.RegisterGlobalRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_DEPTH, regDepth);
631 }
632 shrMgr.RegisterRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_COLOR, regColor);
633 shrMgr.RegisterGlobalRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_COLOR, regColor);
634 if (RenderHandleUtil::IsValid(cth.velNor)) {
635 shrMgr.RegisterRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_VELOCITY_NORMAL, cth.velNor);
636 shrMgr.RegisterGlobalRenderNodeOutput(
637 DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_VELOCITY_NORMAL, cth.velNor);
638 }
639 // NOTE: HDR does not have float intermediate target ATM
640 if (currentScene_.camera.renderPipelineType == RenderCamera::RenderPipelineType::DEFERRED) {
641 shrMgr.RegisterRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_BASE_COLOR, cth.baseColor);
642 shrMgr.RegisterRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_MATERIAL, cth.material);
643 shrMgr.RegisterGlobalRenderNodeOutput(
644 DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_BASE_COLOR, cth.baseColor);
645 shrMgr.RegisterGlobalRenderNodeOutput(
646 DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_MATERIAL, cth.material);
647 } else if (currentScene_.camera.flags & (RenderCamera::CAMERA_FLAG_MSAA_BIT)) {
648 shrMgr.RegisterRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_DEPTH_MSAA, cth.depthMsaa);
649 shrMgr.RegisterRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_COLOR_MSAA, cth.colorMsaa);
650 shrMgr.RegisterGlobalRenderNodeOutput(
651 DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_DEPTH_MSAA, cth.depthMsaa);
652 shrMgr.RegisterGlobalRenderNodeOutput(
653 DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_COLOR_MSAA, cth.colorMsaa);
654 }
655
656 // output history
657 if (currentScene_.camera.flags & RenderCamera::CameraFlagBits::CAMERA_FLAG_HISTORY_BIT) {
658 const uint32_t currIndex = camRes_.historyFlipFrame;
659 const uint32_t nextIndex = (currIndex + 1u) % 2u;
660 shrMgr.RegisterRenderNodeOutput(
661 DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_HISTORY, createdTargets_.history[currIndex].GetHandle());
662 shrMgr.RegisterRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_HISTORY_NEXT,
663 createdTargets_.history[nextIndex].GetHandle());
664 shrMgr.RegisterGlobalRenderNodeOutput(
665 DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_HISTORY, createdTargets_.history[currIndex].GetHandle());
666 shrMgr.RegisterGlobalRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_HISTORY_NEXT,
667 createdTargets_.history[nextIndex].GetHandle());
668 camRes_.historyFlipFrame = nextIndex;
669 }
670 // output cubemap
671 const RenderHandle cubemap = (createdTargets_.cubemap) ? createdTargets_.cubemap.GetHandle() : defaultCubemap_;
672 shrMgr.RegisterRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_RADIANCE_CUBEMAP, cubemap);
673 shrMgr.RegisterGlobalRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_RADIANCE_CUBEMAP, cubemap);
674 }
675
CreateResources()676 void RenderNodeDefaultCameraController::CreateResources()
677 {
678 if ((currentScene_.customCameraId == INVALID_CAM_ID) && currentScene_.customCameraName.empty()) {
679 return;
680 }
681
682 // NOTE: with CAMERA_FLAG_MAIN_BIT we support rendering to cameras without targets
683 // if no depth is given, we create a transient depth
684 CreateResourceBaseTargets();
685
686 IRenderNodeGpuResourceManager& gpuResMgr = renderNodeContextMgr_->GetGpuResourceManager();
687 const auto& camera = currentScene_.camera;
688 bool validDepthHandle = RenderHandleUtil::IsValid(camRes_.depthTarget);
689 const bool isHdr = (camera.renderPipelineType != RenderCamera::RenderPipelineType::LIGHT_FORWARD);
690 const bool isMsaa = (camera.flags & RenderCamera::CAMERA_FLAG_MSAA_BIT);
691 const bool isDeferred = (camera.renderPipelineType == RenderCamera::RenderPipelineType::DEFERRED);
692 const bool isMultiview = (camera.multiViewCameraCount > 0U);
693 const uint32_t mvLayerCount = isMultiview ? (camera.multiViewCameraCount + 1U) : 1U;
694 if (validDepthHandle && isMultiview) {
695 validDepthHandle = false;
696 #if (CORE3D_VALIDATION_ENABLED == 1)
697 CORE_LOG_ONCE_W(renderNodeContextMgr_->GetName() + "cam_controller_multiview_depth",
698 "CORE3D_VALIDATION: Multi-view not supported with custom depth targets (creating new layered depth)");
699 #endif
700 }
701 if ((!validDepthHandle) || isMsaa || isHdr || isDeferred) {
702 GpuImageDesc colorDesc = RenderHandleUtil::IsValid(camRes_.colorTarget)
703 ? gpuResMgr.GetImageDescriptor(camRes_.colorTarget)
704 : gpuResMgr.GetImageDescriptor(createdTargets_.outputColor.GetHandle());
705
706 if (isMultiview) {
707 colorDesc.layerCount = mvLayerCount;
708 }
709 const bool colorTargetChanged = ColorTargetsRecreationNeeded(camera, camRes_, colorDesc);
710
711 GpuImageDesc depthDesc;
712 if (!validDepthHandle) {
713 depthDesc = colorDesc;
714 depthDesc.format = createdTargets_.imageDescs.depth.format;
715 } else {
716 depthDesc = gpuResMgr.GetImageDescriptor(camRes_.depthTarget);
717 }
718 bool depthTargetChanged = DepthTargetsRecreationNeeded(camera, camRes_, depthDesc);
719 // depth size needs to match color
720 if ((colorDesc.width != depthDesc.width) || (colorDesc.height != depthDesc.height)) {
721 depthTargetChanged = true;
722 depthDesc.width = colorDesc.width;
723 depthDesc.height = colorDesc.height;
724 }
725
726 camRes_.outResolution.x = colorDesc.width;
727 camRes_.outResolution.y = colorDesc.height;
728 camRes_.renResolution = currentScene_.camera.renderResolution;
729 camRes_.camFlags = camera.flags;
730 camRes_.pipelineType = camera.renderPipelineType;
731 camRes_.isMultiview = (camera.multiViewCameraCount > 0U);
732 if (isMultiview) {
733 colorDesc.layerCount = mvLayerCount;
734 }
735
736 if ((camRes_.renResolution.x < 1U) || (camRes_.renResolution.y < 1U)) {
737 const string_view nodeName = renderNodeContextMgr_->GetName();
738 #if (CORE3D_VALIDATION_ENABLED == 1)
739 CORE_LOG_ONCE_E(nodeName + "cam_controller_renRes",
740 "CORE3D_VALIDATION: RN:%s camera render resolution %ux%u", nodeName.data(), camRes_.renResolution.x,
741 camRes_.renResolution.y);
742 #endif
743 camRes_.renResolution.x = Math::max(1u, camRes_.renResolution.x);
744 camRes_.renResolution.y = Math::max(1u, camRes_.renResolution.y);
745 }
746
747 const bool enableRenderRes = (camera.renderPipelineType != RenderCamera::RenderPipelineType::LIGHT_FORWARD);
748 if (enableRenderRes) {
749 colorDesc.width = camRes_.renResolution.x;
750 colorDesc.height = camRes_.renResolution.y;
751 depthDesc.width = camRes_.renResolution.x;
752 depthDesc.height = camRes_.renResolution.y;
753 }
754
755 // all decisions are done based on color and depth targets
756 const string_view us = stores_.dataStoreNameScene;
757 if (colorTargetChanged) {
758 CreateColorTargets(
759 gpuResMgr, camera, colorDesc, us, currentScene_.customCamRngName, camRes_, createdTargets_);
760 }
761 if (depthTargetChanged) {
762 CreateDepthTargets(
763 gpuResMgr, camera, depthDesc, us, currentScene_.customCamRngName, camRes_, createdTargets_);
764 }
765 }
766 }
767
CreateResourceBaseTargets()768 void RenderNodeDefaultCameraController::CreateResourceBaseTargets()
769 {
770 IRenderNodeGpuResourceManager& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
771 const auto& camera = currentScene_.camera;
772
773 if ((camera.flags & RenderCamera::CameraFlagBits::CAMERA_FLAG_DYNAMIC_CUBEMAP_BIT) && (!createdTargets_.cubemap)) {
774 const string_view us = stores_.dataStoreNameScene;
775 const string_view camName = currentScene_.customCamRngName;
776 // readiance cubemap is always created with a name
777 createdTargets_.cubemap = gpuResourceMgr.Create(
778 us + DefaultMaterialCameraConstants::CAMERA_COLOR_PREFIX_NAME + "RADIANCE_CUBEMAP_" + camName,
779 camRes_.inputImageDescs.cubemap);
780 #if (CORE3D_VALIDATION_ENABLED == 1)
781 CORE_LOG_I(
782 "CORE3D_VALIDATION: camera (%s) creating dynamic radiance cubemap", currentScene_.customCamRngName.data());
783 #endif
784 }
785
786 camRes_.colorTarget = camera.colorTargets[0].GetHandle();
787 camRes_.depthTarget = camera.depthTarget.GetHandle();
788 // update formats if given
789 auto UpdateTargetFormats = [](const auto& input, auto& output) {
790 if (input.format != BASE_FORMAT_UNDEFINED) {
791 output.format = input.format;
792 }
793 if (input.usageFlags != 0) {
794 output.usageFlags = input.usageFlags;
795 }
796 };
797 UpdateTargetFormats(camera.colorTargetCustomization[0U], camRes_.inputImageDescs.output);
798 UpdateTargetFormats(camera.colorTargetCustomization[0U], camRes_.inputImageDescs.color);
799 UpdateTargetFormats(camera.depthTargetCustomization, camRes_.inputImageDescs.depth);
800 if (camera.flags & RenderCamera::CAMERA_FLAG_MAIN_BIT) {
801 if (!RenderHandleUtil::IsValid(camRes_.colorTarget)) {
802 camRes_.colorTarget = gpuResourceMgr.GetImageHandle("CORE_DEFAULT_BACKBUFFER");
803 #if (CORE3D_VALIDATION_ENABLED == 1)
804 CORE_LOG_ONCE_I(renderNodeContextMgr_->GetName() + "using_def_backbuffer",
805 "CORE3D_VALIDATION: camera (%s) using CORE_DEFAULT_BACKBUFFER", currentScene_.customCamRngName.data());
806 #endif
807 }
808 }
809 if (!RenderHandleUtil::IsValid(camRes_.colorTarget)) {
810 const string_view us = stores_.dataStoreNameScene;
811 if (createdTargets_.outputColor) {
812 const GpuImageDesc colorDesc = gpuResourceMgr.GetImageDescriptor(createdTargets_.outputColor.GetHandle());
813 if ((colorDesc.width != camera.renderResolution.x) || (colorDesc.height != camera.renderResolution.y)) {
814 CreateBaseColorTarget(
815 gpuResourceMgr, camera, us, currentScene_.customCamRngName, camRes_, createdTargets_);
816 }
817 } else {
818 CreateBaseColorTarget(gpuResourceMgr, camera, us, currentScene_.customCamRngName, camRes_, createdTargets_);
819 }
820 }
821 }
822
CreateBuffers()823 void RenderNodeDefaultCameraController::CreateBuffers()
824 {
825 auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
826 string camName;
827 if (currentScene_.customCameraId != INVALID_CAM_ID) {
828 camName = to_string(currentScene_.customCameraId);
829 } else if (!(currentScene_.customCameraName.empty())) {
830 camName = currentScene_.customCameraName;
831 }
832 constexpr MemoryPropertyFlags memPropertyFlags =
833 (CORE_MEMORY_PROPERTY_HOST_VISIBLE_BIT | CORE_MEMORY_PROPERTY_HOST_COHERENT_BIT);
834 const string_view us = stores_.dataStoreNameScene;
835 uboHandles_.generalData =
836 gpuResourceMgr.Create(us + DefaultMaterialCameraConstants::CAMERA_GENERAL_BUFFER_PREFIX_NAME + camName,
837 GpuBufferDesc { CORE_BUFFER_USAGE_UNIFORM_BUFFER_BIT, memPropertyFlags,
838 CORE_ENGINE_BUFFER_CREATION_DYNAMIC_RING_BUFFER,
839 static_cast<uint32_t>(sizeof(DefaultMaterialGeneralDataStruct)) });
840 uboHandles_.environment =
841 gpuResourceMgr.Create(us + DefaultMaterialCameraConstants::CAMERA_ENVIRONMENT_BUFFER_PREFIX_NAME + camName,
842 GpuBufferDesc { CORE_BUFFER_USAGE_UNIFORM_BUFFER_BIT, memPropertyFlags,
843 CORE_ENGINE_BUFFER_CREATION_DYNAMIC_RING_BUFFER,
844 static_cast<uint32_t>(sizeof(DefaultMaterialEnvironmentStruct)) *
845 CORE_DEFAULT_MATERIAL_MAX_ENVIRONMENT_COUNT });
846 uboHandles_.fog = gpuResourceMgr.Create(
847 us + DefaultMaterialCameraConstants::CAMERA_FOG_BUFFER_PREFIX_NAME + camName,
848 GpuBufferDesc { CORE_BUFFER_USAGE_UNIFORM_BUFFER_BIT, memPropertyFlags,
849 CORE_ENGINE_BUFFER_CREATION_DYNAMIC_RING_BUFFER, static_cast<uint32_t>(sizeof(DefaultMaterialFogStruct)) });
850 uboHandles_.postProcess = gpuResourceMgr.Create(
851 us + DefaultMaterialCameraConstants::CAMERA_POST_PROCESS_BUFFER_PREFIX_NAME + camName,
852 GpuBufferDesc { CORE_BUFFER_USAGE_UNIFORM_BUFFER_BIT, memPropertyFlags,
853 CORE_ENGINE_BUFFER_CREATION_DYNAMIC_RING_BUFFER, static_cast<uint32_t>(sizeof(GlobalPostProcessStruct)) });
854
855 uboHandles_.light =
856 gpuResourceMgr.Create(us + DefaultMaterialCameraConstants::CAMERA_LIGHT_BUFFER_PREFIX_NAME + camName,
857 GpuBufferDesc { CORE_BUFFER_USAGE_UNIFORM_BUFFER_BIT, memPropertyFlags,
858 CORE_ENGINE_BUFFER_CREATION_DYNAMIC_RING_BUFFER, sizeof(DefaultMaterialLightStruct) });
859 // NOTE: storage buffer
860 uboHandles_.lightCluster =
861 gpuResourceMgr.Create(us + DefaultMaterialCameraConstants::CAMERA_LIGHT_CLUSTER_BUFFER_PREFIX_NAME + camName,
862 GpuBufferDesc { CORE_BUFFER_USAGE_STORAGE_BUFFER_BIT, memPropertyFlags,
863 CORE_ENGINE_BUFFER_CREATION_DYNAMIC_RING_BUFFER,
864 sizeof(uint32_t) * RenderLightHelper::DEFAULT_CLUSTER_INDEX_COUNT });
865 }
866
UpdateBuffers()867 void RenderNodeDefaultCameraController::UpdateBuffers()
868 {
869 UpdateGeneralUniformBuffer();
870 UpdateLightBuffer();
871 UpdateEnvironmentUniformBuffer();
872 UpdateFogUniformBuffer();
873 UpdatePostProcessUniformBuffer();
874 }
875
UpdateGeneralUniformBuffer()876 void RenderNodeDefaultCameraController::UpdateGeneralUniformBuffer()
877 {
878 const auto& camera = currentScene_.camera;
879 const Math::Vec2 viewportSize = { static_cast<float>(camera.renderResolution.x),
880 static_cast<float>(camera.renderResolution.y) };
881 DefaultMaterialGeneralDataStruct dataStruct {
882 { currentScene_.cameraIdx, 0u, 0u, 0u },
883 { viewportSize.x, viewportSize.y, 1.0f / viewportSize.x, 1.0f / viewportSize.y },
884 currentScene_.sceneTimingData,
885 };
886
887 IRenderNodeGpuResourceManager& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
888 if (auto data = reinterpret_cast<uint8_t*>(gpuResourceMgr.MapBuffer(uboHandles_.generalData.GetHandle())); data) {
889 const auto* dataEnd = data + sizeof(DefaultMaterialGeneralDataStruct);
890 if (!CloneData(data, size_t(dataEnd - data), &dataStruct, sizeof(DefaultMaterialGeneralDataStruct))) {
891 CORE_LOG_E("generalData ubo copying failed.");
892 }
893 gpuResourceMgr.UnmapBuffer(uboHandles_.generalData.GetHandle());
894 }
895 }
896
UpdatePostProcessUniformBuffer()897 void RenderNodeDefaultCameraController::UpdatePostProcessUniformBuffer()
898 {
899 CORE_STATIC_ASSERT(sizeof(GlobalPostProcessStruct) == sizeof(RenderPostProcessConfiguration));
900 IRenderNodeGpuResourceManager& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
901 if (auto data = reinterpret_cast<uint8_t*>(gpuResourceMgr.MapBuffer(uboHandles_.postProcess.GetHandle())); data) {
902 const auto* dataEnd = data + sizeof(GlobalPostProcessStruct);
903 if (!CloneData(data, size_t(dataEnd - data), ¤tRenderPPConfiguration_, sizeof(GlobalPostProcessStruct))) {
904 CORE_LOG_E("post process ubo copying failed.");
905 }
906 gpuResourceMgr.UnmapBuffer(uboHandles_.postProcess.GetHandle());
907 }
908 }
909
UpdateEnvironmentUniformBuffer()910 void RenderNodeDefaultCameraController::UpdateEnvironmentUniformBuffer()
911 {
912 BASE_NS::Math::Vec4
913 defaultSHIndirectCoefficients[9u] {}; // nine vectors which are used in spherical harmonics calculations
914 defaultSHIndirectCoefficients[0] = { 1.0f, 1.0f, 1.0f, 1.0f };
915 constexpr uint32_t envByteSize =
916 sizeof(DefaultMaterialEnvironmentStruct) * CORE_DEFAULT_MATERIAL_MAX_ENVIRONMENT_COUNT;
917
918 const auto& renderDataStoreMgr = renderNodeContextMgr_->GetRenderDataStoreManager();
919 if (const auto* dsCamera = static_cast<IRenderDataStoreDefaultCamera*>(
920 renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameCamera));
921 dsCamera) {
922 // the environments needs to be in camera sorted order
923 // we fetch environments one by one based on their id
924 // in typical scenario there's only one environment present and others are filled with default data
925 IRenderNodeGpuResourceManager& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
926 if (auto data = reinterpret_cast<uint8_t*>(gpuResourceMgr.MapBuffer(uboHandles_.environment.GetHandle()));
927 data) {
928 const auto* dataEnd = data + envByteSize;
929 const auto& camera = currentScene_.camera;
930 for (uint32_t idx = 0; idx < camera.environmentCount; ++idx) {
931 const RenderCamera::Environment currEnv = dsCamera->GetEnvironment(camera.environmentIds[idx]);
932
933 const Math::UVec2 id = GetPacked64(currEnv.id);
934 const Math::UVec2 layer = GetPacked64(currEnv.layerMask);
935 const float radianceCubemapLodCoeff =
936 (currEnv.radianceCubemapMipCount != 0)
937 ? Math::min(CUBE_MAP_LOD_COEFF, static_cast<float>(currEnv.radianceCubemapMipCount))
938 : CUBE_MAP_LOD_COEFF;
939 DefaultMaterialEnvironmentStruct envStruct {
940 Math::Vec4((Math::Vec3(currEnv.indirectSpecularFactor) * currEnv.indirectSpecularFactor.w),
941 currEnv.indirectSpecularFactor.w),
942 Math::Vec4(Math::Vec3(currEnv.indirectDiffuseFactor) * currEnv.indirectDiffuseFactor.w,
943 currEnv.indirectDiffuseFactor.w),
944 Math::Vec4(Math::Vec3(currEnv.envMapFactor) * currEnv.envMapFactor.w, currEnv.envMapFactor.w),
945 Math::Vec4(radianceCubemapLodCoeff, currEnv.envMapLodLevel, 0.0f, 0.0f),
946 currEnv.blendFactor,
947 Math::Mat4Cast(currEnv.rotation),
948 Math::UVec4(id.x, id.y, layer.x, layer.y),
949 {},
950 {},
951 };
952 constexpr size_t countOfSh = countof(envStruct.shIndirectCoefficients);
953 if (currEnv.radianceCubemap) {
954 for (size_t jdx = 0; jdx < countOfSh; ++jdx) {
955 envStruct.shIndirectCoefficients[jdx] = currEnv.shIndirectCoefficients[jdx];
956 }
957 } else {
958 for (size_t jdx = 0; jdx < countOfSh; ++jdx) {
959 envStruct.shIndirectCoefficients[jdx] = defaultSHIndirectCoefficients[jdx];
960 }
961 }
962
963 if (!CloneData(data, size_t(dataEnd - data), &envStruct, sizeof(DefaultMaterialEnvironmentStruct))) {
964 CORE_LOG_E("environment ubo copying failed.");
965 }
966 data = data + sizeof(DefaultMaterialEnvironmentStruct);
967 }
968 gpuResourceMgr.UnmapBuffer(uboHandles_.environment.GetHandle());
969 }
970 }
971 }
972
UpdateFogUniformBuffer()973 void RenderNodeDefaultCameraController::UpdateFogUniformBuffer()
974 {
975 const auto& camera = currentScene_.camera;
976 const RenderCamera::Fog& fog = camera.fog;
977 const Math::UVec2 id = GetPacked64(fog.id);
978 const Math::UVec2 layer = GetPacked64(fog.layerMask);
979 const DefaultMaterialFogStruct fogStruct {
980 Math::UVec4 { id.x, id.y, layer.x, layer.y },
981 fog.firstLayer,
982 fog.secondLayer,
983 fog.baseFactors,
984 fog.inscatteringColor,
985 fog.envMapFactor,
986 fog.additionalFactor,
987 };
988 IRenderNodeGpuResourceManager& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
989 if (auto data = reinterpret_cast<uint8_t*>(gpuResourceMgr.MapBuffer(uboHandles_.fog.GetHandle())); data) {
990 const auto* dataEnd = data + sizeof(DefaultMaterialFogStruct);
991 if (!CloneData(data, size_t(dataEnd - data), &fogStruct, sizeof(DefaultMaterialFogStruct))) {
992 CORE_LOG_E("fog ubo copying failed.");
993 }
994 gpuResourceMgr.UnmapBuffer(uboHandles_.fog.GetHandle());
995 }
996 }
997
UpdateLightBuffer()998 void RenderNodeDefaultCameraController::UpdateLightBuffer()
999 {
1000 const auto& renderDataStoreMgr = renderNodeContextMgr_->GetRenderDataStoreManager();
1001 const auto* dataStoreScene =
1002 static_cast<IRenderDataStoreDefaultScene*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameScene));
1003 const auto* dataStoreLight =
1004 static_cast<IRenderDataStoreDefaultLight*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameLight));
1005
1006 // NOTE: should be culled by camera view frustum (or clustering can handle that)
1007 if (dataStoreScene && dataStoreLight) {
1008 auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
1009 const auto scene = dataStoreScene->GetScene();
1010 const auto& lights = dataStoreLight->GetLights();
1011 const Math::Vec4 shadowAtlasSizeInvSize = RenderLightHelper::GetShadowAtlasSizeInvSize(*dataStoreLight);
1012 const uint32_t shadowCount = dataStoreLight->GetLightCounts().shadowCount;
1013 // light buffer update (needs to be updated every frame)
1014 if (auto data = reinterpret_cast<uint8_t*>(gpuResourceMgr.MapBuffer(uboHandles_.light.GetHandle())); data) {
1015 // NOTE: do not read data from mapped buffer (i.e. do not use mapped buffer as input to anything)
1016 RenderLightHelper::LightCounts lightCounts;
1017 const uint32_t lightCount = std::min(CORE_DEFAULT_MATERIAL_MAX_LIGHT_COUNT, (uint32_t)lights.size());
1018 vector<RenderLightHelper::SortData> sortedFlags = RenderLightHelper::SortLights(lights, lightCount);
1019
1020 auto* singleLightStruct =
1021 reinterpret_cast<DefaultMaterialSingleLightStruct*>(data + RenderLightHelper::LIGHT_LIST_OFFSET);
1022 for (size_t idx = 0; idx < sortedFlags.size(); ++idx) {
1023 const auto& sortData = sortedFlags[idx];
1024 const auto& light = lights[sortData.index];
1025 if (light.layerMask & currentScene_.camera.layerMask) {
1026 // drop lights with no matching camera layers
1027 using UsageFlagBits = RenderLight::LightUsageFlagBits;
1028 if (sortData.lightUsageFlags & UsageFlagBits::LIGHT_USAGE_DIRECTIONAL_LIGHT_BIT) {
1029 lightCounts.directionalLightCount++;
1030 } else if (sortData.lightUsageFlags & UsageFlagBits::LIGHT_USAGE_POINT_LIGHT_BIT) {
1031 lightCounts.pointLightCount++;
1032 } else if (sortData.lightUsageFlags & UsageFlagBits::LIGHT_USAGE_SPOT_LIGHT_BIT) {
1033 lightCounts.spotLightCount++;
1034 }
1035
1036 RenderLightHelper::CopySingleLight(lights[sortData.index], shadowCount, singleLightStruct++);
1037 }
1038 }
1039
1040 DefaultMaterialLightStruct* lightStruct = reinterpret_cast<DefaultMaterialLightStruct*>(data);
1041 lightStruct->directionalLightBeginIndex = 0;
1042 lightStruct->directionalLightCount = lightCounts.directionalLightCount;
1043 lightStruct->pointLightBeginIndex = lightCounts.directionalLightCount;
1044 lightStruct->pointLightCount = lightCounts.pointLightCount;
1045 lightStruct->spotLightBeginIndex = lightCounts.directionalLightCount + lightCounts.pointLightCount;
1046 lightStruct->spotLightCount = lightCounts.spotLightCount;
1047 lightStruct->pad0 = 0;
1048 lightStruct->pad1 = 0;
1049 lightStruct->clusterSizes = Math::UVec4(0, 0, 0, 0);
1050 lightStruct->clusterFactors = Math::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
1051 lightStruct->atlasSizeInvSize = shadowAtlasSizeInvSize;
1052 lightStruct->additionalFactors = { 0.0f, 0.0f, 0.0f, 0.0f };
1053
1054 gpuResourceMgr.UnmapBuffer(uboHandles_.light.GetHandle());
1055 }
1056 }
1057 }
1058
UpdatePostProcessConfiguration()1059 void RenderNodeDefaultCameraController::UpdatePostProcessConfiguration()
1060 {
1061 const auto& dataStoreMgr = renderNodeContextMgr_->GetRenderDataStoreManager();
1062 if (auto* dataStore = static_cast<IRenderDataStorePod*>(dataStoreMgr.GetRenderDataStore(POD_DATA_STORE_NAME));
1063 dataStore) {
1064 auto const dataView = dataStore->Get(currentScene_.camera.postProcessName);
1065 if (dataView.data() && (dataView.size_bytes() == sizeof(PostProcessConfiguration))) {
1066 const PostProcessConfiguration* data = (const PostProcessConfiguration*)dataView.data();
1067 currentRenderPPConfiguration_ =
1068 renderNodeContextMgr_->GetRenderNodeUtil().GetRenderPostProcessConfiguration(*data);
1069 }
1070 }
1071 }
1072
SetDefaultGpuImageDescs()1073 void RenderNodeDefaultCameraController::SetDefaultGpuImageDescs()
1074 {
1075 camRes_.inputImageDescs.depth = DEPTH_DEFAULT_DESC;
1076
1077 camRes_.inputImageDescs.output = OUTPUT_DEFAULT_DESC;
1078 camRes_.inputImageDescs.color = COLOR_DEFAULT_DESC;
1079 camRes_.inputImageDescs.velocityNormal = VELOCITY_NORMAL_DEFAULT_DESC;
1080 camRes_.inputImageDescs.history = HISTORY_DEFAULT_DESC;
1081 camRes_.inputImageDescs.baseColor = BASE_COLOR_DEFAULT_DESC;
1082 camRes_.inputImageDescs.material = MATERIAL_DEFAULT_DESC;
1083
1084 camRes_.inputImageDescs.cubemap = CUBEMAP_DEFAULT_DESC;
1085 }
1086
ParseRenderNodeInputs()1087 void RenderNodeDefaultCameraController::ParseRenderNodeInputs()
1088 {
1089 const IRenderNodeParserUtil& parserUtil = renderNodeContextMgr_->GetRenderNodeParserUtil();
1090 const auto jsonVal = renderNodeContextMgr_->GetNodeJson();
1091 jsonInputs_.customCameraName = parserUtil.GetStringValue(jsonVal, "customCameraName");
1092 jsonInputs_.customCameraId = parserUtil.GetUintValue(jsonVal, "customCameraId");
1093
1094 const vector<RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc> imageDescs =
1095 parserUtil.GetGpuImageDescs(jsonVal, "gpuImageDescs");
1096
1097 for (const auto& ref : imageDescs) {
1098 if (ref.name == DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_OUTPUT) {
1099 camRes_.inputImageDescs.output = ref.desc;
1100 } else if (ref.name == DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_DEPTH) {
1101 camRes_.inputImageDescs.depth = ref.desc;
1102 } else if (ref.name == DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_COLOR) {
1103 camRes_.inputImageDescs.color = ref.desc;
1104 } else if (ref.name == DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_HISTORY) {
1105 camRes_.inputImageDescs.history = ref.desc;
1106 } else if (ref.name == DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_VELOCITY_NORMAL) {
1107 camRes_.inputImageDescs.velocityNormal = ref.desc;
1108 } else if (ref.name == DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_BASE_COLOR) {
1109 camRes_.inputImageDescs.baseColor = ref.desc;
1110 } else if (ref.name == DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_MATERIAL) {
1111 camRes_.inputImageDescs.material = ref.desc;
1112 } else if (ref.name == DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_RADIANCE_CUBEMAP) {
1113 camRes_.inputImageDescs.cubemap = ref.desc;
1114 }
1115 }
1116
1117 // validate
1118 const IRenderNodeGpuResourceManager& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
1119 ValidateDepthDesc(gpuResourceMgr, DEPTH_DEFAULT_DESC, camRes_.inputImageDescs.depth);
1120 ValidateColorDesc(gpuResourceMgr, OUTPUT_DEFAULT_DESC, true, camRes_.inputImageDescs.output);
1121 ValidateColorDesc(gpuResourceMgr, COLOR_DEFAULT_DESC, true, camRes_.inputImageDescs.color);
1122 ValidateColorDesc(gpuResourceMgr, VELOCITY_NORMAL_DEFAULT_DESC, true, camRes_.inputImageDescs.velocityNormal);
1123 ValidateColorDesc(gpuResourceMgr, HISTORY_DEFAULT_DESC, true, camRes_.inputImageDescs.history);
1124 ValidateColorDesc(gpuResourceMgr, BASE_COLOR_DEFAULT_DESC, false, camRes_.inputImageDescs.baseColor);
1125 ValidateColorDesc(gpuResourceMgr, MATERIAL_DEFAULT_DESC, false, camRes_.inputImageDescs.material);
1126 ValidateColorDesc(gpuResourceMgr, CUBEMAP_DEFAULT_DESC, false, camRes_.inputImageDescs.cubemap);
1127 }
1128
1129 // for plugin / factory interface
Create()1130 RENDER_NS::IRenderNode* RenderNodeDefaultCameraController::Create()
1131 {
1132 return new RenderNodeDefaultCameraController();
1133 }
1134
Destroy(IRenderNode * instance)1135 void RenderNodeDefaultCameraController::Destroy(IRenderNode* instance)
1136 {
1137 delete static_cast<RenderNodeDefaultCameraController*>(instance);
1138 }
1139 CORE3D_END_NAMESPACE()
1140