diff --git a/doc/python_api/examples/bpy.types.HydraRenderEngine.py b/doc/python_api/examples/bpy.types.HydraRenderEngine.py index 4f3a051220f6..172b6a6c86c2 100644 --- a/doc/python_api/examples/bpy.types.HydraRenderEngine.py +++ b/doc/python_api/examples/bpy.types.HydraRenderEngine.py @@ -7,6 +7,7 @@ USD Hydra Based Renderer import bpy + class CustomHydraRenderEngine(bpy.types.HydraRenderEngine): # Identifier and name in the user interface. bl_idname = "CUSTOM_HYDRA_RENDERER" @@ -53,8 +54,10 @@ class CustomHydraRenderEngine(bpy.types.HydraRenderEngine): def register(): bpy.utils.register_class(CustomHydraRenderEngine) + def unregister(): bpy.utils.unregister_class(CustomHydraRenderEngine) + if __name__ == "__main__": register() diff --git a/scripts/modules/bpy_hydra.py b/scripts/modules/bpy_hydra.py index 81111da06a96..7613e5bf7fca 100644 --- a/scripts/modules/bpy_hydra.py +++ b/scripts/modules/bpy_hydra.py @@ -4,6 +4,7 @@ __all__ = ( "export_mtlx", ) + def export_mtlx(material): """ Exports material to .mtlx file. It is called from Blender source code. """ import materialx.utils as mx_utils diff --git a/source/blender/render/hydra/CMakeLists.txt b/source/blender/render/hydra/CMakeLists.txt index 5994b1cfbfc4..41180e6604b0 100644 --- a/source/blender/render/hydra/CMakeLists.txt +++ b/source/blender/render/hydra/CMakeLists.txt @@ -62,6 +62,7 @@ set(INC_SYS ${BOOST_INCLUDE_DIR} ${TBB_INCLUDE_DIR} ${GFLAGS_INCLUDE_DIRS} + ${EIGEN3_INCLUDE_DIRS} ) set(LIB diff --git a/source/blender/render/hydra/engine.cc b/source/blender/render/hydra/engine.cc index 3bdd928c501b..d8ced6fb2bfd 100644 --- a/source/blender/render/hydra/engine.cc +++ b/source/blender/render/hydra/engine.cc @@ -55,7 +55,7 @@ Engine::Engine(RenderEngine *bl_engine, const std::string &render_delegate_name) free_camera_delegate_ = std::make_unique( render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("freeCamera")); - if (bl_engine->type->flag & RE_USE_GPU_CONTEXT) { + if (bl_engine->type->flag & RE_USE_GPU_CONTEXT && GPU_backend_get_type() == GPU_BACKEND_OPENGL) { render_task_delegate_ = std::make_unique( render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("renderTask")); } @@ -133,4 +133,22 @@ float Engine::renderer_percent_done() return (float)it->second.UncheckedGet(); } +pxr::HdTaskSharedPtrVector Engine::tasks() +{ + pxr::HdTaskSharedPtrVector res; + if (light_tasks_delegate_) { + if (scene_->r.alphamode != R_ALPHAPREMUL) { +#ifndef __APPLE__ + /* TODO: Temporary disable skydome task for MacOS due to crash with error: + * Failed to created pipeline state, error depthAttachmentPixelFormat is not valid + * and shader writes to depth */ + res.push_back(light_tasks_delegate_->skydome_task()); +#endif + } + res.push_back(light_tasks_delegate_->simple_task()); + } + res.push_back(render_task_delegate_->task()); + return res; +} + } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/engine.h b/source/blender/render/hydra/engine.h index 7fe68c81d9f7..f3558e3ffeeb 100644 --- a/source/blender/render/hydra/engine.h +++ b/source/blender/render/hydra/engine.h @@ -64,7 +64,10 @@ class Engine { protected: float renderer_percent_done(); - virtual void notify_status(float progress, const std::string &title, const std::string &info) = 0; + pxr::HdTaskSharedPtrVector tasks(); + virtual void notify_status(float progress, + const std::string &title, + const std::string &info) = 0; }; } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/final_engine.cc b/source/blender/render/hydra/final_engine.cc index 2413f67d1ba6..e12b24608c1e 100644 --- a/source/blender/render/hydra/final_engine.cc +++ b/source/blender/render/hydra/final_engine.cc @@ -66,18 +66,10 @@ void FinalEngine::render() render_task_delegate_->add_aov(pxr::HdAovTokens->depth); } - pxr::HdTaskSharedPtrVector tasks; - if (light_tasks_delegate_) { - if (scene_->r.alphamode != R_ALPHAPREMUL) { - tasks.push_back(light_tasks_delegate_->skydome_task()); - } - tasks.push_back(light_tasks_delegate_->simple_task()); - } - tasks.push_back(render_task_delegate_->task()); - render_task_delegate_->bind(); - engine_->Execute(render_index_.get(), &tasks); + auto t = tasks(); + engine_->Execute(render_index_.get(), &t); char elapsed_time[32]; double time_begin = PIL_check_seconds_timer(); diff --git a/source/blender/render/hydra/python.cc b/source/blender/render/hydra/python.cc index cec3a0bd377f..be1aa2632252 100644 --- a/source/blender/render/hydra/python.cc +++ b/source/blender/render/hydra/python.cc @@ -37,6 +37,7 @@ static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args) RenderEngine *bl_engine = pyrna_to_pointer(pyengine, &RNA_RenderEngine); + CLOG_INFO(LOG_HYDRA_RENDER, 1, "Engine %s", engine_type); Engine *engine = nullptr; try { if (STREQ(engine_type, "VIEWPORT")) { @@ -53,9 +54,7 @@ static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args) CLOG_ERROR(LOG_HYDRA_RENDER, "%s", e.what()); } - if (engine) { - CLOG_INFO(LOG_HYDRA_RENDER, 1, "Engine %p %s", engine, engine_type); - } + CLOG_INFO(LOG_HYDRA_RENDER, 1, "Engine %p", engine); return PyLong_FromVoidPtr(engine); } @@ -67,9 +66,9 @@ static PyObject *engine_free_func(PyObject * /*self*/, PyObject *args) } Engine *engine = static_cast(PyLong_AsVoidPtr(pyengine)); + CLOG_INFO(LOG_HYDRA_RENDER, 1, "Engine %p", engine); delete engine; - CLOG_INFO(LOG_HYDRA_RENDER, 1, "Engine %p", engine); Py_RETURN_NONE; } diff --git a/source/blender/render/hydra/render_task_delegate.cc b/source/blender/render/hydra/render_task_delegate.cc index 6772920e1d3b..6010d866ee55 100644 --- a/source/blender/render/hydra/render_task_delegate.cc +++ b/source/blender/render/hydra/render_task_delegate.cc @@ -13,8 +13,9 @@ #include "MEM_guardedalloc.h" +#include "Eigen/Core" + #include "engine.h" -#include "render_task_delegate.h" namespace blender::render::hydra { @@ -107,6 +108,16 @@ void RenderTaskDelegate::add_aov(pxr::TfToken const &aov_key) aov_key); if (aov_desc.format == pxr::HdFormatInvalid) { + CLOG_ERROR(LOG_HYDRA_RENDER, "Invalid AOV: %s", aov_key.GetText()); + return; + } + if (!ELEM( + pxr::HdGetComponentFormat(aov_desc.format), pxr::HdFormatFloat32, pxr::HdFormatFloat16)) + { + CLOG_WARN(LOG_HYDRA_RENDER, + "Unsupported data format %s for AOV %s", + pxr::TfEnum::GetName(aov_desc.format).c_str(), + aov_key.GetText()); return; } @@ -120,7 +131,7 @@ void RenderTaskDelegate::add_aov(pxr::TfToken const &aov_key) binding.aovName = aov_key; binding.renderBufferId = buf_id; binding.aovSettings = aov_desc.aovSettings; - binding.clearValue = pxr::VtValue(pxr::GfVec4f(0)); + binding.clearValue = aov_desc.clearValue; task_params_.aovBindings.push_back(binding); render_index.GetChangeTracker().MarkTaskDirty(task_id_, pxr::HdChangeTracker::DirtyParams); @@ -134,11 +145,25 @@ void RenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, void *data) if (!buffer) { return; } - void *buf_data = buffer->Map(); - memcpy(data, - buf_data, - buffer->GetWidth() * buffer->GetHeight() * pxr::HdDataSizeOfFormat(buffer->GetFormat())); - buffer->Unmap(); + + pxr::HdFormat format = buffer->GetFormat(); + size_t len = buffer->GetWidth() * buffer->GetHeight() * pxr::HdGetComponentCount(format); + if (pxr::HdGetComponentFormat(format) == pxr::HdFormatFloat32) { + void *buf_data = buffer->Map(); + memcpy(data, buf_data, len * sizeof(float)); + buffer->Unmap(); + } + else if (pxr::HdGetComponentFormat(format) == pxr::HdFormatFloat16) { + Eigen::half *buf_data = (Eigen::half *)buffer->Map(); + float *fdata = (float *)data; + for (size_t i = 0; i < len; ++i) { + fdata[i] = buf_data[i]; + } + buffer->Unmap(); + } + else { + BLI_assert_unreachable(); + } } void RenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, GPUTexture *texture) @@ -210,6 +235,7 @@ void GPURenderTaskDelegate::add_aov(pxr::TfToken const &aov_key) tex = &tex_depth_; } else { + CLOG_ERROR(LOG_HYDRA_RENDER, "Invalid AOV: %s", aov_key.GetText()); return; } @@ -253,14 +279,11 @@ void GPURenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, void *data) void GPURenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, GPUTexture *texture) { GPUTexture *tex = nullptr; - int c; if (aov_key == pxr::HdAovTokens->color) { tex = tex_color_; - c = 4; } else if (aov_key == pxr::HdAovTokens->depth) { tex = tex_depth_; - c = 1; } if (!tex) { return; diff --git a/source/blender/render/hydra/viewport_engine.cc b/source/blender/render/hydra/viewport_engine.cc index 0c19c4b4f620..be78e6ab437d 100644 --- a/source/blender/render/hydra/viewport_engine.cc +++ b/source/blender/render/hydra/viewport_engine.cc @@ -232,19 +232,11 @@ void ViewportEngine::render() render_task_delegate_->add_aov(pxr::HdAovTokens->color); render_task_delegate_->add_aov(pxr::HdAovTokens->depth); - pxr::HdTaskSharedPtrVector tasks; - if (light_tasks_delegate_) { - if (scene_->r.alphamode != R_ALPHAPREMUL) { - tasks.push_back(light_tasks_delegate_->skydome_task()); - } - tasks.push_back(light_tasks_delegate_->simple_task()); - } - tasks.push_back(render_task_delegate_->task()); - GPUFrameBuffer *view_framebuffer = GPU_framebuffer_active_get(); render_task_delegate_->bind(); - engine_->Execute(render_index_.get(), &tasks); + auto t = tasks(); + engine_->Execute(render_index_.get(), &t); render_task_delegate_->unbind(); @@ -293,7 +285,8 @@ void ViewportEngine::render(bContext *context) render(); } -void ViewportEngine::notify_status(float /*progress*/, const std::string &info, +void ViewportEngine::notify_status(float /*progress*/, + const std::string &info, const std::string &status) { RE_engine_update_stats(bl_engine_, status.c_str(), info.c_str());