Make object visibility and instancing creation to be calculated via depsgraph #57

Merged
Bogdan Nagirniak merged 16 commits from BLEN-442 into hydra-render 2023-07-08 10:09:53 +02:00
5 changed files with 168 additions and 72 deletions
Showing only changes of commit 22a27365d6 - Show all commits

View File

@ -14,6 +14,19 @@ namespace blender::render::hydra {
CLG_LOGREF_DECLARE_GLOBAL(LOG_RENDER_HYDRA_SCENE, "render.hydra.scene"); CLG_LOGREF_DECLARE_GLOBAL(LOG_RENDER_HYDRA_SCENE, "render.hydra.scene");
bool BlenderSceneDelegate::ShadingSettings::operator==(const ShadingSettings &other)
{
bool ret = use_scene_lights == other.use_scene_lights &&
use_scene_world == other.use_scene_world;
if (ret && !use_scene_world) {
/* compare studiolight settings when studiolight is using */
ret = studiolight_name == other.studiolight_name &&
studiolight_rotation == other.studiolight_rotation &&
studiolight_intensity == other.studiolight_intensity;
}
return ret;
}
BlenderSceneDelegate::BlenderSceneDelegate(pxr::HdRenderIndex *parent_index, BlenderSceneDelegate::BlenderSceneDelegate(pxr::HdRenderIndex *parent_index,
pxr::SdfPath const &delegate_id, pxr::SdfPath const &delegate_id,
Engine *engine) Engine *engine)
@ -205,6 +218,8 @@ void BlenderSceneDelegate::populate(Depsgraph *deps, bContext *cont)
check_updates(); check_updates();
} }
else { else {
set_light_shading_settings();
set_world_shading_settings();
update_collection(); update_collection();
update_world(); update_world();
} }
@ -330,17 +345,16 @@ InstancerData *BlenderSceneDelegate::instancer_data(pxr::SdfPath const &id, bool
void BlenderSceneDelegate::update_world() void BlenderSceneDelegate::update_world()
{ {
World *world = scene->world;
if (!world_data_) { if (!world_data_) {
if (world) { if (!shading_settings.use_scene_world || (shading_settings.use_scene_world && scene->world)) {
world_data_ = std::make_unique<WorldData>(this, world, world_prim_id()); world_data_ = std::make_unique<WorldData>(this, world_prim_id());
world_data_->init(); world_data_->init();
world_data_->insert(); world_data_->insert();
} }
} }
else { else {
if (world) { if (!shading_settings.use_scene_world || (shading_settings.use_scene_world && scene->world)) {
world_data_->update(world); world_data_->update();
} }
else { else {
world_data_->remove(); world_data_->remove();
@ -354,6 +368,19 @@ void BlenderSceneDelegate::check_updates()
bool do_update_collection = false; bool do_update_collection = false;
bool do_update_world = false; bool do_update_world = false;
if (set_world_shading_settings()) {
do_update_world = true;
}
if (set_light_shading_settings()) {
if (shading_settings.use_scene_lights) {
add_new_objects();
}
else {
do_update_collection = true;
}
}
DEGIDIterData data = {0}; DEGIDIterData data = {0};
data.graph = depsgraph; data.graph = depsgraph;
data.only_updated = true; data.only_updated = true;
@ -378,7 +405,7 @@ void BlenderSceneDelegate::check_updates()
} break; } break;
case ID_WO: { case ID_WO: {
if (id->recalc & ID_RECALC_SHADING) { if (shading_settings.use_scene_world && id->recalc & ID_RECALC_SHADING) {
do_update_world = true; do_update_world = true;
} }
} break; } break;
@ -441,6 +468,10 @@ void BlenderSceneDelegate::update_collection()
if (!ObjectData::is_visible(this, object)) { if (!ObjectData::is_visible(this, object)) {
continue; continue;
} }
if (!shading_settings.use_scene_lights && object->type == OB_LAMP) {
continue;
}
available_objects.add(object_prim_id(object).GetName()); available_objects.add(object_prim_id(object).GetName());
pxr::SdfPath id = object_prim_id(object); pxr::SdfPath id = object_prim_id(object);
@ -497,4 +528,27 @@ void BlenderSceneDelegate::update_collection()
}); });
} }
bool BlenderSceneDelegate::set_light_shading_settings()
{
if (!view3d) {
return false;
}
ShadingSettings prev_settings(shading_settings);
shading_settings.use_scene_lights = V3D_USES_SCENE_LIGHTS(view3d);
return !(shading_settings == prev_settings);
}
bool BlenderSceneDelegate::set_world_shading_settings()
{
if (!view3d) {
return false;
}
ShadingSettings prev_settings(shading_settings);
shading_settings.use_scene_world = V3D_USES_SCENE_WORLD(view3d);
shading_settings.studiolight_name = view3d->shading.lookdev_light;
shading_settings.studiolight_rotation = view3d->shading.studiolight_rot_z;
shading_settings.studiolight_intensity = view3d->shading.studiolight_intensity;
return !(shading_settings == prev_settings);
}
} // namespace blender::render::hydra } // namespace blender::render::hydra

