Hydra: Pass camera's custom croperties to render delegate

Makes it possible to read custom camera properties in a render delegate,
e.g with HdSceneDelegate::GetCameraParamValue().

Pull Request: https://projects.blender.org/blender/blender/pulls/138918
This commit is contained in:
Dawid-Kurek
2025-07-18 15:55:18 +02:00
committed by Brecht Van Lommel
parent 6aa9cc56a0
commit ccd619bdb2
7 changed files with 117 additions and 5 deletions

View File

@@ -165,6 +165,7 @@ set(SRC
if(WITH_HYDRA)
list(APPEND SRC
hydra/camera_delegate.cc
hydra/curves.cc
hydra/hydra_scene_delegate.cc
hydra/id.cc
@@ -179,6 +180,7 @@ if(WITH_HYDRA)
hydra/volume_modifier.cc
hydra/world.cc
hydra/camera_delegate.hh
hydra/curves.hh
hydra/hydra_scene_delegate.hh
hydra/id.hh

View File

@@ -0,0 +1,68 @@
/* SPDX-FileCopyrightText: 2025 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "camera_delegate.hh"
#include "DNA_ID.h"
#include "DNA_camera_types.h"
#include "DNA_scene_types.h"
#include "BKE_idprop.hh"
#include <pxr/imaging/hd/camera.h>
namespace blender::io::hydra {
static pxr::VtValue vt_value(const IDProperty *prop)
{
switch (prop->type) {
case IDP_INT:
return pxr::VtValue{IDP_Int(prop)};
case IDP_FLOAT:
return pxr::VtValue{IDP_Float(prop)};
case IDP_BOOLEAN:
return pxr::VtValue{bool(IDP_Bool(prop))};
}
return pxr::VtValue{};
}
CameraDelegate::CameraDelegate(pxr::HdRenderIndex *render_index, pxr::SdfPath const &delegate_id)
: pxr::HdxFreeCameraSceneDelegate{render_index, delegate_id}
{
}
void CameraDelegate::sync(const Scene *scene)
{
if (!scene || !scene->camera) {
return;
}
const Camera *camera = static_cast<const Camera *>(scene->camera->data);
if (camera_ == camera) {
return;
}
camera_ = camera;
GetRenderIndex().GetChangeTracker().MarkSprimDirty(GetCameraId(), pxr::HdCamera::DirtyParams);
}
void CameraDelegate::update(const ID *camera)
{
if (&camera_->id == camera) {
GetRenderIndex().GetChangeTracker().MarkSprimDirty(GetCameraId(), pxr::HdCamera::DirtyParams);
}
}
pxr::VtValue CameraDelegate::GetCameraParamValue(pxr::SdfPath const &id, pxr::TfToken const &key)
{
if (camera_ && camera_->id.properties) {
const IDProperty *prop = IDP_GetPropertyFromGroup(camera_->id.properties, key.GetText());
if (prop) {
return vt_value(prop);
}
}
return pxr::HdxFreeCameraSceneDelegate::GetCameraParamValue(id, key);
}
} // namespace blender::io::hydra

View File

@@ -0,0 +1,29 @@
/* SPDX-FileCopyrightText: 2025 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include <pxr/imaging/hdx/freeCameraSceneDelegate.h>
struct Camera;
struct ID;
struct Scene;
namespace blender::io::hydra {
class CameraDelegate : public pxr::HdxFreeCameraSceneDelegate {
public:
CameraDelegate(pxr::HdRenderIndex *render_index, pxr::SdfPath const &delegate_id);
~CameraDelegate() override = default;
void sync(const Scene *scene);
void update(const ID *camera);
pxr::VtValue GetCameraParamValue(pxr::SdfPath const &id, pxr::TfToken const &key) override;
private:
const Camera *camera_{nullptr};
};
} // namespace blender::io::hydra

View File

@@ -14,6 +14,7 @@
#include "BLI_listbase.h"
#include "BLI_set.hh"
#include "BLI_string.h"
#include "camera_delegate.hh"
#include "DEG_depsgraph_query.hh"
@@ -36,8 +37,11 @@ bool HydraSceneDelegate::ShadingSettings::operator==(const ShadingSettings &othe
HydraSceneDelegate::HydraSceneDelegate(pxr::HdRenderIndex *parent_index,
pxr::SdfPath const &delegate_id,
CameraDelegate *camera_delegate,
const bool use_materialx)
: HdSceneDelegate(parent_index, delegate_id), use_materialx(use_materialx)
: HdSceneDelegate(parent_index, delegate_id),
use_materialx(use_materialx),
camera_delegate_(camera_delegate)
{
instancer_data_ = std::make_unique<InstancerData>(this, instancer_prim_id());
world_data_ = std::make_unique<WorldData>(this, world_prim_id());
@@ -393,6 +397,10 @@ void HydraSceneDelegate::check_updates()
}
break;
}
case ID_CA: {
camera_delegate_->update(id);
break;
}
case ID_WO: {
if (shading_settings.use_scene_world && id->recalc & ID_RECALC_SHADING) {
do_update_world = true;

View File

@@ -29,6 +29,7 @@ namespace blender::io::hydra {
extern struct CLG_LogRef *LOG_HYDRA_SCENE;
class Engine;
class CameraDelegate;
class HydraSceneDelegate : public pxr::HdSceneDelegate {
friend ObjectData; /* has access to materials */
@@ -59,9 +60,12 @@ class HydraSceneDelegate : public pxr::HdSceneDelegate {
std::unique_ptr<InstancerData> instancer_data_;
std::unique_ptr<WorldData> world_data_;
CameraDelegate *camera_delegate_ = nullptr;
public:
HydraSceneDelegate(pxr::HdRenderIndex *parent_index,
pxr::SdfPath const &delegate_id,
CameraDelegate *camera_delegate,
bool use_materialx);
~HydraSceneDelegate() override = default;

View File

@@ -66,7 +66,7 @@ Engine::Engine(RenderEngine *bl_engine, const std::string &render_delegate_name)
}
render_index_.reset(pxr::HdRenderIndex::New(render_delegate_.Get(), hd_drivers));
free_camera_delegate_ = std::make_unique<pxr::HdxFreeCameraSceneDelegate>(
free_camera_delegate_ = std::make_unique<io::hydra::CameraDelegate>(
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("freeCamera"));
if (bl_engine->type->flag & RE_USE_GPU_CONTEXT && GPU_backend_get_type() == GPU_BACKEND_OPENGL) {
@@ -103,7 +103,7 @@ void Engine::sync(Depsgraph *depsgraph, bContext *context)
if (!hydra_scene_delegate_) {
pxr::SdfPath scene_path = pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene");
hydra_scene_delegate_ = std::make_unique<io::hydra::HydraSceneDelegate>(
render_index_.get(), scene_path, use_materialx);
render_index_.get(), scene_path, free_camera_delegate_.get(), use_materialx);
}
hydra_scene_delegate_->populate(depsgraph, context ? CTX_wm_view3d(context) : nullptr);
}
@@ -122,6 +122,7 @@ void Engine::sync(Depsgraph *depsgraph, bContext *context)
}
usd_scene_delegate_->populate(depsgraph);
}
free_camera_delegate_->sync(scene_);
}
void Engine::set_render_setting(const std::string &key, const pxr::VtValue &val)

