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 "util/render_util.h"
17
18 #include <3d/intf_graphics_context.h>
19 #include <3d/render/intf_render_data_store_default_camera.h>
20 #include <core/intf_engine.h>
21 #include <core/json/json.h>
22 #include <core/namespace.h>
23 #include <render/device/intf_device.h>
24 #include <render/device/intf_gpu_resource_manager.h>
25 #include <render/intf_render_context.h>
26 #include <render/render_data_structures.h>
27
28 CORE3D_BEGIN_NAMESPACE()
29 using namespace BASE_NS;
30 using namespace CORE_NS;
31 using namespace RENDER_NS;
32
33 namespace {
34 constexpr const string_view SCENE_STR = "3drendernodegraphs://core3d_rng_scene.rng";
35 constexpr const string_view CAM_SCENE_LWRP_STR = "3drendernodegraphs://core3d_rng_cam_scene_lwrp.rng";
36 constexpr const string_view CAM_SCENE_LWRP_MSAA_STR = "3drendernodegraphs://core3d_rng_cam_scene_lwrp_msaa.rng";
37 constexpr const string_view CAM_SCENE_LWRP_MSAA_DEPTH_STR =
38 "3drendernodegraphs://core3d_rng_cam_scene_lwrp_msaa_depth.rng";
39 constexpr const string_view CAM_SCENE_LWRP_MSAA_GLES_STR =
40 "3drendernodegraphs://core3d_rng_cam_scene_lwrp_msaa_gles.rng";
41 constexpr const string_view CAM_SCENE_HDRP_STR = "3drendernodegraphs://core3d_rng_cam_scene_hdrp.rng";
42 constexpr const string_view CAM_SCENE_HDRP_MSAA_STR = "3drendernodegraphs://core3d_rng_cam_scene_hdrp_msaa.rng";
43 constexpr const string_view CAM_SCENE_HDRP_MSAA_DEPTH_STR =
44 "3drendernodegraphs://core3d_rng_cam_scene_hdrp_msaa_depth.rng";
45 constexpr const string_view CAM_SCENE_REFLECTION_STR = "3drendernodegraphs://core3d_rng_reflection_cam_scene.rng";
46 constexpr const string_view CAM_SCENE_REFLECTION_MSAA_STR =
47 "3drendernodegraphs://core3d_rng_reflection_cam_scene_msaa.rng";
48 constexpr const string_view CAM_SCENE_PRE_PASS_STR = "3drendernodegraphs://core3d_rng_cam_scene_pre_pass.rng";
49 constexpr const string_view CAM_SCENE_DEFERRED_STR = "3drendernodegraphs://core3d_rng_cam_scene_deferred.rng";
50 constexpr const string_view CAM_SCENE_POST_PROCESS_STR = "3drendernodegraphs://core3d_rng_cam_scene_post_process.rng";
51
52
53 constexpr const string_view RENDER_NODE_DEFAULT_CAMERA_CONTROLLER_STR = "RenderNodeDefaultCameraController";
54 constexpr const string_view RENDER_NODE_DEFAULT_MATERIAL_RENDER_SLOT_STR = "RenderNodeDefaultMaterialRenderSlot";
55
LoadRenderNodeGraph(IRenderNodeGraphLoader & rngLoader,const string_view rng)56 RenderNodeGraphDesc LoadRenderNodeGraph(IRenderNodeGraphLoader& rngLoader, const string_view rng)
57 {
58 IRenderNodeGraphLoader::LoadResult lr = rngLoader.Load(rng);
59 if (!lr.success) {
60 CORE_LOG_E("error loading render node graph: %s - error: %s", rng.data(), lr.error.data());
61 }
62 return lr.desc;
63 }
64
GetDefaultCameraControllerNode()65 inline RenderNodeDesc GetDefaultCameraControllerNode()
66 {
67 RenderNodeDesc rnd;
68 rnd.typeName = RENDER_NODE_DEFAULT_CAMERA_CONTROLLER_STR;
69 rnd.nodeName = "CORE3D_RN_CAM_CTRL";
70 rnd.nodeJson = "{\"typeName\" : \"RenderNodeDefaultCameraController\",\"nodeName\" : \"CORE3D_RN_CAM_CTRL\"}";
71 return rnd;
72 }
73
GetPodPostProcess(const string_view name)74 inline json::standalone_value GetPodPostProcess(const string_view name)
75 {
76 auto renderDataStore = json::standalone_value { json::standalone_value::object {} };
77 renderDataStore["dataStoreName"] = "RenderDataStorePod";
78 renderDataStore["typeName"] = "RenderDataStorePod"; // This is render data store TYPE_NAME
79 renderDataStore["configurationName"] = string(name);
80 return renderDataStore;
81 }
82
GetPostProcess(const string_view name)83 inline json::standalone_value GetPostProcess(const string_view name)
84 {
85 auto renderDataStore = json::standalone_value { json::standalone_value::object {} };
86 renderDataStore["dataStoreName"] = "RenderDataStorePostProcess";
87 renderDataStore["typeName"] = "RenderDataStorePostProcess"; // This is render data store TYPE_NAME
88 renderDataStore["configurationName"] = string(name);
89 return renderDataStore;
90 }
91
HasRenderDataStorePostProcess(const json::standalone_value & dataStore)92 inline bool HasRenderDataStorePostProcess(const json::standalone_value& dataStore)
93 {
94 if (const auto typeName = dataStore.find("typeName"); typeName) {
95 if (typeName->is_string() && (typeName->string_ == "RenderDataStorePostProcess")) {
96 return true;
97 }
98 }
99 return false;
100 }
101
GetCameraName(const RenderCamera & camera)102 inline string GetCameraName(const RenderCamera& camera)
103 {
104 return camera.name.empty() ? string(to_hex(camera.id)) : string(camera.name);
105 }
106
GetSceneName(const RenderScene & scene)107 inline string GetSceneName(const RenderScene& scene)
108 {
109 return scene.name.empty() ? string(to_hex(scene.id)) : string(scene.name);
110 }
111
FillCameraDescsData(const RenderCamera & renderCamera,const string & customCameraName,RenderNodeGraphDesc & desc)112 void FillCameraDescsData(const RenderCamera& renderCamera, const string& customCameraName, RenderNodeGraphDesc& desc)
113 {
114 // check for render compatibility for render node graph RenderNodeDefaultCameraController
115 if (!renderCamera.customRenderNodeGraphFile.empty()) {
116 bool forceInject = true;
117 for (const auto& rnRef : desc.nodes) {
118 if (rnRef.typeName == RENDER_NODE_DEFAULT_CAMERA_CONTROLLER_STR) {
119 forceInject = false;
120 break;
121 }
122 }
123 if (forceInject) {
124 for (size_t nodeIdx = 0; nodeIdx < desc.nodes.size(); ++nodeIdx) {
125 if (desc.nodes[nodeIdx].typeName == RENDER_NODE_DEFAULT_MATERIAL_RENDER_SLOT_STR) {
126 desc.nodes.insert(desc.nodes.begin() + int64_t(nodeIdx), GetDefaultCameraControllerNode());
127 #if (CORE3D_DEV_ENABLED == 1)
128 CORE_LOG_W("Injecting camera RenderNodeDefaultCameraController render node for compatibility");
129 #endif
130 break;
131 }
132 }
133 }
134 }
135 for (auto& rnRef : desc.nodes) {
136 json::standalone_value jsonVal = CORE_NS::json::parse(rnRef.nodeJson.data());
137 jsonVal["customCameraId"] = renderCamera.id; // cam id
138 jsonVal["customCameraName"] = customCameraName;
139 if (renderCamera.flags & RenderCamera::CAMERA_FLAG_REFLECTION_BIT) {
140 jsonVal["nodeFlags"] = 7u; // NOTE: hard coded
141 }
142 if (auto dataStore = jsonVal.find("renderDataStore"); dataStore) {
143 if (auto config = dataStore->find("configurationName"); config) {
144 if (!config->string_.empty()) {
145 const bool rpp = HasRenderDataStorePostProcess(*dataStore);
146 auto renderDataStore = rpp ? GetPostProcess(renderCamera.postProcessName)
147 : GetPodPostProcess(renderCamera.postProcessName);
148 jsonVal["renderDataStore"] = move(renderDataStore);
149 }
150 }
151 }
152 rnRef.nodeJson = to_string(jsonVal);
153 }
154 }
155
FillCameraPostProcessDescsData(const RenderCamera & renderCamera,const uint64_t baseCameraId,const string & customCameraName,const bool customPostProcess,RenderNodeGraphDesc & desc)156 void FillCameraPostProcessDescsData(const RenderCamera& renderCamera, const uint64_t baseCameraId,
157 const string& customCameraName, const bool customPostProcess, RenderNodeGraphDesc& desc)
158 {
159 for (auto& rnRef : desc.nodes) {
160 json::standalone_value jsonVal = CORE_NS::json::parse(rnRef.nodeJson.data());
161 // add camera info as well
162 jsonVal["customCameraId"] = renderCamera.id; // cam id
163 jsonVal["customCameraName"] = customCameraName;
164 jsonVal["multiviewBaseCameraId"] = baseCameraId;
165 if (auto dataStore = jsonVal.find("renderDataStore"); dataStore) {
166 if (auto config = dataStore->find("configurationName"); config) {
167 if (config->is_string() && (!config->string_.empty())) {
168 const bool rpp = customPostProcess || HasRenderDataStorePostProcess(*dataStore);
169 auto renderDataStore = rpp ? GetPostProcess(renderCamera.postProcessName)
170 : GetPodPostProcess(renderCamera.postProcessName);
171 jsonVal["renderDataStore"] = move(renderDataStore);
172 }
173 }
174 }
175 rnRef.nodeJson = to_string(jsonVal);
176 }
177 }
178 } // namespace
179
RenderUtil(IGraphicsContext & graphicsContext)180 RenderUtil::RenderUtil(IGraphicsContext& graphicsContext)
181 : context_(graphicsContext.GetRenderContext()), backendType_(context_.GetDevice().GetBackendType())
182 {
183 InitRenderNodeGraphs();
184 }
185
InitRenderNodeGraphs()186 void RenderUtil::InitRenderNodeGraphs()
187 {
188 IRenderNodeGraphManager& rngm = context_.GetRenderNodeGraphManager();
189 IRenderNodeGraphLoader& rngl = rngm.GetRenderNodeGraphLoader();
190
191 rngdScene_ = LoadRenderNodeGraph(rngl, SCENE_STR);
192 rngdCamLwrp_ = LoadRenderNodeGraph(rngl, CAM_SCENE_LWRP_STR);
193 rngdCamLwrpMsaa_ = LoadRenderNodeGraph(rngl, CAM_SCENE_LWRP_MSAA_STR);
194 rngdCamLwrpMsaaDepth_ = LoadRenderNodeGraph(rngl, CAM_SCENE_LWRP_MSAA_DEPTH_STR);
195 rngdCamLwrpMsaaGles_ = LoadRenderNodeGraph(rngl, CAM_SCENE_LWRP_MSAA_GLES_STR);
196 rngdCamHdr_ = LoadRenderNodeGraph(rngl, CAM_SCENE_HDRP_STR);
197 rngdCamHdrMsaa_ = LoadRenderNodeGraph(rngl, CAM_SCENE_HDRP_MSAA_STR);
198 rngdCamHdrMsaaDepth_ = LoadRenderNodeGraph(rngl, CAM_SCENE_HDRP_MSAA_DEPTH_STR);
199 rngdReflCam_ = LoadRenderNodeGraph(rngl, CAM_SCENE_REFLECTION_STR);
200 rngdReflCamMsaa_ = LoadRenderNodeGraph(rngl, CAM_SCENE_REFLECTION_MSAA_STR);
201 rngdCamPrePass_ = LoadRenderNodeGraph(rngl, CAM_SCENE_PRE_PASS_STR);
202
203 rngdDeferred_ = LoadRenderNodeGraph(rngl, CAM_SCENE_DEFERRED_STR);
204
205 rngdPostProcess_ = LoadRenderNodeGraph(rngl, CAM_SCENE_POST_PROCESS_STR);
206 }
207
SelectBaseDesc(const RenderCamera & renderCamera) const208 RenderNodeGraphDesc RenderUtil::SelectBaseDesc(const RenderCamera& renderCamera) const
209 {
210 if (!renderCamera.customRenderNodeGraphFile.empty()) {
211 // custom render node graph file given which is patched
212 IRenderNodeGraphLoader& rngl = context_.GetRenderNodeGraphManager().GetRenderNodeGraphLoader();
213 return LoadRenderNodeGraph(rngl, renderCamera.customRenderNodeGraphFile);
214 }
215
216 if (renderCamera.flags & RenderCamera::CAMERA_FLAG_REFLECTION_BIT) {
217 // check for msaa
218 return (renderCamera.flags & RenderCamera::CAMERA_FLAG_MSAA_BIT) ? rngdReflCamMsaa_ : rngdReflCam_;
219 }
220 if (renderCamera.flags & RenderCamera::CAMERA_FLAG_OPAQUE_BIT) {
221 return rngdCamPrePass_;
222 }
223 if (renderCamera.renderPipelineType == RenderCamera::RenderPipelineType::DEFERRED) {
224 return rngdDeferred_;
225 }
226 if (renderCamera.flags & RenderCamera::CAMERA_FLAG_MSAA_BIT) {
227 // NOTE: check for optimal GL(ES) render node graph if backbuffer is multisampled
228 const bool depthOutput =
229 ((renderCamera.flags & RenderCamera::CameraFlagBits::CAMERA_FLAG_OUTPUT_DEPTH_BIT) != 0U);
230 if (renderCamera.renderPipelineType != RenderCamera::RenderPipelineType::LIGHT_FORWARD) {
231 return depthOutput ? rngdCamHdrMsaaDepth_ : rngdCamHdrMsaa_;
232 }
233
234 if ((backendType_ == DeviceBackendType::VULKAN) ||
235 (renderCamera.flags & RenderCamera::CameraFlagBits::CAMERA_FLAG_CUSTOM_TARGETS_BIT)) {
236 return depthOutput ? rngdCamLwrpMsaaDepth_ : rngdCamLwrpMsaa_;
237 }
238 const auto& gpuResourceMgr = context_.GetDevice().GetGpuResourceManager();
239 // NOTE: special handling on msaa swapchain with GLES
240 // creates issues with multi-ECS cases and might need to be dropped
241 // Prefer assigning swapchain image to camera in this case
242 const RenderHandleReference imageHandle = gpuResourceMgr.GetImageHandle("CORE_DEFAULT_BACKBUFFER");
243 const GpuImageDesc imageDesc = gpuResourceMgr.GetImageDescriptor(imageHandle);
244 if ((renderCamera.flags & RenderCamera::CAMERA_FLAG_MAIN_BIT) && (imageDesc.sampleCountFlags > 1) &&
245 (!depthOutput)) {
246 #if (CORE3D_VALIDATION_ENABLED == 1)
247 CORE_LOG_ONCE_I("3d_util_depth_gles_mixing" + to_string(renderCamera.id),
248 "CORE3D_VALIDATION: GL(ES) Camera MSAA flags checked from CORE_DEFAULT_BACKBUFFER. "
249 "Prefer assigning swapchain handle to camera.");
250 #endif
251 return rngdCamLwrpMsaaGles_;
252 }
253 return depthOutput ? rngdCamLwrpMsaaDepth_ : rngdCamLwrpMsaa_;
254 }
255 if (renderCamera.renderPipelineType != RenderCamera::RenderPipelineType::LIGHT_FORWARD) {
256 return rngdCamHdr_;
257 }
258 return rngdCamLwrp_;
259 }
260
GetBasePostProcessDesc(const RenderCamera & renderCamera) const261 RenderNodeGraphDesc RenderUtil::GetBasePostProcessDesc(const RenderCamera& renderCamera) const
262 {
263 // light forward and opaque / pre-pass camera does not have separate post processes
264 if ((renderCamera.renderPipelineType != RenderCamera::RenderPipelineType::LIGHT_FORWARD) &&
265 ((renderCamera.flags & RenderCamera::CAMERA_FLAG_OPAQUE_BIT) == 0)) {
266 return rngdPostProcess_;
267 } else {
268 return {};
269 }
270 }
271
GetRenderNodeGraphDesc(const RenderScene & renderScene,const RenderCamera & renderCamera,const uint32_t flags) const272 RenderNodeGraphDesc RenderUtil::GetRenderNodeGraphDesc(
273 const RenderScene& renderScene, const RenderCamera& renderCamera, const uint32_t flags) const
274 {
275 const string customCameraName = GetCameraName(renderCamera);
276 RenderNodeGraphDesc desc = SelectBaseDesc(renderCamera);
277 // process
278 desc.renderNodeGraphName = renderScene.name + to_hex(renderCamera.id);
279 FillCameraDescsData(renderCamera, customCameraName, desc);
280 return desc;
281 }
282
GetRenderNodeGraphDescs(const RenderScene & renderScene,const RenderCamera & renderCamera,const uint32_t flags,const array_view<const RenderCamera> multiviewCameras) const283 IRenderUtil::CameraRenderNodeGraphDescs RenderUtil::GetRenderNodeGraphDescs(const RenderScene& renderScene,
284 const RenderCamera& renderCamera, const uint32_t flags, const array_view<const RenderCamera> multiviewCameras) const
285 {
286 // Gets RenderNodeGraphDescs for camera and patches
287 // 1. With built-in RNGs
288 // * Select RNG for camera
289 // * Select RNG for camera post process (if not LIGHT_FORWARD)
290 // 2. With built-in RNG for camera and custom for post process
291 // * Select RNG for camera
292 // * Load RNG for camera post process
293 // 3. With custom RNG for camera
294 // * Load RNG for camera
295 // * Load RNG for camera post process, only if custom given
296 // NOTE: special opaque / pre-pass camera (transmission) has built-in post process in RNG
297
298 const string customCameraName = GetCameraName(renderCamera);
299 IRenderUtil::CameraRenderNodeGraphDescs descs;
300 // process camera
301 {
302 auto& desc = descs.camera;
303 desc = SelectBaseDesc(renderCamera);
304 desc.renderNodeGraphName = renderScene.name + to_hex(renderCamera.id);
305 FillCameraDescsData(renderCamera, customCameraName, desc);
306 }
307 // process post process
308 // NOTE: we do not add base post process render node graph to custom camera render node graphs
309 {
310 // NOTE: currently there are separate paths for new post process configurations and old
311 auto& desc = descs.postProcess;
312 const bool customPostProcess = !renderCamera.customPostProcessRenderNodeGraphFile.empty();
313 if (customPostProcess) {
314 IRenderNodeGraphLoader& rngl = context_.GetRenderNodeGraphManager().GetRenderNodeGraphLoader();
315 desc = LoadRenderNodeGraph(rngl, renderCamera.customPostProcessRenderNodeGraphFile);
316 } else if (renderCamera.customRenderNodeGraphFile.empty()) {
317 // only fetched when using built-in camera RNGs
318 desc = GetBasePostProcessDesc(renderCamera);
319 }
320 if (!desc.nodes.empty()) {
321 desc.renderNodeGraphName = renderScene.name + to_hex(renderCamera.id);
322 FillCameraPostProcessDescsData(
323 renderCamera, RenderSceneDataConstants::INVALID_ID, customCameraName, customPostProcess, desc);
324 }
325 #if (CORE3D_VALIDATION_ENABLED == 1)
326 if (renderCamera.multiViewCameraCount != static_cast<uint32_t>(multiviewCameras.size())) {
327 CORE_LOG_W("CORE3D_VALIDATION: Multi-view camera count mismatch in render node graph creation.");
328 }
329 #endif
330 // multi-view camera post processes
331 if (renderCamera.multiViewCameraCount == static_cast<uint32_t>(multiviewCameras.size())) {
332 #if (CORE3D_VALIDATION_ENABLED == 1)
333 if (!renderCamera.customPostProcessRenderNodeGraphFile.empty()) {
334 CORE_LOG_W("CORE3D_VALIDATION: Multi-view camera custom post process render node graph not supported.");
335 }
336 #endif
337 CORE_ASSERT(descs.multiViewCameraCount <= countof(descs.multiViewCameraPostProcesses));
338 descs.multiViewCameraCount = renderCamera.multiViewCameraCount;
339 for (size_t mvIdx = 0; mvIdx < descs.multiViewCameraCount; ++mvIdx) {
340 const auto& mvCameraRef = multiviewCameras[mvIdx];
341 auto& ppDesc = descs.multiViewCameraPostProcesses[mvIdx];
342 ppDesc = GetBasePostProcessDesc(mvCameraRef);
343 if (!ppDesc.nodes.empty()) {
344 const string ppCustomCameraName = GetCameraName(mvCameraRef);
345 ppDesc.renderNodeGraphName = renderScene.name + to_hex(mvCameraRef.id);
346 FillCameraPostProcessDescsData(mvCameraRef, renderCamera.id, ppCustomCameraName, false, ppDesc);
347 }
348 }
349 }
350 }
351
352 return descs;
353 }
354
GetRenderNodeGraphDescs(const RenderScene & renderScene,const RenderCamera & renderCamera,const uint32_t flags) const355 IRenderUtil::CameraRenderNodeGraphDescs RenderUtil::GetRenderNodeGraphDescs(
356 const RenderScene& renderScene, const RenderCamera& renderCamera, const uint32_t flags) const
357 {
358 return GetRenderNodeGraphDescs(renderScene, renderCamera, flags, {});
359 }
360
GetRenderNodeGraphDesc(const RenderScene & renderScene,const uint32_t flags) const361 RenderNodeGraphDesc RenderUtil::GetRenderNodeGraphDesc(const RenderScene& renderScene, const uint32_t flags) const
362 {
363 RenderNodeGraphDesc desc;
364 if (!renderScene.customRenderNodeGraphFile.empty()) {
365 // custom render node graph file given which is patched
366 IRenderNodeGraphLoader& rngl = context_.GetRenderNodeGraphManager().GetRenderNodeGraphLoader();
367 desc = LoadRenderNodeGraph(rngl, renderScene.customRenderNodeGraphFile);
368 } else {
369 desc = rngdScene_;
370 }
371 const string customSceneName = GetSceneName(renderScene);
372 const auto sceneIdStr = to_hex(renderScene.id);
373 const auto combinedStr = renderScene.name + sceneIdStr;
374 desc.renderNodeGraphName = combinedStr;
375 for (auto& rnRef : desc.nodes) {
376 json::standalone_value jsonVal = CORE_NS::json::parse(rnRef.nodeJson.data());
377 jsonVal[string_view("customId")] = renderScene.id; // cam id
378 jsonVal[string_view("customName")] = customSceneName;
379 rnRef.nodeJson = to_string(jsonVal);
380 }
381 return desc;
382 }
383
GetRenderNodeGraphDesc(const RenderScene & renderScene,const string & rngFile,const uint32_t flags) const384 RenderNodeGraphDesc RenderUtil::GetRenderNodeGraphDesc(
385 const RenderScene& renderScene, const string& rngFile, const uint32_t flags) const
386 {
387 RenderNodeGraphDesc desc;
388 if (!rngFile.empty()) {
389 // custom render node graph file given which is patched
390 IRenderNodeGraphLoader& rngl = context_.GetRenderNodeGraphManager().GetRenderNodeGraphLoader();
391 desc = LoadRenderNodeGraph(rngl, rngFile);
392 } else {
393 desc = rngdScene_;
394 }
395 const string customSceneName = GetSceneName(renderScene);
396 const auto sceneIdStr = to_hex(renderScene.id);
397 const auto combinedStr = renderScene.name + sceneIdStr;
398 desc.renderNodeGraphName = combinedStr;
399 for (auto& rnRef : desc.nodes) {
400 json::standalone_value jsonVal = CORE_NS::json::parse(rnRef.nodeJson.data());
401 jsonVal[string_view("customId")] = renderScene.id;
402 jsonVal[string_view("customName")] = customSceneName;
403 rnRef.nodeJson = to_string(jsonVal);
404 }
405 return desc;
406 }
407
UseCustomRng(const BASE_NS::string & uri)408 void RenderUtil::UseCustomRng(const BASE_NS::string& uri)
409 {
410 IRenderNodeGraphManager& rngm = context_.GetRenderNodeGraphManager();
411 IRenderNodeGraphLoader& rngl = rngm.GetRenderNodeGraphLoader();
412 rngdCamLwrp_ = LoadRenderNodeGraph(rngl, uri);
413 }
414
UseCustomRngGroup(const CustomRngGroup & rngGroup)415 void RenderUtil::UseCustomRngGroup(const CustomRngGroup& rngGroup)
416 {
417 // Future: provide all kinds of custom rngs
418 IRenderNodeGraphManager& rngm = context_.GetRenderNodeGraphManager();
419 IRenderNodeGraphLoader& rngl = rngm.GetRenderNodeGraphLoader();
420 if (!rngGroup.lwrp.empty()) {
421 rngdCamLwrp_ = LoadRenderNodeGraph(rngl, rngGroup.lwrp);
422 }
423 if (!rngGroup.lwrpMsaa.empty()) {
424 rngdCamLwrpMsaa_ = LoadRenderNodeGraph(rngl, rngGroup.lwrpMsaa);
425 }
426 if (!rngGroup.hdrp.empty()) {
427 rngdCamHdr_ = LoadRenderNodeGraph(rngl, rngGroup.hdrp);
428 }
429 if (!rngGroup.hdrpMsaa.empty()) {
430 rngdCamHdrMsaa_ = LoadRenderNodeGraph(rngl, rngGroup.hdrpMsaa);
431 }
432 }
433
434 CORE3D_END_NAMESPACE()
435