Optimized SubMesh to hold only used vertices #84

Merged
Bogdan Nagirniak merged 3 commits from BLEN-474 into hydra-render 2023-08-02 16:45:15 +02:00
10 changed files with 98 additions and 44 deletions
Showing only changes of commit e023f7b25f - Show all commits

View File

@ -7,6 +7,7 @@ USD Hydra Based Renderer
import bpy import bpy
class CustomHydraRenderEngine(bpy.types.HydraRenderEngine): class CustomHydraRenderEngine(bpy.types.HydraRenderEngine):
# Identifier and name in the user interface. # Identifier and name in the user interface.
bl_idname = "CUSTOM_HYDRA_RENDERER" bl_idname = "CUSTOM_HYDRA_RENDERER"
@ -53,8 +54,10 @@ class CustomHydraRenderEngine(bpy.types.HydraRenderEngine):
def register(): def register():
bpy.utils.register_class(CustomHydraRenderEngine) bpy.utils.register_class(CustomHydraRenderEngine)
def unregister(): def unregister():
bpy.utils.unregister_class(CustomHydraRenderEngine) bpy.utils.unregister_class(CustomHydraRenderEngine)
if __name__ == "__main__": if __name__ == "__main__":
register() register()

View File

@ -4,13 +4,10 @@ __all__ = (
"export_mtlx", "export_mtlx",
) )
def export_mtlx(material): def export_mtlx(material):
""" Exports material to .mtlx file. It is called from Blender source code. """ """ Exports material to .mtlx file. It is called from Blender source code. """
try:
import materialx.utils as mx_utils import materialx.utils as mx_utils
except ImportError:
print("ERROR: no MaterialX addon available")
return ""
doc = mx_utils.export(material, None) doc = mx_utils.export(material, None)
if not doc: if not doc:

View File

@ -113,9 +113,34 @@ pxr::HdCullStyle MaterialData::cull_style() const
void MaterialData::export_mtlx() void MaterialData::export_mtlx()
{ {
/* Call of python function hydra.export_mtlx() */
PyGILState_STATE gstate; PyGILState_STATE gstate;
/* Checking materialx addon */
static bool matx_addon_checked = false;
static bool has_matx_addon = false;
if (!matx_addon_checked) {
gstate = PyGILState_Ensure();
/* Adding second check into the lock, good practice to make this fully correct */
if (!matx_addon_checked) {
PyObject *mx_module = PyImport_ImportModule("materialx");
has_matx_addon = mx_module != nullptr;
Py_XDECREF(mx_module);
if (!has_matx_addon) {
PyErr_Print();
CLOG_WARN(LOG_HYDRA_SCENE, "No MaterialX addon, materials won't be exported.");
}
matx_addon_checked = true;
}
PyGILState_Release(gstate);
}
if (!has_matx_addon) {
return;
}
/* Call of python function bpy_hydra.export_mtlx() */
gstate = PyGILState_Ensure(); gstate = PyGILState_Ensure();
PyObject *module, *dict, *func, *result; PyObject *module, *dict, *func, *result;

View File

@ -62,6 +62,7 @@ set(INC_SYS
${BOOST_INCLUDE_DIR} ${BOOST_INCLUDE_DIR}
${TBB_INCLUDE_DIR} ${TBB_INCLUDE_DIR}
${GFLAGS_INCLUDE_DIRS} ${GFLAGS_INCLUDE_DIRS}
${EIGEN3_INCLUDE_DIRS}
) )
set(LIB set(LIB

View File

@ -55,7 +55,7 @@ Engine::Engine(RenderEngine *bl_engine, const std::string &render_delegate_name)
free_camera_delegate_ = std::make_unique<pxr::HdxFreeCameraSceneDelegate>( free_camera_delegate_ = std::make_unique<pxr::HdxFreeCameraSceneDelegate>(
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("freeCamera")); 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<GPURenderTaskDelegate>( render_task_delegate_ = std::make_unique<GPURenderTaskDelegate>(
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("renderTask")); render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("renderTask"));
} }
@ -133,4 +133,22 @@ float Engine::renderer_percent_done()
return (float)it->second.UncheckedGet<double>(); return (float)it->second.UncheckedGet<double>();
} }
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 } // namespace blender::render::hydra

View File

@ -64,7 +64,10 @@ class Engine {
protected: protected:
float renderer_percent_done(); 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 } // namespace blender::render::hydra

View File

@ -66,18 +66,10 @@ void FinalEngine::render()
render_task_delegate_->add_aov(pxr::HdAovTokens->depth); 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(); render_task_delegate_->bind();
engine_->Execute(render_index_.get(), &tasks); auto t = tasks();
engine_->Execute(render_index_.get(), &t);
char elapsed_time[32]; char elapsed_time[32];
double time_begin = PIL_check_seconds_timer(); double time_begin = PIL_check_seconds_timer();

View File