View File

@@ -10,11 +10,11 @@
#include <pxr/imaging/hd/driver.h>
#include <pxr/imaging/hd/engine.h>
#include <pxr/imaging/hd/pluginRenderDelegateUniqueHandle.h>
#include <pxr/imaging/hdx/freeCameraSceneDelegate.h>
#include <pxr/imaging/hgi/hgi.h>
#include <pxr/usd/usd/stage.h>
#include <pxr/usdImaging/usdImaging/delegate.h>
#include "hydra/camera_delegate.hh"
#include "hydra/hydra_scene_delegate.hh"
#include "hydra/settings.hh"
#include "hydra/usd_scene_delegate.hh"
@@ -44,11 +44,11 @@ class Engine {
pxr::HdPluginRenderDelegateUniqueHandle render_delegate_;
std::unique_ptr<pxr::HdRenderIndex> render_index_;
std::unique_ptr<io::hydra::CameraDelegate> free_camera_delegate_;
std::unique_ptr<io::hydra::HydraSceneDelegate> hydra_scene_delegate_;
std::unique_ptr<io::hydra::USDSceneDelegate> usd_scene_delegate_;
std::unique_ptr<RenderTaskDelegate> render_task_delegate_;
std::unique_ptr<pxr::HdxFreeCameraSceneDelegate> free_camera_delegate_;
std::unique_ptr<LightTasksDelegate> light_tasks_delegate_;
std::unique_ptr<pxr::HdEngine> engine_;