forked from blender/blender
Make object visibility and instancing creation to be calculated via depsgraph #57
@ -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
|
||||||
|
@ -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_;
|
||||||
|
@ -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);
|
||||||
|
@ -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,93 +28,122 @@
|
|||||||
|
|
||||||
/* 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;
|
||||||
|
|
||||||
if (world->use_nodes) {
|
float intensity = 1.0f;
|
||||||
/* TODO: Create nodes parsing system */
|
float exposure = 1.0f;
|
||||||
|
pxr::GfVec3f color(1.0f, 1.0f, 1.0f);
|
||||||
|
pxr::SdfAssetPath texture_file;
|
||||||
|
|
||||||
bNode *output_node = ntreeShaderOutputNode(world->nodetree, SHD_OUTPUT_ALL);
|
if (scene_delegate_->shading_settings.use_scene_world) {
|
||||||
blender::Span<bNodeSocket *> input_sockets = output_node->input_sockets();
|
World *world = scene_delegate_->scene->world;
|
||||||
bNodeSocket *input_socket = nullptr;
|
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 1, "%s: %s", prim_id.GetText(), world->id.name);
|
||||||
|
|
||||||
for (auto socket : input_sockets) {
|
exposure = world->exposure;
|
||||||
if (STREQ(socket->name, "Surface")) {
|
if (world->use_nodes) {
|
||||||
input_socket = socket;
|
/* TODO: Create nodes parsing system */
|
||||||
break;
|
|
||||||
|
bNode *output_node = ntreeShaderOutputNode(world->nodetree, SHD_OUTPUT_ALL);
|
||||||
|
blender::Span<bNodeSocket *> input_sockets = output_node->input_sockets();
|
||||||
|
bNodeSocket *input_socket = nullptr;
|
||||||
|
|
||||||
|
for (auto socket : input_sockets) {
|
||||||
|
if (STREQ(socket->name, "Surface")) {
|
||||||
|
input_socket = socket;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!input_socket) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bNodeLink const *link = input_socket->directly_linked_links()[0];
|
||||||
|
if (input_socket->directly_linked_links().is_empty()) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!input_socket) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bNodeLink const *link = input_socket->directly_linked_links()[0];
|
|
||||||
if (input_socket->directly_linked_links().is_empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bNode *input_node = link->fromnode;
|
bNode *input_node = link->fromnode;
|
||||||
if (input_node->type != SH_NODE_BACKGROUND) {
|
if (input_node->type != SH_NODE_BACKGROUND) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bNodeSocket color_input = input_node->input_by_identifier("Color");
|
bNodeSocket color_input = input_node->input_by_identifier("Color");
|
||||||
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;
|
||||||
if (color_input_node->type == SH_NODE_TEX_IMAGE) {
|
if (color_input_node->type == SH_NODE_TEX_IMAGE) {
|
||||||
NodeTexImage *tex = static_cast<NodeTexImage *>(color_input_node->storage);
|
NodeTexImage *tex = static_cast<NodeTexImage *>(color_input_node->storage);
|
||||||
Image *image = (Image *)color_input_node->id;
|
Image *image = (Image *)color_input_node->id;
|
||||||
if (image) {
|
if (image) {
|
||||||
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 {
|
||||||
|
intensity = 1.0f;
|
||||||
|
color = pxr::GfVec3f(world->horr, world->horg, world->horb);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture_file.GetAssetPath().empty()) {
|
||||||
|
float fill_color[4] = {color[0], color[1], color[2], 1.0f};
|
||||||
|
std::string image_path = cache_image_color(fill_color);
|
||||||
|
texture_file = pxr::SdfAssetPath(image_path, image_path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
data_[pxr::HdLightTokens->intensity] = 1.0f;
|
CLOG_INFO(LOG_RENDER_HYDRA_SCENE,
|
||||||
data_[pxr::HdLightTokens->exposure] = world->exposure;
|
1,
|
||||||
data_[pxr::HdLightTokens->color] = pxr::GfVec3f(world->horr, world->horg, world->horb);
|
"%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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data_.find(pxr::HdLightTokens->textureFile) == data_.end()) {
|
data_[pxr::HdLightTokens->intensity] = intensity;
|
||||||
pxr::GfVec3f c = data_[pxr::HdLightTokens->color].Get<pxr::GfVec3f>();
|
data_[pxr::HdLightTokens->exposure] = exposure;
|
||||||
float color[4] = {c[0], c[1], c[2], 1.0f};
|
data_[pxr::HdLightTokens->color] = color;
|
||||||
std::string image_path = cache_image_color(color);
|
data_[pxr::HdLightTokens->textureFile] = texture_file;
|
||||||
data_[pxr::HdLightTokens->textureFile] = pxr::SdfAssetPath(image_path, image_path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user