• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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