WIP Make shadows visible for Storm delegate #80

Closed
Vasyl Pidhirskyi wants to merge 16 commits from Vasyl-Pidhirskyi/blender_bn:BLEN-469 into hydra-render

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
13 changed files with 107 additions and 41 deletions
Showing only changes of commit 95dabdca31 - Show all commits

View File

@ -28,6 +28,7 @@ class CustomHydraRenderEngine(bpy.types.HydraRenderEngine):
return { return {
'myBoolean': True, 'myBoolean': True,
'myValue': 8, 'myValue': 8,
'aovToken:Depth': "depth",
} }
# Settings used by the synchronization process. # Settings used by the synchronization process.
@ -43,6 +44,11 @@ class CustomHydraRenderEngine(bpy.types.HydraRenderEngine):
super().update(data, depsgraph) super().update(data, depsgraph)
# Do extra work here # Do extra work here
def update_render_passes(self, scene, render_layer):
if render_layer.use_pass_z:
self.register_pass(scene, render_layer, 'Depth', 1, 'Z', 'VALUE')
# Registration # Registration
def register(): def register():
bpy.utils.register_class(CustomHydraRenderEngine) bpy.utils.register_class(CustomHydraRenderEngine)

View File

@ -1283,6 +1283,7 @@ class HydraRenderEngine(RenderEngine):
# Final render. # Final render.
def update(self, data, depsgraph): def update(self, data, depsgraph):
import _bpy_hydra import _bpy_hydra
import bpy
engine_type = 'PREVIEW' if self.is_preview else 'FINAL' engine_type = 'PREVIEW' if self.is_preview else 'FINAL'
if not self.engine_ptr: if not self.engine_ptr:
@ -1293,7 +1294,7 @@ class HydraRenderEngine(RenderEngine):
for key, val in self.get_sync_settings(engine_type).items(): for key, val in self.get_sync_settings(engine_type).items():
_bpy_hydra.engine_set_sync_setting(self.engine_ptr, key, val) _bpy_hydra.engine_set_sync_setting(self.engine_ptr, key, val)
_bpy_hydra.engine_update(self.engine_ptr, depsgraph, None) _bpy_hydra.engine_update(self.engine_ptr, depsgraph, bpy.context)
for key, val in self.get_render_settings('PREVIEW' if self.is_preview else 'FINAL').items(): for key, val in self.get_render_settings('PREVIEW' if self.is_preview else 'FINAL').items():
_bpy_hydra.engine_set_render_setting(self.engine_ptr, key, val) _bpy_hydra.engine_set_render_setting(self.engine_ptr, key, val)

View File