View File

@ -7,11 +7,11 @@
#include <pxr/imaging/hd/sceneDelegate.h> #include <pxr/imaging/hd/sceneDelegate.h>
#include "BKE_context.h" #include "BKE_context.h"
#include "BLI_map.hh"
#include "DEG_depsgraph.h" #include "DEG_depsgraph.h"
#include "CLG_log.h" #include "CLG_log.h"
#include "BLI_map.hh"
#include "curves.h" #include "curves.h"
#include "instancer.h" #include "instancer.h"
#include "light.h" #include "light.h"
@ -37,6 +37,16 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
Map<pxr::TfToken, pxr::VtValue> render_tokens; Map<pxr::TfToken, pxr::VtValue> render_tokens;
}; };
struct ShadingSettings {
bool use_scene_lights = true;
bool use_scene_world = true;
std::string studiolight_name;
float studiolight_rotation;
float studiolight_intensity;
bool operator==(const ShadingSettings &other);
};
BlenderSceneDelegate(pxr::HdRenderIndex *parent_index, BlenderSceneDelegate(pxr::HdRenderIndex *parent_index,
pxr::SdfPath const &delegate_id, pxr::SdfPath const &delegate_id,
Engine *engine); Engine *engine);
@ -71,6 +81,7 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
Scene *scene = nullptr; Scene *scene = nullptr;
Engine *engine; Engine *engine;
Settings settings; Settings settings;
ShadingSettings shading_settings;
private: private:
pxr::SdfPath prim_id(ID *id, const char *prefix) const; pxr::SdfPath prim_id(ID *id, const char *prefix) const;
@ -89,6 +100,8 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
void update_world(); void update_world();
void check_updates(); void check_updates();
void update_collection(); void update_collection();
bool set_light_shading_settings();
bool set_world_shading_settings();
ObjectDataMap objects_; ObjectDataMap objects_;
MaterialDataMap materials_; MaterialDataMap materials_;

View File