@ -37,6 +37,7 @@ static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args)
RenderEngine *bl_engine = pyrna_to_pointer<RenderEngine>(pyengine, &RNA_RenderEngine); RenderEngine *bl_engine = pyrna_to_pointer<RenderEngine>(pyengine, &RNA_RenderEngine);
CLOG_INFO(LOG_HYDRA_RENDER, 1, "Engine %s", engine_type);
Engine *engine = nullptr; Engine *engine = nullptr;
try { try {
if (STREQ(engine_type, "VIEWPORT")) { 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()); CLOG_ERROR(LOG_HYDRA_RENDER, "%s", e.what());
} }
if (engine) { CLOG_INFO(LOG_HYDRA_RENDER, 1, "Engine %p", engine);
CLOG_INFO(LOG_HYDRA_RENDER, 1, "Engine %p %s", engine, engine_type);
}
return PyLong_FromVoidPtr(engine); return PyLong_FromVoidPtr(engine);
} }
@ -67,9 +66,9 @@ static PyObject *engine_free_func(PyObject * /*self*/, PyObject *args)
} }
Engine *engine = static_cast<Engine *>(PyLong_AsVoidPtr(pyengine)); Engine *engine = static_cast<Engine *>(PyLong_AsVoidPtr(pyengine));
CLOG_INFO(LOG_HYDRA_RENDER, 1, "Engine %p", engine);
delete engine; delete engine;
CLOG_INFO(LOG_HYDRA_RENDER, 1, "Engine %p", engine);
Py_RETURN_NONE; Py_RETURN_NONE;
} }

View File

@ -13,8 +13,9 @@
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
#include "Eigen/Core"
#include "engine.h" #include "engine.h"
#include "render_task_delegate.h"
namespace blender::render::hydra { namespace blender::render::hydra {
@ -107,6 +108,16 @@ void RenderTaskDelegate::add_aov(pxr::TfToken const &aov_key)
aov_key); aov_key);
if (aov_desc.format == pxr::HdFormatInvalid) { 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; return;
} }
@ -120,7 +131,7 @@ void RenderTaskDelegate::add_aov(pxr::TfToken const &aov_key)
binding.aovName = aov_key; binding.aovName = aov_key;
binding.renderBufferId = buf_id; binding.renderBufferId = buf_id;
binding.aovSettings = aov_desc.aovSettings; binding.aovSettings = aov_desc.aovSettings;
binding.clearValue = pxr::VtValue(pxr::GfVec4f(0)); binding.clearValue = aov_desc.clearValue;
task_params_.aovBindings.push_back(binding); task_params_.aovBindings.push_back(binding);
render_index.GetChangeTracker().MarkTaskDirty(task_id_, pxr::HdChangeTracker::DirtyParams); render_index.GetChangeTracker().MarkTaskDirty(task_id_, pxr::HdChangeTracker::DirtyParams);
@ -134,12 +145,26 @@ void RenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, void *data)
if (!buffer) { if (!buffer) {
return; return;
} }
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(); void *buf_data = buffer->Map();
memcpy(data, memcpy(data, buf_data, len * sizeof(float));
buf_data,
buffer->GetWidth() * buffer->GetHeight() * pxr::HdDataSizeOfFormat(buffer->GetFormat()));
buffer->Unmap(); 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) 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_; tex = &tex_depth_;
} }
else { else {
CLOG_ERROR(LOG_HYDRA_RENDER, "Invalid AOV: %s", aov_key.GetText());
return; 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) void GPURenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, GPUTexture *texture)
{ {
GPUTexture *tex = nullptr; GPUTexture *tex = nullptr;
int c;
if (aov_key == pxr::HdAovTokens->color) { if (aov_key == pxr::HdAovTokens->color) {
tex = tex_color_; tex = tex_color_;
c = 4;
} }
else if (aov_key == pxr::HdAovTokens->depth) { else if (aov_key == pxr::HdAovTokens->depth) {
tex = tex_depth_; tex = tex_depth_;
c = 1;
} }
if (!tex) { if (!tex) {
return; return;

View File

@ -232,19 +232,11 @@ void ViewportEngine::render()
render_task_delegate_->add_aov(pxr::HdAovTokens->color); render_task_delegate_->add_aov(pxr::HdAovTokens->color);
render_task_delegate_->add_aov(pxr::HdAovTokens->depth); 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(); GPUFrameBuffer *view_framebuffer = GPU_framebuffer_active_get();
render_task_delegate_->bind(); render_task_delegate_->bind();
engine_->Execute(render_index_.get(), &tasks); auto t = tasks();
engine_->Execute(render_index_.get(), &t);
render_task_delegate_->unbind(); render_task_delegate_->unbind();
@ -293,7 +285,8 @@ void ViewportEngine::render(bContext *context)
render(); 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) const std::string &status)
{ {
RE_engine_update_stats(bl_engine_, status.c_str(), info.c_str()); RE_engine_update_stats(bl_engine_, status.c_str(), info.c_str());