@ -45,11 +45,11 @@ class InstancerData : public IdData {
void update_double_sided(MaterialData *mat_data); void update_double_sided(MaterialData *mat_data);
/* Following update functions are working together: /* Following update functions are working together:
pre_update() * pre_update()
update_instance() * update_instance()
update_instance() * update_instance()
... * ...
post_update() */ * post_update() */
void pre_update(); void pre_update();
void update_instance(Object *parent_ob, DupliObject *dupli); void update_instance(Object *parent_ob, DupliObject *dupli);
void post_update(); void post_update();

View File

@ -33,8 +33,6 @@ Engine::Engine(RenderEngine *bl_engine, const std::string &render_delegate_name)
pxr::TF_PY_ALLOW_THREADS_IN_SCOPE(); pxr::TF_PY_ALLOW_THREADS_IN_SCOPE();
/* USD has limited support for Vulkan. To make it works USD should be built
* with PXR_ENABLE_VULKAN_SUPPORT=TRUE which is not possible now */
if (GPU_backend_get_type() == GPU_BACKEND_VULKAN) { if (GPU_backend_get_type() == GPU_BACKEND_VULKAN) {
BLI_setenv("HGI_ENABLE_VULKAN", "1"); BLI_setenv("HGI_ENABLE_VULKAN", "1");
} }
@ -120,7 +118,13 @@ void Engine::set_sync_setting(const std::string &key, const pxr::VtValue &val)
void Engine::set_render_setting(const std::string &key, const pxr::VtValue &val) void Engine::set_render_setting(const std::string &key, const pxr::VtValue &val)
{ {
if (STRPREFIX(key.c_str(), "aovToken:")) {
render_delegate_settings_.aovs.add_new(key.substr(key.find(":") + 1),
pxr::TfToken(val.UncheckedGet<std::string>()));
}
else {
render_delegate_->SetRenderSetting(pxr::TfToken(key), val); render_delegate_->SetRenderSetting(pxr::TfToken(key), val);
}
} }
float Engine::renderer_percent_done() float Engine::renderer_percent_done()

View File

@ -29,6 +29,10 @@ namespace blender::render::hydra {
extern struct CLG_LogRef *LOG_RENDER_HYDRA; extern struct CLG_LogRef *LOG_RENDER_HYDRA;
struct RenderDelegateSettings {
Map<std::string, pxr::TfToken> aovs;
};
class Engine { class Engine {
protected: protected:
std::string render_delegate_name_; std::string render_delegate_name_;
@ -44,6 +48,7 @@ class Engine {
std::unique_ptr<io::hydra::HydraSceneDelegate> hydra_scene_delegate_; std::unique_ptr<io::hydra::HydraSceneDelegate> hydra_scene_delegate_;
std::unique_ptr<io::hydra::USDSceneDelegate> usd_scene_delegate_; std::unique_ptr<io::hydra::USDSceneDelegate> usd_scene_delegate_;
RenderDelegateSettings render_delegate_settings_;
std::unique_ptr<RenderTaskDelegate> render_task_delegate_; std::unique_ptr<RenderTaskDelegate> render_task_delegate_;
std::unique_ptr<pxr::HdxFreeCameraSceneDelegate> free_camera_delegate_; std::unique_ptr<pxr::HdxFreeCameraSceneDelegate> free_camera_delegate_;
std::unique_ptr<LightTasksDelegate> light_tasks_delegate_; std::unique_ptr<LightTasksDelegate> light_tasks_delegate_;

View File

@ -23,8 +23,6 @@
namespace blender::render::hydra { namespace blender::render::hydra {
/* FinalEngine implementation */
void FinalEngine::render(Depsgraph *depsgraph) void FinalEngine::render(Depsgraph *depsgraph)
{ {
const Scene *scene = DEG_get_evaluated_scene(depsgraph); const Scene *scene = DEG_get_evaluated_scene(depsgraph);
@ -56,7 +54,18 @@ void FinalEngine::render(Depsgraph *depsgraph)
} }
render_task_delegate_->add_aov(pxr::HdAovTokens->color); render_task_delegate_->add_aov(pxr::HdAovTokens->color);
if (bl_engine_->type->flag & RE_USE_GPU_CONTEXT) {
render_task_delegate_->add_aov(pxr::HdAovTokens->depth); render_task_delegate_->add_aov(pxr::HdAovTokens->depth);
}
RenderResult *result = RE_engine_get_result(bl_engine_);
RenderLayer *layer = (RenderLayer *)result->layers.first;
for (RenderPass *pass = (RenderPass *)layer->passes.first; pass != nullptr; pass = pass->next) {
pxr::TfToken *aov_token = render_delegate_settings_.aovs.lookup_ptr(pass->name);
if (aov_token) {
render_task_delegate_->add_aov(*aov_token);
}
}
pxr::HdTaskSharedPtrVector tasks; pxr::HdTaskSharedPtrVector tasks;
if (light_tasks_delegate_) { if (light_tasks_delegate_) {
@ -118,14 +127,10 @@ void FinalEngine::update_render_result()
if (rlayer) { if (rlayer) {
LISTBASE_FOREACH (RenderPass *, rpass, &rlayer->passes) { LISTBASE_FOREACH (RenderPass *, rpass, &rlayer->passes) {
pxr::TfToken aov_key; pxr::TfToken *aov_token = render_delegate_settings_.aovs.lookup_ptr(rpass->name);
if (STREQ(rpass->name, "Combined")) { if (aov_token) {
aov_key = pxr::HdAovTokens->color; render_task_delegate_->read_aov(*aov_token, rpass->ibuf->float_buffer.data);
} }
else if (STREQ(rpass->name, "Depth")) {
aov_key = pxr::HdAovTokens->depth;
}
render_task_delegate_->read_aov(aov_key, rpass->ibuf->float_buffer.data);
} }
} }

View File

@ -2,6 +2,7 @@
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */ * SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
#include "light_tasks_delegate.h" #include "light_tasks_delegate.h"
#include "engine.h"
namespace blender::render::hydra { namespace blender::render::hydra {
@ -15,10 +16,15 @@ LightTasksDelegate::LightTasksDelegate(pxr::HdRenderIndex *parent_index,
GetRenderIndex().InsertTask<pxr::HdxSkydomeTask>(this, skydome_task_id_); GetRenderIndex().InsertTask<pxr::HdxSkydomeTask>(this, skydome_task_id_);
shadow_task_id_ = GetDelegateID().AppendElementString("shadowTask"); shadow_task_id_ = GetDelegateID().AppendElementString("shadowTask");
GetRenderIndex().InsertTask<pxr::HdxShadowTask>(this, shadow_task_id_); GetRenderIndex().InsertTask<pxr::HdxShadowTask>(this, shadow_task_id_);
CLOG_INFO(LOG_RENDER_HYDRA, 1, "%s", simple_task_id_.GetText());
CLOG_INFO(LOG_RENDER_HYDRA, 1, "%s", skydome_task_id_.GetText());
} }
pxr::VtValue LightTasksDelegate::Get(pxr::SdfPath const &id, pxr::TfToken const &key) pxr::VtValue LightTasksDelegate::Get(pxr::SdfPath const &id, pxr::TfToken const &key)
{ {
CLOG_INFO(LOG_RENDER_HYDRA, 3, "%s, %s", id.GetText(), key.GetText());
if (key == pxr::HdTokens->params) { if (key == pxr::HdTokens->params) {
if (id == simple_task_id_) { if (id == simple_task_id_) {
return pxr::VtValue(simple_task_params_); return pxr::VtValue(simple_task_params_);
@ -46,8 +52,8 @@ pxr::HdTaskSharedPtr LightTasksDelegate::shadow_task()
pxr::HdTaskSharedPtr LightTasksDelegate::skydome_task() pxr::HdTaskSharedPtr LightTasksDelegate::skydome_task()
{ {
/* Note that this task is intended to be the first "Render Task", /* Note that this task is intended to be the first "Render Task",
so that the AOV's are properly cleared, however it * so that the AOV's are properly cleared, however it
does not spawn a HdRenderPass. */ * does not spawn a HdRenderPass. */
return GetRenderIndex().GetTask(skydome_task_id_); return GetRenderIndex().GetTask(skydome_task_id_);
} }

View File

@ -13,6 +13,9 @@
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
#include "engine.h"
#include "render_task_delegate.h"
namespace blender::render::hydra { namespace blender::render::hydra {
RenderTaskDelegate::RenderTaskDelegate(pxr::HdRenderIndex *parent_index, RenderTaskDelegate::RenderTaskDelegate(pxr::HdRenderIndex *parent_index,
@ -24,10 +27,14 @@ RenderTaskDelegate::RenderTaskDelegate(pxr::HdRenderIndex *parent_index,
task_params_.enableLighting = true; task_params_.enableLighting = true;
task_params_.alphaThreshold = 0.1f; task_params_.alphaThreshold = 0.1f;
CLOG_INFO(LOG_RENDER_HYDRA, 1, "%s", task_id_.GetText());
} }
pxr::VtValue RenderTaskDelegate::Get(pxr::SdfPath const & /*id*/, pxr::TfToken const &key) pxr::VtValue RenderTaskDelegate::Get(pxr::SdfPath const &id, pxr::TfToken const &key)
{ {
CLOG_INFO(LOG_RENDER_HYDRA, 3, "%s, %s", id.GetText(), key.GetText());
if (key == pxr::HdTokens->params) { if (key == pxr::HdTokens->params) {
return pxr::VtValue(task_params_); return pxr::VtValue(task_params_);
} }
@ -38,13 +45,17 @@ pxr::VtValue RenderTaskDelegate::Get(pxr::SdfPath const & /*id*/, pxr::TfToken c
return pxr::VtValue(); return pxr::VtValue();
} }
pxr::TfTokenVector RenderTaskDelegate::GetTaskRenderTags(pxr::SdfPath const & /*id*/) pxr::TfTokenVector RenderTaskDelegate::GetTaskRenderTags(pxr::SdfPath const &id)
{ {
CLOG_INFO(LOG_RENDER_HYDRA, 3, "%s", id.GetText());
return {pxr::HdRenderTagTokens->geometry}; return {pxr::HdRenderTagTokens->geometry};
} }
pxr::HdRenderBufferDescriptor RenderTaskDelegate::GetRenderBufferDescriptor(pxr::SdfPath const &id) pxr::HdRenderBufferDescriptor RenderTaskDelegate::GetRenderBufferDescriptor(pxr::SdfPath const &id)
{ {
CLOG_INFO(LOG_RENDER_HYDRA, 3, "%s", id.GetText());
return buffer_descriptors_[id]; return buffer_descriptors_[id];
} }
@ -95,6 +106,10 @@ void RenderTaskDelegate::add_aov(pxr::TfToken const &aov_key)
pxr::HdAovDescriptor aov_desc = render_index.GetRenderDelegate()->GetDefaultAovDescriptor( pxr::HdAovDescriptor aov_desc = render_index.GetRenderDelegate()->GetDefaultAovDescriptor(
aov_key); aov_key);
if (aov_desc.format == pxr::HdFormatInvalid) {
return;
}
int w = task_params_.viewport[2] - task_params_.viewport[0]; int w = task_params_.viewport[2] - task_params_.viewport[0];
int h = task_params_.viewport[3] - task_params_.viewport[1]; int h = task_params_.viewport[3] - task_params_.viewport[1];
render_index.InsertBprim(pxr::HdPrimTypeTokens->renderBuffer, this, buf_id); render_index.InsertBprim(pxr::HdPrimTypeTokens->renderBuffer, this, buf_id);
@ -108,6 +123,8 @@ void RenderTaskDelegate::add_aov(pxr::TfToken const &aov_key)
binding.clearValue = pxr::VtValue(pxr::GfVec4f(0)); binding.clearValue = pxr::VtValue(pxr::GfVec4f(0));
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);
CLOG_INFO(LOG_RENDER_HYDRA, 1, "%s", aov_key.GetText());
} }
void RenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, void *data) void RenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, void *data)
@ -150,6 +167,7 @@ pxr::SdfPath RenderTaskDelegate::buffer_id(pxr::TfToken const &aov_key) const
GPURenderTaskDelegate::~GPURenderTaskDelegate() GPURenderTaskDelegate::~GPURenderTaskDelegate()
{ {
unbind();
if (tex_color_) { if (tex_color_) {
GPU_texture_free(tex_color_); GPU_texture_free(tex_color_);
} }
@ -188,7 +206,7 @@ void GPURenderTaskDelegate::add_aov(pxr::TfToken const &aov_key)
tex = &tex_color_; tex = &tex_color_;
} }
else if (aov_key == pxr::HdAovTokens->depth) { else if (aov_key == pxr::HdAovTokens->depth) {
format = GPU_DEPTH32F_STENCIL8; format = GPU_DEPTH_COMPONENT32F;
tex = &tex_depth_; tex = &tex_depth_;
} }
else { else {
@ -206,6 +224,8 @@ void GPURenderTaskDelegate::add_aov(pxr::TfToken const &aov_key)
format, format,
GPU_TEXTURE_USAGE_GENERAL, GPU_TEXTURE_USAGE_GENERAL,
nullptr); nullptr);
CLOG_INFO(LOG_RENDER_HYDRA, 1, "%s", aov_key.GetText());
} }
void GPURenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, void *data) void GPURenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, void *data)
@ -263,7 +283,7 @@ void GPURenderTaskDelegate::bind()
/* Workaround missing/buggy VAOs in hgiGL and hdSt. For OpenGL compatibility /* Workaround missing/buggy VAOs in hgiGL and hdSt. For OpenGL compatibility
* profile this is not a problem, but for core profile it is. */ * profile this is not a problem, but for core profile it is. */
if (GPU_backend_get_type() == GPU_BACKEND_OPENGL) { if (VAO_ == 0 && GPU_backend_get_type() == GPU_BACKEND_OPENGL) {
glGenVertexArrays(1, &VAO_); glGenVertexArrays(1, &VAO_);
glBindVertexArray(VAO_); glBindVertexArray(VAO_);
} }
@ -271,10 +291,25 @@ void GPURenderTaskDelegate::bind()
void GPURenderTaskDelegate::unbind() void GPURenderTaskDelegate::unbind()
{ {
if (GPU_backend_get_type() == GPU_BACKEND_OPENGL) { if (VAO_) {
glDeleteVertexArrays(1, &VAO_); glDeleteVertexArrays(1, &VAO_);
VAO_ = 0;
} }
if (framebuffer_) {
GPU_framebuffer_free(framebuffer_); GPU_framebuffer_free(framebuffer_);
framebuffer_ = nullptr;
}
}
GPUTexture *GPURenderTaskDelegate::aov_texture(pxr::TfToken const &aov_key)
{
if (aov_key == pxr::HdAovTokens->color) {
return tex_color_;
}
if (aov_key == pxr::HdAovTokens->depth) {
return tex_depth_;
}
return nullptr;
} }
} // namespace blender::render::hydra } // namespace blender::render::hydra

View File

@ -30,8 +30,8 @@ class RenderTaskDelegate : public pxr::HdSceneDelegate {
pxr::HdRenderBufferDescriptor GetRenderBufferDescriptor(pxr::SdfPath const &id) override; pxr::HdRenderBufferDescriptor GetRenderBufferDescriptor(pxr::SdfPath const &id) override;
pxr::HdTaskSharedPtr task(); pxr::HdTaskSharedPtr task();
bool is_converged();
void set_camera(pxr::SdfPath const &camera_id); void set_camera(pxr::SdfPath const &camera_id);
virtual bool is_converged();
virtual void set_viewport(pxr::GfVec4d const &viewport); virtual void set_viewport(pxr::GfVec4d const &viewport);
virtual void add_aov(pxr::TfToken const &aov_key); virtual void add_aov(pxr::TfToken const &aov_key);
virtual void read_aov(pxr::TfToken const &aov_key, void *data); virtual void read_aov(pxr::TfToken const &aov_key, void *data);
@ -60,6 +60,7 @@ class GPURenderTaskDelegate : public RenderTaskDelegate {
void read_aov(pxr::TfToken const &aov_key, GPUTexture *texture) override; void read_aov(pxr::TfToken const &aov_key, GPUTexture *texture) override;
void bind() override; void bind() override;
void unbind() override; void unbind() override;
GPUTexture *aov_texture(pxr::TfToken const &aov_key);
}; };
} // namespace blender::render::hydra } // namespace blender::render::hydra

View File

View File

@ -188,13 +188,11 @@ void DrawTexture::write_data(int width, int height, const void *data)
(float *)data); (float *)data);
} }
void DrawTexture::draw(GPUShader *shader, const pxr::GfVec4d &viewport) void DrawTexture::draw(GPUShader *shader, const pxr::GfVec4d &viewport, GPUTexture *tex)
{
draw(shader, texture_, viewport);
}
void DrawTexture::draw(GPUShader *shader, GPUTexture *tex, const pxr::GfVec4d &viewport)
{ {
if (!tex) {
tex = texture_;
}
int slot = GPU_shader_get_sampler_binding(shader, "image"); int slot = GPU_shader_get_sampler_binding(shader, "image");
GPU_texture_bind(tex, slot); GPU_texture_bind(tex, slot);
GPU_shader_uniform_1i(shader, "image", slot); GPU_shader_uniform_1i(shader, "image", slot);
@ -260,14 +258,20 @@ void ViewportEngine::render(Depsgraph *depsgraph, bContext *context)
render_task_delegate_->unbind(); render_task_delegate_->unbind();
draw_texture_.write_data(view_settings.width(), view_settings.height(), nullptr);
render_task_delegate_->read_aov(pxr::HdAovTokens->color, draw_texture_.texture());
GPU_framebuffer_bind(view_framebuffer); GPU_framebuffer_bind(view_framebuffer);
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_IMAGE); GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_IMAGE);
GPU_shader_bind(shader); GPU_shader_bind(shader);
GPURenderTaskDelegate *gpu_task = dynamic_cast<GPURenderTaskDelegate *>(
render_task_delegate_.get());
if (gpu_task) {
draw_texture_.draw(shader, viewport, gpu_task->aov_texture(pxr::HdAovTokens->color));
}
else {
draw_texture_.write_data(view_settings.width(), view_settings.height(), nullptr);
render_task_delegate_->read_aov(pxr::HdAovTokens->color, draw_texture_.texture());
draw_texture_.draw(shader, viewport); draw_texture_.draw(shader, viewport);
}
GPU_shader_unbind(); GPU_shader_unbind();

View File

@ -23,8 +23,7 @@ class DrawTexture {
~DrawTexture(); ~DrawTexture();
void write_data(int width, int height, const void *data); void write_data(int width, int height, const void *data);
void draw(GPUShader *shader, const pxr::GfVec4d &viewport); void draw(GPUShader *shader, const pxr::GfVec4d &viewport, GPUTexture *tex = nullptr);
void draw(GPUShader *shader, GPUTexture *tex, const pxr::GfVec4d &viewport);
GPUTexture *texture() const; GPUTexture *texture() const;
private: private: