Export volumes from object modifier (quick effect) #62

Merged
Bogdan Nagirniak merged 28 commits from BLEN-448 into hydra-render 2023-07-20 23:49:25 +02:00
27 changed files with 318 additions and 405 deletions
Showing only changes of commit 3e609b0a40 - Show all commits

View File

@ -88,8 +88,8 @@ set(SRC
render_task_delegate.cc
render_task_delegate.h
simple_light_task_delegate.cc
simple_light_task_delegate.h
light_tasks_delegate.cc
light_tasks_delegate.h
scene_delegate/blender_scene_delegate.cc
scene_delegate/blender_scene_delegate.h

View File

@ -53,9 +53,8 @@ Engine::Engine(RenderEngine *bl_engine, const std::string &render_delegate_name)
render_task_delegate_ = std::make_unique<RenderTaskDelegate>(
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("renderTask"));
if (render_delegate_name == "HdStormRendererPlugin") {
simple_light_task_delegate_ = std::make_unique<SimpleLightTaskDelegate>(
render_index_.get(),
pxr::SdfPath::AbsoluteRootPath().AppendElementString("simpleLightTask"));
light_tasks_delegate_ = std::make_unique<LightTasksDelegate>(
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("lightTasks"));
}
engine_ = std::make_unique<pxr::HdEngine>();

View File

@ -17,8 +17,8 @@
#include "CLG_log.h"
#include "light_tasks_delegate.h"
#include "render_task_delegate.h"
#include "simple_light_task_delegate.h"
#include "scene_delegate/blender_scene_delegate.h"
#include "scene_delegate/usd_scene_delegate.hh"
@ -57,7 +57,7 @@ class Engine {
std::unique_ptr<RenderTaskDelegate> render_task_delegate_;
std::unique_ptr<pxr::HdxFreeCameraSceneDelegate> free_camera_delegate_;
std::unique_ptr<SimpleLightTaskDelegate> simple_light_task_delegate_;
std::unique_ptr<LightTasksDelegate> light_tasks_delegate_;
std::unique_ptr<pxr::HdEngine> engine_;
};

View File

@ -106,10 +106,10 @@ void FinalEngine::prepare_for_render(Depsgraph *depsgraph)
free_camera_delegate_->SetCamera(camera);
render_task_delegate_->set_camera_and_viewport(
free_camera_delegate_->GetCameraId(), pxr::GfVec4d(0, 0, resolution_[0], resolution_[1]));
if (simple_light_task_delegate_) {
simple_light_task_delegate_->set_camera_path(free_camera_delegate_->GetCameraId());
tasks_.push_back(simple_light_task_delegate_->get_task());
if (light_tasks_delegate_) {
light_tasks_delegate_->set_camera_and_viewport(
free_camera_delegate_->GetCameraId(), pxr::GfVec4d(0, 0, resolution_[0], resolution_[1]));
tasks_ = light_tasks_delegate_->get_tasks();
}
tasks_.push_back(render_task_delegate_->get_task());
@ -149,20 +149,6 @@ void FinalEngineGPU::render(Depsgraph *depsgraph)
float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
/* Workaround Storm rendering with transparent background. Does not currently work for
* USD, and should probably be optional depending on the Blender film transparency setting. */
if (hydra_scene_delegate_ && render_delegate_name == "HdStormRendererPlugin") {
pxr::VtValue world_color = hydra_scene_delegate_->GetLightParamValue(
hydra_scene_delegate_->GetDelegateID().AppendElementString("World"),
pxr::HdLightTokens->color);
if (!world_color.IsEmpty()) {
auto &c = world_color.Get<pxr::GfVec3f>();
clear_color[0] = c[0];
clear_color[1] = c[1];
clear_color[2] = c[2];
}
}
GPU_framebuffer_clear_color_depth(framebuffer, clear_color, 1.0f);
/* Important: we have to create and bind at least one Vertex Array Object (VAO) before render

View File

@ -0,0 +1,58 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
#include <pxr/imaging/hdx/simpleLightTask.h>
#include <pxr/imaging/hdx/skydomeTask.h>
#include "light_tasks_delegate.h"
namespace blender::render::hydra {
LightTasksDelegate::LightTasksDelegate(pxr::HdRenderIndex *parent_index,
pxr::SdfPath const &delegate_id)
: pxr::HdSceneDelegate(parent_index, delegate_id)
{
skydome_task_id_ = GetDelegateID().AppendElementString("simpleLightTask");
simple_task_id_ = GetDelegateID().AppendElementString("skydomeTask");
GetRenderIndex().InsertTask<pxr::HdxSkydomeTask>(this, skydome_task_id_);
GetRenderIndex().InsertTask<pxr::HdxSimpleLightTask>(this, simple_task_id_);
}
pxr::HdTaskSharedPtrVector LightTasksDelegate::get_tasks()
{
/*Note that this task is intended to be the first "Render Task",
so that the AOV's are properly cleared, however it
does not spawn a HdRenderPass.*/
return {GetRenderIndex().GetTask(skydome_task_id_), GetRenderIndex().GetTask(simple_task_id_)};
}
void LightTasksDelegate::set_camera_and_viewport(pxr::SdfPath const &camera_id,
pxr::GfVec4d const &viewport)
{
if (simple_task_params_.cameraPath != camera_id) {
simple_task_params_.cameraPath = camera_id;
GetRenderIndex().GetChangeTracker().MarkTaskDirty(simple_task_id_,
pxr::HdChangeTracker::DirtyParams);
}
if (skydome_task_params_.viewport != viewport || skydome_task_params_.camera != camera_id) {
skydome_task_params_.viewport = viewport;
skydome_task_params_.camera = camera_id;
GetRenderIndex().GetChangeTracker().MarkTaskDirty(skydome_task_id_,
pxr::HdChangeTracker::DirtyParams);
}
}
pxr::VtValue LightTasksDelegate::Get(pxr::SdfPath const &id, pxr::TfToken const &key)
{
if (key == pxr::HdTokens->params) {
if (id == simple_task_id_) {
return pxr::VtValue(simple_task_params_);
}
else if (id == skydome_task_id_) {
return pxr::VtValue(skydome_task_params_);
}
}
return pxr::VtValue();
}
} // namespace blender::render::hydra

View File

@ -0,0 +1,30 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
#pragma once
#include <pxr/imaging/hd/sceneDelegate.h>
#include <pxr/imaging/hdx/renderSetupTask.h>
#include <pxr/imaging/hdx/simpleLightTask.h>
namespace blender::render::hydra {
class LightTasksDelegate : public pxr::HdSceneDelegate {
public:
LightTasksDelegate(pxr::HdRenderIndex *parentIndex, pxr::SdfPath const &delegate_id);
~LightTasksDelegate() override = default;
pxr::HdTaskSharedPtrVector get_tasks();
void set_camera_and_viewport(pxr::SdfPath const &camera_id, pxr::GfVec4d const &viewport);
/* Delegate methods */
pxr::VtValue Get(pxr::SdfPath const &id, pxr::TfToken const &key) override;
private:
pxr::SdfPath simple_task_id_;
pxr::SdfPath skydome_task_id_;
pxr::HdxSimpleLightTaskParams simple_task_params_;
pxr::HdxRenderTaskParams skydome_task_params_;
};
} // namespace blender::render::hydra

View File

@ -10,11 +10,9 @@ namespace blender::render::hydra {
void PreviewEngine::render(Depsgraph *depsgraph)
{
prepare_for_render(depsgraph);
render_task_delegate_->set_renderer_aov(pxr::HdAovTokens->color);
{
/* Release the GIL before calling into hydra, in case any hydra plugins call into python. */
engine_->Execute(render_index_.get(), &tasks_);
}
std::vector<float> &pixels = render_images_["Combined"];
while (true) {

View File

@ -45,7 +45,7 @@ pxr::HdBasisCurvesTopology BlenderSceneDelegate::GetBasisCurvesTopology(pxr::Sdf
{
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText());
CurvesData *c_data = curves_data(id);
return c_data->curves_topology(id);
return c_data->topology();
};
pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id)
@ -68,21 +68,9 @@ pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id)
pxr::VtValue BlenderSceneDelegate::Get(pxr::SdfPath const &id, pxr::TfToken const &key)
{
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s, %s", id.GetText(), key.GetText());
MeshData *m_data = mesh_data(id);
if (m_data) {
return m_data->get_data(id, key);
}
CurvesData *c_data = curves_data(id);
if (c_data) {
return c_data->get_data(id, key);
}
VolumeData *v_data = volume_data(id);
if (v_data) {
return v_data->get_data(id, key);
}
ObjectData *obj_data = object_data(id);
if (obj_data) {
return obj_data->get_data(key);
return obj_data->get_data(id, key);
}
MaterialData *mat_data = material_data(id);
if (mat_data) {
@ -103,9 +91,6 @@ pxr::VtValue BlenderSceneDelegate::GetLightParamValue(pxr::SdfPath const &id,
if (l_data) {
return l_data->get_data(key);
}
if (id == world_prim_id()) {
return world_data_->get_data(key);
}
return pxr::VtValue();
}
@ -131,17 +116,9 @@ pxr::HdPrimvarDescriptorVector BlenderSceneDelegate::GetPrimvarDescriptors(
pxr::SdfPath BlenderSceneDelegate::GetMaterialId(pxr::SdfPath const &rprim_id)
{
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", rprim_id.GetText());
MeshData *m_data = mesh_data(rprim_id);
if (m_data) {
return m_data->material_id(rprim_id);
}
CurvesData *c_data = curves_data(rprim_id);
if (c_data) {
return c_data->material_id();
}
VolumeData *v_data = volume_data(rprim_id);
if (v_data) {
return v_data->material_id();
ObjectData *obj_data = object_data(rprim_id);
if (obj_data) {
return obj_data->material_id(rprim_id);
}
return pxr::SdfPath();
}
@ -289,6 +266,10 @@ pxr::SdfPath BlenderSceneDelegate::world_prim_id() const
ObjectData *BlenderSceneDelegate::object_data(pxr::SdfPath const &id) const
{
if (id == world_prim_id()) {
return world_data_.get();
}
pxr::SdfPath p_id = (id.GetName().find("SM_") == 0 || id.GetName().find("VF_") == 0) ?
id.GetParentPath() :
id;
@ -296,6 +277,7 @@ ObjectData *BlenderSceneDelegate::object_data(pxr::SdfPath const &id) const
if (obj_data) {
return obj_data->get();
}
InstancerData *i_data = instancer_data(p_id, true);
if (i_data) {
return i_data->object_data(id);
@ -490,7 +472,6 @@ void BlenderSceneDelegate::update_collection()
}
else {
obj_data = objects_.lookup_or_add(id, ObjectData::create(this, object, id)).get();
obj_data->init();
obj_data->insert();
}
}

View File

@ -29,10 +29,7 @@ extern struct CLG_LogRef *LOG_RENDER_HYDRA_SCENE;
class Engine;
class BlenderSceneDelegate : public pxr::HdSceneDelegate {
friend ObjectData; /* has access to instances */
friend CurvesData; /* has access to materials */
friend VolumeData; /* has access to materials */
friend MeshData; /* has access to materials */
friend ObjectData; /* has access to materials */
friend MaterialData; /* has access to objects and instancers */
public:

View File

@ -20,7 +20,7 @@ CurvesData::CurvesData(BlenderSceneDelegate *scene_delegate,
void CurvesData::init()
{
ID_LOG(1, "");
ID_LOGN(1, "");
Object *object = (Object *)id;
write_curves((Curves *)object->data);
@ -30,14 +30,14 @@ void CurvesData::init()
void CurvesData::insert()
{
ID_LOG(1, "");
ID_LOGN(1, "");
scene_delegate_->GetRenderIndex().InsertRprim(
pxr::HdPrimTypeTokens->basisCurves, scene_delegate_, prim_id);
}
void CurvesData::remove()
{
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 1, "%s", prim_id.GetText());
ID_LOG(1, "");
scene_delegate_->GetRenderIndex().RemoveRprim(prim_id);
}
@ -63,10 +63,10 @@ void CurvesData::update()
}
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(prim_id, bits);
ID_LOG(1, "");
ID_LOGN(1, "");
}
pxr::VtValue CurvesData::get_data(pxr::SdfPath const & /* id */, pxr::TfToken const &key) const
pxr::VtValue CurvesData::get_data(pxr::TfToken const &key) const
{
if (key == pxr::HdTokens->points) {
return pxr::VtValue(vertices_);
@ -80,18 +80,22 @@ pxr::VtValue CurvesData::get_data(pxr::SdfPath const & /* id */, pxr::TfToken co
return pxr::VtValue();
}
bool CurvesData::update_visibility()
pxr::SdfPath CurvesData::material_id() const
{
bool ret = ObjectData::update_visibility();
if (ret) {
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(
prim_id, pxr::HdChangeTracker::DirtyVisibility);
ID_LOG(1, "");
if (!mat_data_) {
return pxr::SdfPath();
}
return ret;
return mat_data_->prim_id;
}
pxr::HdBasisCurvesTopology CurvesData::curves_topology(pxr::SdfPath const & /* id */) const
void CurvesData::available_materials(Set<pxr::SdfPath> &paths) const
{
if (mat_data_ && !mat_data_->prim_id.IsEmpty()) {
paths.add(mat_data_->prim_id);
}
}
pxr::HdBasisCurvesTopology CurvesData::topology() const
{
return pxr::HdBasisCurvesTopology(pxr::HdTokens->linear,
pxr::TfToken(),
@ -122,19 +126,15 @@ pxr::HdPrimvarDescriptorVector CurvesData::primvar_descriptors(
return primvars;
}
pxr::SdfPath CurvesData::material_id() const
void CurvesData::write_materials()
{
if (!mat_data_) {
return pxr::SdfPath();
}
return mat_data_->prim_id;
}
void CurvesData::available_materials(Set<pxr::SdfPath> &paths) const
{
if (mat_data_ && !mat_data_->prim_id.IsEmpty()) {
paths.add(mat_data_->prim_id);
Object *object = (Object *)id;
Material *mat = nullptr;
/* TODO: Using only first material. Add support for multimaterial. */
if (BKE_object_material_count_eval(object) > 0) {
mat = BKE_object_material_get_eval(object, 0);
}
mat_data_ = get_or_create_material(mat);
}
void CurvesData::write_curves(Curves *curves)
@ -178,28 +178,4 @@ void CurvesData::write_uv_maps(Curves *curves)
}
}
void CurvesData::write_materials()
{
Object *object = (Object *)id;
Material *mat = nullptr;
/* TODO: Using only first material. Add support for multimaterial. */
if (BKE_object_material_count_eval(object) > 0) {
mat = BKE_object_material_get_eval(object, 0);
}
if (!mat) {
mat_data_ = nullptr;
return;
}
pxr::SdfPath p_id = scene_delegate_->material_prim_id(mat);
mat_data_ = scene_delegate_->material_data(p_id);
if (!mat_data_) {
scene_delegate_->materials_.add_new(
p_id, std::make_unique<MaterialData>(scene_delegate_, mat, p_id));
mat_data_ = scene_delegate_->material_data(p_id);
mat_data_->init();
mat_data_->insert();
}
}
} // namespace blender::render::hydra

View File

@ -24,18 +24,19 @@ class CurvesData : public ObjectData {
void remove() override;
void update() override;
pxr::VtValue get_data(pxr::SdfPath const &id, pxr::TfToken const &key) const;
bool update_visibility() override;
pxr::VtValue get_data(pxr::TfToken const &key) const override;
pxr::SdfPath material_id() const override;
void available_materials(Set<pxr::SdfPath> &paths) const override;
pxr::HdBasisCurvesTopology curves_topology(pxr::SdfPath const &id) const;
pxr::HdBasisCurvesTopology topology() const;
pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation) const;
pxr::SdfPath material_id() const;
void available_materials(Set<pxr::SdfPath> &paths) const;
protected:
void write_materials() override;
private:
void write_curves(Curves *curves);
void write_uv_maps(Curves *curves);
void write_materials();
pxr::VtIntArray curve_vertex_counts_;
pxr::VtVec3fArray vertices_;

View File

@ -12,9 +12,4 @@ IdData::IdData(BlenderSceneDelegate *scene_delegate, ID *id, pxr::SdfPath const
{
}
pxr::VtValue IdData::get_data(pxr::TfToken const & /*key*/) const
{
return pxr::VtValue();
}
} // namespace blender::render::hydra

View File

@ -13,14 +13,14 @@
template<> struct blender::DefaultHash<pxr::SdfPath> {
uint64_t operator()(const pxr::SdfPath &value) const
{
return pxr::SdfPath::Hash()(value);
return (uint64_t)value.GetHash();
}
};
template<> struct blender::DefaultHash<pxr::TfToken> {
uint64_t operator()(const pxr::TfToken &value) const
{
return pxr::TfHash()(value);
return (uint64_t)value.Hash();
}
};
@ -38,8 +38,7 @@ class IdData {
virtual void remove() = 0;
virtual void update() = 0;
virtual pxr::VtValue get_data(pxr::TfToken const &key) const;
template<class T> const T get_data(pxr::TfToken const &key) const;
virtual pxr::VtValue get_data(pxr::TfToken const &key) const = 0;
ID *id;
pxr::SdfPath prim_id;
@ -48,12 +47,10 @@ class IdData {
BlenderSceneDelegate *scene_delegate_;
};
template<class T> const T IdData::get_data(pxr::TfToken const &key) const
{
return get_data(key).Get<T>();
}
#define ID_LOG(level, msg, ...) \
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, level, "%s: " msg, prim_id.GetText(), ##__VA_ARGS__);
#define ID_LOGN(level, msg, ...) \
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, \
level, \
"%s (%s): " msg, \

View File

@ -24,7 +24,7 @@ LightData::LightData(BlenderSceneDelegate *scene_delegate,
void LightData::init()
{
ID_LOG(1, "");
ID_LOGN(1, "");
Light *light = (Light *)((Object *)id)->data;
data_.clear();
@ -97,13 +97,13 @@ void LightData::init()
void LightData::insert()
{
ID_LOG(1, "");
ID_LOGN(1, "");
scene_delegate_->GetRenderIndex().InsertSprim(prim_type_, scene_delegate_, prim_id);
}
void LightData::remove()
{
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 1, "%s", prim_id.GetText());
ID_LOG(1, "");
scene_delegate_->GetRenderIndex().RemoveSprim(prim_type_, prim_id);
}
@ -128,13 +128,13 @@ void LightData::update()
}
if (bits != pxr::HdChangeTracker::Clean) {
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id, bits);
ID_LOG(1, "");
ID_LOGN(1, "");
}
}
pxr::VtValue LightData::get_data(pxr::TfToken const &key) const
{
ID_LOG(3, "%s", key.GetText());
ID_LOGN(3, "%s", key.GetText());
auto it = data_.find(key);
if (it != data_.end()) {
return pxr::VtValue(it->second);
@ -148,17 +148,6 @@ pxr::VtValue LightData::get_data(pxr::TfToken const &key) const
return pxr::VtValue();
}
bool LightData::update_visibility()
{
bool ret = ObjectData::update_visibility();
if (ret) {
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id,
pxr::HdLight::DirtyParams);
ID_LOG(1, "");
}
return ret;
}
pxr::TfToken LightData::prim_type(Light *light)
{
switch (light->type) {

View File

@ -27,9 +27,8 @@ class LightData : public ObjectData {
void update() override;
pxr::VtValue get_data(pxr::TfToken const &key) const override;
bool update_visibility() override;
private:
protected:
pxr::TfToken prim_type(Light *light);
std::map<pxr::TfToken, pxr::VtValue> data_;

View File

@ -31,7 +31,7 @@ MaterialData::MaterialData(BlenderSceneDelegate *scene_delegate,
void MaterialData::init()
{
ID_LOG(1, "");
ID_LOGN(1, "");
double_sided = (((Material *)id)->blend_flag & MA_BL_CULL_BACKFACE) == 0;
export_mtlx();
@ -42,20 +42,20 @@ void MaterialData::init()
void MaterialData::insert()
{
ID_LOG(1, "");
ID_LOGN(1, "");
scene_delegate_->GetRenderIndex().InsertSprim(
pxr::HdPrimTypeTokens->material, scene_delegate_, prim_id);
}
void MaterialData::remove()
{
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 1, "%s", prim_id.GetText());
ID_LOG(1, "");
scene_delegate_->GetRenderIndex().RemoveSprim(pxr::HdPrimTypeTokens->material, prim_id);
}
void MaterialData::update()
{
ID_LOG(1, "");
ID_LOGN(1, "");
bool prev_double_sided = double_sided;
init();
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id,
@ -74,7 +74,7 @@ void MaterialData::update()
pxr::VtValue MaterialData::get_data(pxr::TfToken const &key) const
{
if (key == scene_delegate_->settings.mx_filename_key) {
ID_LOG(3, "%s", key.GetText());
ID_LOGN(3, "%s", key.GetText());
if (!mtlx_path_.GetResolvedPath().empty()) {
return pxr::VtValue(mtlx_path_);
}
@ -149,12 +149,12 @@ void MaterialData::export_mtlx()
PyGILState_Release(gstate);
mtlx_path_ = pxr::SdfAssetPath(path, path);
ID_LOG(1, "mtlx=%s", mtlx_path_.GetResolvedPath().c_str());
ID_LOGN(1, "mtlx=%s", mtlx_path_.GetResolvedPath().c_str());
}
void MaterialData::write_material_network_map()
{
ID_LOG(1, "");
ID_LOGN(1, "");
if (mtlx_path_.GetResolvedPath().empty()) {
material_network_map_ = pxr::VtValue();
return;

View File

@ -27,7 +27,7 @@ MeshData::MeshData(BlenderSceneDelegate *scene_delegate,
void MeshData::init()
{
ID_LOG(1, "");
ID_LOGN(1, "");
Object *object = (Object *)id;
Mesh *mesh = BKE_object_to_mesh(nullptr, object, false);
@ -42,15 +42,15 @@ void MeshData::init()
void MeshData::insert()
{
/* Empty, because insertion of rprims happen in write_submeshes() */
ID_LOGN(1, "");
update_prims();
}
void MeshData::remove()
{
for (int i = 0; i < submeshes_.size(); ++i) {
scene_delegate_->GetRenderIndex().RemoveRprim(submesh_prim_id(i));
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 1, "%s: %d", prim_id.GetText(), i);
}
ID_LOG(1, "");
submeshes_.clear();
update_prims();
}
void MeshData::update()
@ -58,6 +58,7 @@ void MeshData::update()
Object *object = (Object *)id;
if ((id->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) {
init();
update_prims();
return;
}
@ -77,35 +78,45 @@ void MeshData::update()
for (int i = 0; i < submeshes_.size(); ++i) {
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(submesh_prim_id(i), bits);
ID_LOG(1, "%d", i);
ID_LOGN(1, "%d", i);
}
}
pxr::VtValue MeshData::get_data(pxr::SdfPath const &id, pxr::TfToken const &key) const
pxr::VtValue MeshData::get_data(pxr::TfToken const &key) const
{
if (key == pxr::HdTokens->points) {
return pxr::VtValue(vertices_);
}
else if (key == pxr::HdTokens->normals) {
return pxr::VtValue();
}
pxr::VtValue MeshData::get_data(pxr::SdfPath const &id, pxr::TfToken const &key) const
{
if (key == pxr::HdTokens->normals) {
return pxr::VtValue(submesh(id).normals);
}
else if (key == pxr::tokens_->st) {
return pxr::VtValue(submesh(id).uvs);
}
return pxr::VtValue();
return get_data(key);
}
bool MeshData::update_visibility()
pxr::SdfPath MeshData::material_id(pxr::SdfPath const &id) const
{
bool ret = ObjectData::update_visibility();
if (ret) {
for (int i = 0; i < submeshes_.size(); ++i) {
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(
submesh_prim_id(i), pxr::HdChangeTracker::DirtyVisibility);
ID_LOG(1, "%d", i);
const SubMesh &sm = submesh(id);
if (!sm.mat_data) {
return pxr::SdfPath();
}
return sm.mat_data->prim_id;
}
void MeshData::available_materials(Set<pxr::SdfPath> &paths) const
{
for (auto &sm : submeshes_) {
if (sm.mat_data && !sm.mat_data->prim_id.IsEmpty()) {
paths.add(sm.mat_data->prim_id);
}
}
return ret;
}
pxr::HdMeshTopology MeshData::mesh_topology(pxr::SdfPath const &id) const
@ -139,15 +150,6 @@ pxr::HdPrimvarDescriptorVector MeshData::primvar_descriptors(
return primvars;
}
pxr::SdfPath MeshData::material_id(pxr::SdfPath const &id) const
{
const SubMesh &sm = submesh(id);
if (!sm.mat_data) {
return pxr::SdfPath();
}
return sm.mat_data->prim_id;
}
pxr::HdCullStyle MeshData::cull_style(pxr::SdfPath const &id) const
{
const SubMesh &sm = submesh(id);
@ -173,16 +175,7 @@ void MeshData::update_double_sided(MaterialData *mat_data)
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(
submesh_prim_id(i),
pxr::HdChangeTracker::DirtyDoubleSided | pxr::HdChangeTracker::DirtyCullStyle);
ID_LOG(1, "%d", i);
}
}
}
void MeshData::available_materials(Set<pxr::SdfPath> &paths) const
{
for (auto &sm : submeshes_) {
if (sm.mat_data && !sm.mat_data->prim_id.IsEmpty()) {
paths.add(sm.mat_data->prim_id);
ID_LOGN(1, "%d", i);
}
}
}
@ -196,6 +189,16 @@ pxr::SdfPathVector MeshData::submesh_paths() const
return ret;
}
void MeshData::write_materials()
{
Object *object = (Object *)id;
for (int i = 0; i < submeshes_.size(); ++i) {
SubMesh &m = submeshes_[i];
Material *mat = BKE_object_material_get_eval(object, m.mat_index + 1);
m.mat_data = get_or_create_material(mat);
}
}
pxr::SdfPath MeshData::submesh_prim_id(int index) const
{
char name[16];
@ -212,7 +215,6 @@ const MeshData::SubMesh &MeshData::submesh(pxr::SdfPath const &id) const
void MeshData::write_submeshes(Mesh *mesh)
{
int sub_meshes_prev_count = submeshes_.size();
submeshes_.clear();
vertices_.clear();
@ -275,49 +277,28 @@ void MeshData::write_submeshes(Mesh *mesh)
vertices_.push_back(pxr::GfVec3f(v.x, v.y, v.z));
}
}
}
/* Update prims in render index */
void MeshData::update_prims()
{
auto &render_index = scene_delegate_->GetRenderIndex();
int i;
for (i = 0; i < submeshes_.size(); ++i) {
pxr::SdfPath p = submesh_prim_id(i);
if (i < sub_meshes_prev_count) {
if (i < submeshes_count_) {
render_index.GetChangeTracker().MarkRprimDirty(p, pxr::HdChangeTracker::AllDirty);
ID_LOG(1, "Update %d", i);
ID_LOGN(1, "Update %d", i);
}
else {
render_index.InsertRprim(pxr::HdPrimTypeTokens->mesh, scene_delegate_, p);
ID_LOG(1, "Insert %d", i);
ID_LOGN(1, "Insert %d", i);
}
}
for (; i < sub_meshes_prev_count; ++i) {
for (; i < submeshes_count_; ++i) {
render_index.RemoveRprim(submesh_prim_id(i));
ID_LOG(1, "Remove %d", i);
}
}
void MeshData::write_materials()
{
Object *object = (Object *)id;
for (int i = 0; i < submeshes_.size(); ++i) {
SubMesh &m = submeshes_[i];
Material *mat = BKE_object_material_get_eval(object, m.mat_index + 1);
if (!mat) {
m.mat_data = nullptr;
continue;
}
pxr::SdfPath p_id = scene_delegate_->material_prim_id(mat);
m.mat_data = scene_delegate_->material_data(p_id);
if (!m.mat_data) {
m.mat_data = scene_delegate_->materials_
.lookup_or_add(p_id,
std::make_unique<MaterialData>(scene_delegate_, mat, p_id))
.get();
m.mat_data->init();
m.mat_data->insert();
}
}
submeshes_count_ = submeshes_.size();
}
} // namespace blender::render::hydra

View File

@ -32,26 +32,30 @@ class MeshData : public ObjectData {
void remove() override;
void update() override;
pxr::VtValue get_data(pxr::SdfPath const &id, pxr::TfToken const &key) const;
bool update_visibility() override;
pxr::VtValue get_data(pxr::TfToken const &key) const override;
pxr::VtValue get_data(pxr::SdfPath const &id, pxr::TfToken const &key) const override;
pxr::SdfPath material_id(pxr::SdfPath const &id) const override;
void available_materials(Set<pxr::SdfPath> &paths) const override;
pxr::HdMeshTopology mesh_topology(pxr::SdfPath const &id) const;
pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation) const;
pxr::SdfPath material_id(pxr::SdfPath const &id) const;
pxr::HdCullStyle cull_style(pxr::SdfPath const &id) const;
bool double_sided(pxr::SdfPath const &id) const;
void update_double_sided(MaterialData *mat_data);
void available_materials(Set<pxr::SdfPath> &paths) const;
pxr::SdfPathVector submesh_paths() const;
protected:
void write_materials() override;
private:
pxr::SdfPath submesh_prim_id(int index) const;
const SubMesh &submesh(pxr::SdfPath const &id) const;
void write_submeshes(Mesh *mesh);
void write_materials();
void update_prims();
pxr::VtVec3fArray vertices_;
std::vector<SubMesh> submeshes_;
int submeshes_count_ = 0;
};
} // namespace blender::render::hydra

View File

@ -23,7 +23,7 @@ std::unique_ptr<ObjectData> ObjectData::create(BlenderSceneDelegate *scene_deleg
Object *object,
pxr::SdfPath const &prim_id)
{
std::unique_ptr<ObjectData> data;
std::unique_ptr<ObjectData> obj_data;
if (VolumeModifierData::is_volume_modifier(object)) {
return std::make_unique<VolumeModifierData>(scene_delegate, object, prim_id);
@ -35,21 +35,23 @@ std::unique_ptr<ObjectData> ObjectData::create(BlenderSceneDelegate *scene_deleg
case OB_FONT:
case OB_CURVES_LEGACY:
case OB_MBALL:
data = std::make_unique<MeshData>(scene_delegate, object, prim_id);
obj_data = std::make_unique<MeshData>(scene_delegate, object, prim_id);
break;
case OB_CURVES:
data = std::make_unique<CurvesData>(scene_delegate, object, prim_id);
obj_data = std::make_unique<CurvesData>(scene_delegate, object, prim_id);
break;
case OB_LAMP:
data = std::make_unique<LightData>(scene_delegate, object, prim_id);
obj_data = std::make_unique<LightData>(scene_delegate, object, prim_id);
break;
case OB_VOLUME:
data = std::make_unique<VolumeData>(scene_delegate, object, prim_id);
obj_data = std::make_unique<VolumeData>(scene_delegate, object, prim_id);
break;
default:
BLI_assert_unreachable();
break;
}
return data;
obj_data->init();
return obj_data;
}
bool ObjectData::is_supported(Object *object)
@ -82,18 +84,48 @@ bool ObjectData::is_visible(BlenderSceneDelegate *scene_delegate, Object *object
return ret;
}
bool ObjectData::update_visibility()
pxr::VtValue ObjectData::get_data(pxr::SdfPath const &id, pxr::TfToken const &key) const
{
bool prev_visible = visible;
visible = is_visible(scene_delegate_, (Object *)id);
return visible != prev_visible;
return get_data(key);
}
pxr::SdfPath ObjectData::material_id() const
{
return pxr::SdfPath();
}
pxr::SdfPath ObjectData::material_id(pxr::SdfPath const &id) const
{
return material_id();
}
void ObjectData::available_materials(Set<pxr::SdfPath> &paths) const {}
void ObjectData::write_transform()
{
transform = gf_matrix_from_transform(((Object *)id)->object_to_world);
}
void ObjectData::write_materials() {}
MaterialData *ObjectData::get_or_create_material(Material *mat)
{
if (!mat) {
return nullptr;
}
pxr::SdfPath p_id = scene_delegate_->material_prim_id(mat);
MaterialData *mat_data = scene_delegate_->material_data(p_id);
if (!mat_data) {
scene_delegate_->materials_.add_new(
p_id, std::make_unique<MaterialData>(scene_delegate_, mat, p_id));
mat_data = scene_delegate_->material_data(p_id);
mat_data->init();
mat_data->insert();
}
return mat_data;
}
pxr::GfMatrix4d gf_matrix_from_transform(float m[4][4])
{
pxr::GfMatrix4d ret;

View File

@ -9,6 +9,7 @@
#include "BKE_layer.h"
#include "BKE_object.h"
#include "BLI_map.hh"
#include "BLI_set.hh"
#include "DNA_object_types.h"
#include "id.h"
@ -28,13 +29,19 @@ class ObjectData : public IdData {
Object *object,
int mode = OB_VISIBLE_SELF);
virtual bool update_visibility();
using IdData::get_data;
virtual pxr::VtValue get_data(pxr::SdfPath const &id, pxr::TfToken const &key) const;
virtual pxr::SdfPath material_id() const;
virtual pxr::SdfPath material_id(pxr::SdfPath const &id) const;
virtual void available_materials(Set<pxr::SdfPath> &paths) const;
pxr::GfMatrix4d transform;
bool visible = true;
protected:
virtual void write_transform();
virtual void write_materials();
MaterialData *get_or_create_material(Material *mat);
};
using ObjectDataMap = Map<pxr::SdfPath, std::unique_ptr<ObjectData>>;

View File

@ -35,7 +35,7 @@ void VolumeData::init()
return;
}
filepath_ = BKE_volume_grids_frame_filepath(volume);
ID_LOG(1, "%s", filepath_.c_str());
ID_LOGN(1, "%s", filepath_.c_str());
if (volume->runtime.grids) {
const int num_grids = BKE_volume_num_grids(volume);
@ -61,22 +61,22 @@ void VolumeData::insert()
scene_delegate_->GetRenderIndex().InsertRprim(
pxr::HdPrimTypeTokens->volume, scene_delegate_, prim_id);
ID_LOG(1, "");
ID_LOGN(1, "");
for (auto &desc : field_descriptors_) {
scene_delegate_->GetRenderIndex().InsertBprim(
desc.fieldPrimType, scene_delegate_, desc.fieldId);
ID_LOG(2, "Volume field %s", desc.fieldId.GetText());
ID_LOGN(2, "Volume field %s", desc.fieldId.GetText());
}
}
void VolumeData::remove()
{
for (auto &desc : field_descriptors_) {
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", desc.fieldId.GetText());
ID_LOG(2, "%s", desc.fieldId.GetText());
scene_delegate_->GetRenderIndex().RemoveBprim(desc.fieldPrimType, desc.fieldId);
}
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 1, "%s", prim_id.GetText());
ID_LOG(1, "");
scene_delegate_->GetRenderIndex().RemoveRprim(prim_id);
}
@ -102,18 +102,14 @@ void VolumeData::update()
}
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(prim_id, bits);
ID_LOG(1, "");
ID_LOGN(1, "");
}
pxr::VtValue VolumeData::get_data(pxr::SdfPath const &id, pxr::TfToken const &key) const
pxr::VtValue VolumeData::get_data(pxr::TfToken const &key) const
{
if (key == pxr::HdVolumeFieldSchemaTokens->filePath) {
return pxr::VtValue(pxr::SdfAssetPath(filepath_, filepath_));
}
if (key == pxr::HdVolumeFieldSchemaTokens->fieldName) {
std::string name = id.GetName();
return pxr::VtValue(pxr::TfToken(name.substr(name.find("VF_") + 3)));
}
if (key == pxr::HdVolumeFieldSchemaTokens->fieldIndex) {
return pxr::VtValue(0);
}
@ -123,20 +119,14 @@ pxr::VtValue VolumeData::get_data(pxr::SdfPath const &id, pxr::TfToken const &ke
return pxr::VtValue();
}
bool VolumeData::update_visibility()
pxr::VtValue VolumeData::get_data(pxr::SdfPath const &id, pxr::TfToken const &key) const
{
bool ret = ObjectData::update_visibility();
if (ret) {
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(
prim_id, pxr::HdChangeTracker::DirtyVisibility);
ID_LOG(1, "");
}
return ret;
if (key == pxr::HdVolumeFieldSchemaTokens->fieldName) {
std::string name = id.GetName();
return pxr::VtValue(pxr::TfToken(name.substr(name.find("VF_") + 3)));
}
pxr::HdVolumeFieldDescriptorVector VolumeData::field_descriptors() const
{
return field_descriptors_;
return get_data(key);
}
pxr::SdfPath VolumeData::material_id() const
@ -154,6 +144,11 @@ void VolumeData::available_materials(Set<pxr::SdfPath> &paths) const
}
}
pxr::HdVolumeFieldDescriptorVector VolumeData::field_descriptors() const
{
return field_descriptors_;
}
void VolumeData::write_materials()
{
Object *object = (Object *)id;
@ -162,20 +157,7 @@ void VolumeData::write_materials()
if (BKE_object_material_count_eval(object) > 0) {
mat = BKE_object_material_get_eval(object, 0);
}
if (!mat) {
mat_data_ = nullptr;
return;
}
pxr::SdfPath p_id = scene_delegate_->material_prim_id(mat);
mat_data_ = scene_delegate_->material_data(p_id);
if (!mat_data_) {
scene_delegate_->materials_.add_new(
p_id, std::make_unique<MaterialData>(scene_delegate_, mat, p_id));
mat_data_ = scene_delegate_->material_data(p_id);
mat_data_->init();
mat_data_->insert();
}
mat_data_ = get_or_create_material(mat);
}
} // namespace blender::render::hydra

View File

@ -19,16 +19,17 @@ class VolumeData : public ObjectData {
void remove() override;
void update() override;
pxr::VtValue get_data(pxr::SdfPath const &id, pxr::TfToken const &key) const;
bool update_visibility() override;
pxr::VtValue get_data(pxr::TfToken const &key) const override;
pxr::VtValue get_data(pxr::SdfPath const &id, pxr::TfToken const &key) const override;
pxr::SdfPath material_id() const override;
void available_materials(Set<pxr::SdfPath> &paths) const override;
pxr::HdVolumeFieldDescriptorVector field_descriptors() const;
pxr::SdfPath material_id() const;
void available_materials(Set<pxr::SdfPath> &paths) const;
protected:
void write_materials();
void write_materials() override;
private:
std::string filepath_;
pxr::HdVolumeFieldDescriptorVector field_descriptors_;
MaterialData *mat_data_ = nullptr;

View File

@ -33,14 +33,13 @@
namespace blender::render::hydra {
WorldData::WorldData(BlenderSceneDelegate *scene_delegate, pxr::SdfPath const &prim_id)
: IdData(scene_delegate, nullptr, prim_id)
: LightData(scene_delegate, nullptr, prim_id)
{
prim_type_ = pxr::HdPrimTypeTokens->domeLight;
}
void WorldData::init()
{
write_transform();
data_.clear();
data_[pxr::UsdLuxTokens->orientToStageUpAxis] = true;
@ -51,7 +50,7 @@ void WorldData::init()
if (scene_delegate_->shading_settings.use_scene_world) {
World *world = scene_delegate_->scene->world;
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 1, "%s: %s", prim_id.GetText(), world->id.name);
ID_LOG(1, "%s", world->id.name);
exposure = world->exposure;
if (world->use_nodes) {
@ -115,21 +114,13 @@ void WorldData::init()
}
}
else {
CLOG_INFO(LOG_RENDER_HYDRA_SCENE,
1,
"%s: studiolight: %s",
prim_id.GetText(),
scene_delegate_->shading_settings.studiolight_name.c_str());
ID_LOG(1, "studiolight: %s", scene_delegate_->shading_settings.studiolight_name.c_str());
StudioLight *sl = BKE_studiolight_find(
scene_delegate_->shading_settings.studiolight_name.c_str(),
STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE);
if (sl != NULL && sl->flag & STUDIOLIGHT_TYPE_WORLD) {
texture_file = pxr::SdfAssetPath(sl->filepath, sl->filepath);
transform *= pxr::GfMatrix4d(
pxr::GfRotation(pxr::GfVec3d(0.0, 0.0, -1.0),
RAD2DEGF(scene_delegate_->shading_settings.studiolight_rotation)),
pxr::GfVec3d());
/* coefficient to follow Cycles result */
intensity = scene_delegate_->shading_settings.studiolight_intensity / 2;
}
@ -139,45 +130,27 @@ void WorldData::init()
data_[pxr::HdLightTokens->exposure] = exposure;
data_[pxr::HdLightTokens->color] = color;
data_[pxr::HdLightTokens->textureFile] = texture_file;
}
void WorldData::insert()
{
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 1, "%s", prim_id.GetText());
scene_delegate_->GetRenderIndex().InsertSprim(
pxr::HdPrimTypeTokens->domeLight, scene_delegate_, prim_id);
}
void WorldData::remove()
{
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 1, "%s", prim_id.GetText());
scene_delegate_->GetRenderIndex().RemoveSprim(pxr::HdPrimTypeTokens->domeLight, prim_id);
write_transform();
}
void WorldData::update()
{
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 1, "%s", prim_id.GetText());
ID_LOG(1, "");
init();
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id,
pxr::HdLight::AllDirty);
}
pxr::VtValue WorldData::get_data(pxr::TfToken const &key) const
{
auto it = data_.find(key);
if (it != data_.end()) {
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s: %s", prim_id.GetText(), key.GetText());
return pxr::VtValue(it->second);
}
return pxr::VtValue();
}
void WorldData::write_transform()
{
transform = pxr::GfMatrix4d(pxr::GfRotation(pxr::GfVec3d(1.0, 0.0, 0.0), -90), pxr::GfVec3d());
transform *= pxr::GfMatrix4d(pxr::GfRotation(pxr::GfVec3d(1.0, 0.0, 0.0), -180), pxr::GfVec3d());
transform *= pxr::GfMatrix4d(pxr::GfRotation(pxr::GfVec3d(0.0, 0.0, 1.0), 90.0), pxr::GfVec3d());
transform = pxr::GfMatrix4d().SetRotate(pxr::GfRotation(pxr::GfVec3d(1.0, 0.0, 0.0), 90.0)) *
pxr::GfMatrix4d().SetRotate(pxr::GfRotation(pxr::GfVec3d(0.0, 0.0, 1.0), 90.0));
if (!scene_delegate_->shading_settings.use_scene_world) {
transform *= pxr::GfMatrix4d().SetRotate(
pxr::GfRotation(pxr::GfVec3d(0.0, 0.0, -1.0),
RAD2DEGF(scene_delegate_->shading_settings.studiolight_rotation)));
}
}
} // namespace blender::render::hydra

View File

@ -14,28 +14,19 @@
#include "DNA_view3d_types.h"
#include "DNA_world_types.h"
#include "id.h"
#include "light.h"
namespace blender::render::hydra {
class WorldData : public IdData {
class WorldData : public LightData {
public:
WorldData(BlenderSceneDelegate *scene_delegate, pxr::SdfPath const &prim_id);
void init() override;
void insert() override;
void remove() override;
void update() override;
void update(World *world);
pxr::VtValue get_data(pxr::TfToken const &key) const override;
pxr::GfMatrix4d transform;
private:
void write_transform();
std::map<pxr::TfToken, pxr::VtValue> data_;
protected:
void write_transform() override;
};
} // namespace blender::render::hydra

View File

@ -1,41 +0,0 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
#include <pxr/imaging/hdx/simpleLightTask.h>
#include "simple_light_task_delegate.h"
namespace blender::render::hydra {
SimpleLightTaskDelegate::SimpleLightTaskDelegate(pxr::HdRenderIndex *parent_index,
pxr::SdfPath const &delegate_id)
: pxr::HdSceneDelegate(parent_index, delegate_id)
{
pxr::SdfPath task_id = get_task_id();
GetRenderIndex().InsertTask<pxr::HdxSimpleLightTask>(this, task_id);
}
pxr::SdfPath SimpleLightTaskDelegate::get_task_id() const
{
return GetDelegateID().AppendElementString("task");
}
pxr::HdTaskSharedPtr SimpleLightTaskDelegate::get_task()
{
return GetRenderIndex().GetTask(get_task_id());
}
void SimpleLightTaskDelegate::set_camera_path(pxr::SdfPath const &camera_path)
{
task_params_.cameraPath = camera_path;
}
pxr::VtValue SimpleLightTaskDelegate::Get(pxr::SdfPath const & /*id*/, pxr::TfToken const &key)
{
if (key == pxr::HdTokens->params) {
return pxr::VtValue(task_params_);
}
return pxr::VtValue();
}
} // namespace blender::render::hydra

View File

@ -1,28 +0,0 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
#pragma once
#include <pxr/imaging/hd/sceneDelegate.h>
#include <pxr/imaging/hdx/simpleLightTask.h>
namespace blender::render::hydra {
class SimpleLightTaskDelegate : public pxr::HdSceneDelegate {
public:
SimpleLightTaskDelegate(pxr::HdRenderIndex *parentIndex, pxr::SdfPath const &delegate_id);
~SimpleLightTaskDelegate() override = default;
pxr::SdfPath get_task_id() const;
pxr::HdTaskSharedPtr get_task();
void set_camera_path(pxr::SdfPath const &);
/* Delegate methods */
pxr::VtValue Get(pxr::SdfPath const &id, pxr::TfToken const &key) override;
private:
pxr::HdxSimpleLightTaskParams task_params_;
};
} // namespace blender::render::hydra

View File

@ -236,8 +236,13 @@ void ViewportEngine::render(Depsgraph * /* depsgraph */, bContext *context)
view_settings.border[1],
view_settings.border[2],
view_settings.border[3]));
if (simple_light_task_delegate_) {
simple_light_task_delegate_->set_camera_path(free_camera_delegate_->GetCameraId());
if (light_tasks_delegate_) {
light_tasks_delegate_->set_camera_and_viewport(free_camera_delegate_->GetCameraId(),
pxr::GfVec4d(view_settings.border[0],
view_settings.border[1],
view_settings.border[2],
view_settings.border[3]));
}
if ((bl_engine_->type->flag & RE_USE_GPU_CONTEXT) == 0) {
@ -248,8 +253,8 @@ void ViewportEngine::render(Depsgraph * /* depsgraph */, bContext *context)
GPU_shader_bind(shader);
pxr::HdTaskSharedPtrVector tasks;
if (simple_light_task_delegate_) {
tasks.push_back(simple_light_task_delegate_->get_task());
if (light_tasks_delegate_) {
tasks = light_tasks_delegate_->get_tasks();
}
tasks.push_back(render_task_delegate_->get_task());