@ -228,6 +228,10 @@ void InstancerData::write_instances()
if (!ObjectData::is_visible(scene_delegate_, d.dupli_parent)) { if (!ObjectData::is_visible(scene_delegate_, d.dupli_parent)) {
continue; continue;
} }
if (!scene_delegate_->shading_settings.use_scene_lights && ob->type == OB_LAMP) {
continue;
}
pxr::SdfPath p_id = object_prim_id(ob); pxr::SdfPath p_id = object_prim_id(ob);
if (ob->type == OB_LAMP) { if (ob->type == OB_LAMP) {
LightInstance *inst = light_instance(p_id); LightInstance *inst = light_instance(p_id);

View File

@ -16,6 +16,8 @@
#include "BKE_node.h" #include "BKE_node.h"
#include "BKE_node_runtime.hh" #include "BKE_node_runtime.hh"
#include "BKE_studiolight.h"
#include "BLI_math_rotation.h"
#include "BLI_path_util.h" #include "BLI_path_util.h"
#include "NOD_shader.h" #include "NOD_shader.h"
@ -26,26 +28,32 @@
/* TODO : add custom tftoken "transparency"? */ /* TODO : add custom tftoken "transparency"? */
/* NOTE: opacity and blur aren't supported by USD */
namespace blender::render::hydra { namespace blender::render::hydra {
WorldData::WorldData(BlenderSceneDelegate *scene_delegate, WorldData::WorldData(BlenderSceneDelegate *scene_delegate, pxr::SdfPath const &prim_id)
World *world, : IdData(scene_delegate, nullptr, prim_id)
pxr::SdfPath const &prim_id)
: IdData(scene_delegate, (ID *)world, prim_id)
{ {
} }
void WorldData::init() void WorldData::init()
{ {
ID_LOG(1, "");
write_transform(); write_transform();
World *world = (World *)id;
data_.clear(); data_.clear();
data_[pxr::UsdLuxTokens->orientToStageUpAxis] = true; data_[pxr::UsdLuxTokens->orientToStageUpAxis] = true;
float intensity = 1.0f;
float exposure = 1.0f;
pxr::GfVec3f color(1.0f, 1.0f, 1.0f);
pxr::SdfAssetPath texture_file;
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);
exposure = world->exposure;
if (world->use_nodes) { if (world->use_nodes) {
/* TODO: Create nodes parsing system */ /* TODO: Create nodes parsing system */
@ -76,10 +84,9 @@ void WorldData::init()
bNodeSocket strength_input = input_node->input_by_identifier("Strength"); bNodeSocket strength_input = input_node->input_by_identifier("Strength");
float const *strength = strength_input.default_value_typed<float>(); float const *strength = strength_input.default_value_typed<float>();
float const *color = color_input.default_value_typed<float>(); float const *input_color = color_input.default_value_typed<float>();
data_[pxr::HdLightTokens->intensity] = strength[1]; intensity = strength[1];
data_[pxr::HdLightTokens->exposure] = 1.0f; color = pxr::GfVec3f(input_color[0], input_color[1], input_color[2]);
data_[pxr::HdLightTokens->color] = pxr::GfVec3f(color[0], color[1], color[2]);
if (!color_input.directly_linked_links().is_empty()) { if (!color_input.directly_linked_links().is_empty()) {
bNode *color_input_node = color_input.directly_linked_links()[0]->fromnode; bNode *color_input_node = color_input.directly_linked_links()[0]->fromnode;
@ -90,29 +97,53 @@ void WorldData::init()
std::string image_path = cache_or_get_image_file( std::string image_path = cache_or_get_image_file(
image, scene_delegate_->context, &tex->iuser); image, scene_delegate_->context, &tex->iuser);
if (!image_path.empty()) { if (!image_path.empty()) {
data_[pxr::HdLightTokens->textureFile] = pxr::SdfAssetPath(image_path, image_path); texture_file = pxr::SdfAssetPath(image_path, image_path);
} }
} }
} }
} }
} }
else { else {
data_[pxr::HdLightTokens->intensity] = 1.0f; intensity = 1.0f;
data_[pxr::HdLightTokens->exposure] = world->exposure; color = pxr::GfVec3f(world->horr, world->horg, world->horb);
data_[pxr::HdLightTokens->color] = pxr::GfVec3f(world->horr, world->horg, world->horb);
} }
if (data_.find(pxr::HdLightTokens->textureFile) == data_.end()) { if (texture_file.GetAssetPath().empty()) {
pxr::GfVec3f c = data_[pxr::HdLightTokens->color].Get<pxr::GfVec3f>(); float fill_color[4] = {color[0], color[1], color[2], 1.0f};
float color[4] = {c[0], c[1], c[2], 1.0f}; std::string image_path = cache_image_color(fill_color);
std::string image_path = cache_image_color(color); texture_file = pxr::SdfAssetPath(image_path, image_path);
data_[pxr::HdLightTokens->textureFile] = pxr::SdfAssetPath(image_path, image_path);
} }
} }
else {
CLOG_INFO(LOG_RENDER_HYDRA_SCENE,
1,
"%s: studiolight: %s",
prim_id.GetText(),
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;
}
}
data_[pxr::HdLightTokens->intensity] = intensity;
data_[pxr::HdLightTokens->exposure] = exposure;
data_[pxr::HdLightTokens->color] = color;
data_[pxr::HdLightTokens->textureFile] = texture_file;
}
void WorldData::insert() void WorldData::insert()
{ {
ID_LOG(1, ""); CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 1, "%s", prim_id.GetText());
scene_delegate_->GetRenderIndex().InsertSprim( scene_delegate_->GetRenderIndex().InsertSprim(
pxr::HdPrimTypeTokens->domeLight, scene_delegate_, prim_id); pxr::HdPrimTypeTokens->domeLight, scene_delegate_, prim_id);
} }
@ -125,23 +156,17 @@ void WorldData::remove()
void WorldData::update() void WorldData::update()
{ {
ID_LOG(1, ""); CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 1, "%s", prim_id.GetText());
init(); init();
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id, scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id,
pxr::HdLight::AllDirty); pxr::HdLight::AllDirty);
} }
void WorldData::update(World *world)
{
id = (ID *)world;
update();
}
pxr::VtValue WorldData::get_data(pxr::TfToken const &key) const pxr::VtValue WorldData::get_data(pxr::TfToken const &key) const
{ {
auto it = data_.find(key); auto it = data_.find(key);
if (it != data_.end()) { if (it != data_.end()) {
ID_LOG(3, "%s", key.GetText()); CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s: %s", prim_id.GetText(), key.GetText());
return pxr::VtValue(it->second); return pxr::VtValue(it->second);
} }
return pxr::VtValue(); return pxr::VtValue();

View File

@ -20,7 +20,7 @@ namespace blender::render::hydra {
class WorldData : public IdData { class WorldData : public IdData {
public: public:
WorldData(BlenderSceneDelegate *scene_delegate, World *world, pxr::SdfPath const &prim_id); WorldData(BlenderSceneDelegate *scene_delegate, pxr::SdfPath const &prim_id);
void init() override; void init() override;
void insert() override; void insert() override;