From f23e3099ef8ccf2a9c28dd4a24671d0228a53d12 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Fri, 28 Jul 2023 01:53:14 +0300 Subject: [PATCH 01/13] Make viewport with GPU context to render into separate framebuffer --- .../render/hydra/render_task_delegate.cc | 13 ++++ .../render/hydra/render_task_delegate.h | 1 + .../blender/render/hydra/viewport_engine.cc | 64 +++++++++++++------ 3 files changed, 60 insertions(+), 18 deletions(-) diff --git a/source/blender/render/hydra/render_task_delegate.cc b/source/blender/render/hydra/render_task_delegate.cc index 02d2392ddf00..450cc5fc4c2c 100644 --- a/source/blender/render/hydra/render_task_delegate.cc +++ b/source/blender/render/hydra/render_task_delegate.cc @@ -105,6 +105,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)); task_params_.aovBindings.push_back(binding); render_index.GetChangeTracker().MarkTaskDirty(task_id_, pxr::HdChangeTracker::DirtyParams); } @@ -237,6 +238,18 @@ void GPURenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, GPUTexture *te MEM_freeN(tex_data); } +GPUTexture *GPURenderTaskDelegate::aov_texture(pxr::TfToken const &aov_key) const +{ + GPUTexture *tex = nullptr; + if (aov_key == pxr::HdAovTokens->color) { + tex = tex_color_; + } + else if (aov_key == pxr::HdAovTokens->depth) { + tex = tex_depth_; + } + return tex; +} + void GPURenderTaskDelegate::bind() { if (!framebuffer_) { diff --git a/source/blender/render/hydra/render_task_delegate.h b/source/blender/render/hydra/render_task_delegate.h index 5952b8f86859..5fe7afe9b933 100644 --- a/source/blender/render/hydra/render_task_delegate.h +++ b/source/blender/render/hydra/render_task_delegate.h @@ -57,6 +57,7 @@ class GPURenderTaskDelegate : public RenderTaskDelegate { void add_aov(pxr::TfToken const &aov_key) override; void read_aov(pxr::TfToken const &aov_key, void *data) override; void read_aov(pxr::TfToken const &aov_key, GPUTexture *texture) override; + GPUTexture *aov_texture(pxr::TfToken const &aov_key) const; void bind() override; void unbind() override; }; diff --git a/source/blender/render/hydra/viewport_engine.cc b/source/blender/render/hydra/viewport_engine.cc index 4438e7bce56d..b1ed6dffbbcd 100644 --- a/source/blender/render/hydra/viewport_engine.cc +++ b/source/blender/render/hydra/viewport_engine.cc @@ -183,7 +183,7 @@ void DrawTexture::write_data(int width, int height, const void *data) width, height, 1, - GPU_RGBA16F, + GPU_RGBA32F, GPU_TEXTURE_USAGE_GENERAL, (float *)data); } @@ -237,20 +237,15 @@ void ViewportEngine::render(Depsgraph *depsgraph, bContext *context) light_tasks_delegate_->set_viewport(viewport); } - if ((bl_engine_->type->flag & RE_USE_GPU_CONTEXT) == 0) { - render_task_delegate_->add_aov(pxr::HdAovTokens->color); - } + render_task_delegate_->add_aov(pxr::HdAovTokens->color); + render_task_delegate_->add_aov(pxr::HdAovTokens->depth); - /* Workaround missing/buggy VAOs in hgiGL and hdSt. For OpenGL compatibility - * profile this is not a problem, but for core profile it is. */ - GLuint VAO; - if (GPU_backend_get_type() == GPU_BACKEND_OPENGL) { - glGenVertexArrays(1, &VAO); - glBindVertexArray(VAO); - } + //if ((bl_engine_->type->flag & RE_USE_GPU_CONTEXT) == 0) { + //render_task_delegate_->bind(); + //} - GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_IMAGE); - GPU_shader_bind(shader); + ///* Workaround missing/buggy VAOs in hgiGL and hdSt. For OpenGL compatibility + // * profile this is not a problem, but for core profile it is. */ pxr::HdTaskSharedPtrVector tasks; if (light_tasks_delegate_) { @@ -260,19 +255,52 @@ void ViewportEngine::render(Depsgraph *depsgraph, bContext *context) tasks.push_back(light_tasks_delegate_->simple_task()); } tasks.push_back(render_task_delegate_->task()); + + GPUFrameBuffer *prev_fb = GPU_framebuffer_active_get(); + GPUFrameBuffer *framebuffer = nullptr; + GLuint VAO; + if (bl_engine_->type->flag & RE_USE_GPU_CONTEXT) { + GPURenderTaskDelegate *r = dynamic_cast(render_task_delegate_.get()); + framebuffer = GPU_framebuffer_create("fb_render_hydra"); + GPU_framebuffer_ensure_config( + &framebuffer, + {GPU_ATTACHMENT_TEXTURE(r->aov_texture(pxr::HdAovTokens->depth)), + GPU_ATTACHMENT_TEXTURE(r->aov_texture(pxr::HdAovTokens->color))}); + GPU_framebuffer_bind(framebuffer); + float clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + GPU_framebuffer_clear_color_depth(framebuffer, clear_color, 1.0f); + if (GPU_backend_get_type() == GPU_BACKEND_OPENGL) { + glGenVertexArrays(1, &VAO); + glBindVertexArray(VAO); + } + } + engine_->Execute(render_index_.get(), &tasks); - if ((bl_engine_->type->flag & RE_USE_GPU_CONTEXT) == 0) { + if (bl_engine_->type->flag & RE_USE_GPU_CONTEXT) { + if (GPU_backend_get_type() == GPU_BACKEND_OPENGL) { + glDeleteVertexArrays(1, &VAO); + } + GPU_framebuffer_free(framebuffer); + } + + //if ((bl_engine_->type->flag & RE_USE_GPU_CONTEXT) == 0) { 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(prev_fb); + GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_IMAGE); + GPU_shader_bind(shader); + draw_texture_.draw(shader, viewport); - } + //} GPU_shader_unbind(); - if (GPU_backend_get_type() == GPU_BACKEND_OPENGL) { - glDeleteVertexArrays(1, &VAO); - } + //if (GPU_backend_get_type() == GPU_BACKEND_OPENGL) { + // glDeleteVertexArrays(1, &VAO); + //} + //render_task_delegate_->unbind(); if (renderer_percent_done() == 0.0f) { time_begin_ = PIL_check_seconds_timer(); -- 2.30.2 From 6ba2f8dbb4b2ed0c045af2aebabcbfb8f43ff888 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Fri, 28 Jul 2023 02:32:38 +0300 Subject: [PATCH 02/13] Fix read_aov() to texture by checking data format --- source/blender/render/hydra/render_task_delegate.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/render/hydra/render_task_delegate.cc b/source/blender/render/hydra/render_task_delegate.cc index 450cc5fc4c2c..f8590223517f 100644 --- a/source/blender/render/hydra/render_task_delegate.cc +++ b/source/blender/render/hydra/render_task_delegate.cc @@ -131,8 +131,11 @@ void RenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, GPUTexture *textu if (!buffer) { return; } + eGPUDataFormat format = buffer->GetFormat() == pxr::HdFormat::HdFormatFloat16Vec4 ? + GPU_DATA_HALF_FLOAT : + GPU_DATA_FLOAT; void *buf_data = buffer->Map(); - GPU_texture_update(texture, GPU_DATA_FLOAT, buf_data); + GPU_texture_update(texture, format, buf_data); buffer->Unmap(); } -- 2.30.2 From 4d8d9ae681dd3be079590aff46b86b2580801068 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Fri, 28 Jul 2023 09:53:32 +0300 Subject: [PATCH 03/13] Fixes and code improvements --- source/blender/render/hydra/final_engine.cc | 5 +- .../render/hydra/render_task_delegate.cc | 32 +++++------ .../render/hydra/render_task_delegate.h | 2 +- .../blender/render/hydra/viewport_engine.cc | 53 ++++--------------- 4 files changed, 25 insertions(+), 67 deletions(-) diff --git a/source/blender/render/hydra/final_engine.cc b/source/blender/render/hydra/final_engine.cc index 12fe44325d62..d70a3371ec20 100644 --- a/source/blender/render/hydra/final_engine.cc +++ b/source/blender/render/hydra/final_engine.cc @@ -57,8 +57,6 @@ void FinalEngine::render(Depsgraph *depsgraph) render_task_delegate_->add_aov(pxr::HdAovTokens->color); render_task_delegate_->add_aov(pxr::HdAovTokens->depth); - render_task_delegate_->bind(); - pxr::HdTaskSharedPtrVector tasks; if (light_tasks_delegate_) { if (scene->r.alphamode != R_ALPHAPREMUL) { @@ -67,6 +65,9 @@ void FinalEngine::render(Depsgraph *depsgraph) 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); char elapsed_time[32]; diff --git a/source/blender/render/hydra/render_task_delegate.cc b/source/blender/render/hydra/render_task_delegate.cc index f8590223517f..79ef78a6628a 100644 --- a/source/blender/render/hydra/render_task_delegate.cc +++ b/source/blender/render/hydra/render_task_delegate.cc @@ -148,6 +148,16 @@ pxr::SdfPath RenderTaskDelegate::buffer_id(pxr::TfToken const &aov_key) const return GetDelegateID().AppendElementString("aov_" + aov_key.GetString()); } +GPURenderTaskDelegate::~GPURenderTaskDelegate() +{ + if (tex_color_) { + GPU_texture_free(tex_color_); + } + if (tex_depth_) { + GPU_texture_free(tex_depth_); + } +} + void GPURenderTaskDelegate::set_viewport(pxr::GfVec4d const &viewport) { if (task_params_.viewport == viewport) { @@ -241,23 +251,9 @@ void GPURenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, GPUTexture *te MEM_freeN(tex_data); } -GPUTexture *GPURenderTaskDelegate::aov_texture(pxr::TfToken const &aov_key) const -{ - GPUTexture *tex = nullptr; - if (aov_key == pxr::HdAovTokens->color) { - tex = tex_color_; - } - else if (aov_key == pxr::HdAovTokens->depth) { - tex = tex_depth_; - } - return tex; -} - void GPURenderTaskDelegate::bind() { - if (!framebuffer_) { - framebuffer_ = GPU_framebuffer_create("fb_render_hydra"); - } + framebuffer_ = GPU_framebuffer_create("fb_render_hydra"); GPU_framebuffer_ensure_config( &framebuffer_, {GPU_ATTACHMENT_TEXTURE(tex_depth_), GPU_ATTACHMENT_TEXTURE(tex_color_)}); GPU_framebuffer_bind(framebuffer_); @@ -268,9 +264,7 @@ void GPURenderTaskDelegate::bind() /* Workaround missing/buggy VAOs in hgiGL and hdSt. For OpenGL compatibility * profile this is not a problem, but for core profile it is. */ if (GPU_backend_get_type() == GPU_BACKEND_OPENGL) { - if (VAO_ == 0) { - glGenVertexArrays(1, &VAO_); - } + glGenVertexArrays(1, &VAO_); glBindVertexArray(VAO_); } } @@ -281,8 +275,6 @@ void GPURenderTaskDelegate::unbind() glDeleteVertexArrays(1, &VAO_); } GPU_framebuffer_free(framebuffer_); - GPU_texture_free(tex_color_); - GPU_texture_free(tex_depth_); } } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/render_task_delegate.h b/source/blender/render/hydra/render_task_delegate.h index 5fe7afe9b933..d61d6e93a4e3 100644 --- a/source/blender/render/hydra/render_task_delegate.h +++ b/source/blender/render/hydra/render_task_delegate.h @@ -52,12 +52,12 @@ class GPURenderTaskDelegate : public RenderTaskDelegate { public: using RenderTaskDelegate::RenderTaskDelegate; + ~GPURenderTaskDelegate() override; void set_viewport(pxr::GfVec4d const &viewport) override; void add_aov(pxr::TfToken const &aov_key) override; void read_aov(pxr::TfToken const &aov_key, void *data) override; void read_aov(pxr::TfToken const &aov_key, GPUTexture *texture) override; - GPUTexture *aov_texture(pxr::TfToken const &aov_key) const; void bind() override; void unbind() override; }; diff --git a/source/blender/render/hydra/viewport_engine.cc b/source/blender/render/hydra/viewport_engine.cc index b1ed6dffbbcd..ee0df57a2e8c 100644 --- a/source/blender/render/hydra/viewport_engine.cc +++ b/source/blender/render/hydra/viewport_engine.cc @@ -240,13 +240,6 @@ void ViewportEngine::render(Depsgraph *depsgraph, bContext *context) render_task_delegate_->add_aov(pxr::HdAovTokens->color); render_task_delegate_->add_aov(pxr::HdAovTokens->depth); - //if ((bl_engine_->type->flag & RE_USE_GPU_CONTEXT) == 0) { - //render_task_delegate_->bind(); - //} - - ///* Workaround missing/buggy VAOs in hgiGL and hdSt. For OpenGL compatibility - // * profile this is not a problem, but for core profile it is. */ - pxr::HdTaskSharedPtrVector tasks; if (light_tasks_delegate_) { if (scene->r.alphamode != R_ALPHAPREMUL) { @@ -256,52 +249,24 @@ void ViewportEngine::render(Depsgraph *depsgraph, bContext *context) } tasks.push_back(render_task_delegate_->task()); - GPUFrameBuffer *prev_fb = GPU_framebuffer_active_get(); - GPUFrameBuffer *framebuffer = nullptr; - GLuint VAO; - if (bl_engine_->type->flag & RE_USE_GPU_CONTEXT) { - GPURenderTaskDelegate *r = dynamic_cast(render_task_delegate_.get()); - framebuffer = GPU_framebuffer_create("fb_render_hydra"); - GPU_framebuffer_ensure_config( - &framebuffer, - {GPU_ATTACHMENT_TEXTURE(r->aov_texture(pxr::HdAovTokens->depth)), - GPU_ATTACHMENT_TEXTURE(r->aov_texture(pxr::HdAovTokens->color))}); - GPU_framebuffer_bind(framebuffer); - float clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - GPU_framebuffer_clear_color_depth(framebuffer, clear_color, 1.0f); - if (GPU_backend_get_type() == GPU_BACKEND_OPENGL) { - glGenVertexArrays(1, &VAO); - glBindVertexArray(VAO); - } - } + GPUFrameBuffer *view_framebuffer = GPU_framebuffer_active_get(); + render_task_delegate_->bind(); engine_->Execute(render_index_.get(), &tasks); - if (bl_engine_->type->flag & RE_USE_GPU_CONTEXT) { - if (GPU_backend_get_type() == GPU_BACKEND_OPENGL) { - glDeleteVertexArrays(1, &VAO); - } - GPU_framebuffer_free(framebuffer); - } + render_task_delegate_->unbind(); - //if ((bl_engine_->type->flag & RE_USE_GPU_CONTEXT) == 0) { - draw_texture_.write_data(view_settings.width(), view_settings.height(), nullptr); - render_task_delegate_->read_aov(pxr::HdAovTokens->color, draw_texture_.texture()); + 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(prev_fb); - GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_IMAGE); - GPU_shader_bind(shader); + GPU_framebuffer_bind(view_framebuffer); + GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_IMAGE); + GPU_shader_bind(shader); - draw_texture_.draw(shader, viewport); - //} + draw_texture_.draw(shader, viewport); GPU_shader_unbind(); - //if (GPU_backend_get_type() == GPU_BACKEND_OPENGL) { - // glDeleteVertexArrays(1, &VAO); - //} - //render_task_delegate_->unbind(); - if (renderer_percent_done() == 0.0f) { time_begin_ = PIL_check_seconds_timer(); } -- 2.30.2 From 832090903ebdf60fd32e2b063cfb7484a8e18c86 Mon Sep 17 00:00:00 2001 From: Vasyl-Pidhirskyi Date: Fri, 28 Jul 2023 15:47:12 +0300 Subject: [PATCH 04/13] Implemented shadow_task within light_tasks_delegate. Added shadow_task to final and viewport engines. Added use_storm_shadows to struct ShadingSettings. --- .../io/usd/hydra/hydra_scene_delegate.h | 1 + source/blender/render/hydra/final_engine.cc | 2 ++ .../render/hydra/light_tasks_delegate.cc | 27 +++++++++++++++++++ .../render/hydra/light_tasks_delegate.h | 5 ++++ .../blender/render/hydra/viewport_engine.cc | 2 ++ 5 files changed, 37 insertions(+) diff --git a/source/blender/io/usd/hydra/hydra_scene_delegate.h b/source/blender/io/usd/hydra/hydra_scene_delegate.h index ac7988445134..9299e2657b0a 100644 --- a/source/blender/io/usd/hydra/hydra_scene_delegate.h +++ b/source/blender/io/usd/hydra/hydra_scene_delegate.h @@ -44,6 +44,7 @@ class HydraSceneDelegate : public pxr::HdSceneDelegate { std::string studiolight_name; float studiolight_rotation; float studiolight_intensity; + bool use_storm_shadows = false; bool operator==(const ShadingSettings &other); }; diff --git a/source/blender/render/hydra/final_engine.cc b/source/blender/render/hydra/final_engine.cc index d70a3371ec20..34d6030c4739 100644 --- a/source/blender/render/hydra/final_engine.cc +++ b/source/blender/render/hydra/final_engine.cc @@ -52,6 +52,7 @@ void FinalEngine::render(Depsgraph *depsgraph) render_task_delegate_->set_viewport(pxr::GfVec4d(0, 0, resolution_[0], resolution_[1])); if (light_tasks_delegate_) { light_tasks_delegate_->set_viewport(pxr::GfVec4d(0, 0, resolution_[0], resolution_[1])); + light_tasks_delegate_->set_shadows(hydra_scene_delegate_->shading_settings.use_storm_shadows); } render_task_delegate_->add_aov(pxr::HdAovTokens->color); @@ -63,6 +64,7 @@ void FinalEngine::render(Depsgraph *depsgraph) tasks.push_back(light_tasks_delegate_->skydome_task()); } tasks.push_back(light_tasks_delegate_->simple_task()); + tasks.push_back(light_tasks_delegate_->shadow_task()); } tasks.push_back(render_task_delegate_->task()); diff --git a/source/blender/render/hydra/light_tasks_delegate.cc b/source/blender/render/hydra/light_tasks_delegate.cc index c66cfab748cd..b5ef40765edc 100644 --- a/source/blender/render/hydra/light_tasks_delegate.cc +++ b/source/blender/render/hydra/light_tasks_delegate.cc @@ -13,6 +13,8 @@ LightTasksDelegate::LightTasksDelegate(pxr::HdRenderIndex *parent_index, GetRenderIndex().InsertTask(this, simple_task_id_); skydome_task_id_ = GetDelegateID().AppendElementString("skydomeTask"); GetRenderIndex().InsertTask(this, skydome_task_id_); + shadow_task_id_ = GetDelegateID().AppendElementString("shadowTask"); + GetRenderIndex().InsertTask(this, shadow_task_id_); } pxr::VtValue LightTasksDelegate::Get(pxr::SdfPath const &id, pxr::TfToken const &key) @@ -24,6 +26,9 @@ pxr::VtValue LightTasksDelegate::Get(pxr::SdfPath const &id, pxr::TfToken const else if (id == skydome_task_id_) { return pxr::VtValue(skydome_task_params_); } + else if (id == shadow_task_id_) { + return pxr::VtValue(shadow_task_params_); + } } return pxr::VtValue(); } @@ -33,6 +38,11 @@ pxr::HdTaskSharedPtr LightTasksDelegate::simple_task() return GetRenderIndex().GetTask(simple_task_id_); } +pxr::HdTaskSharedPtr LightTasksDelegate::shadow_task() +{ + return GetRenderIndex().GetTask(shadow_task_id_); +} + pxr::HdTaskSharedPtr LightTasksDelegate::skydome_task() { /* Note that this task is intended to be the first "Render Task", @@ -52,6 +62,23 @@ void LightTasksDelegate::set_camera(pxr::SdfPath const &camera_id) skydome_task_params_.camera = camera_id; GetRenderIndex().GetChangeTracker().MarkTaskDirty(skydome_task_id_, pxr::HdChangeTracker::DirtyParams); + + GetRenderIndex().GetChangeTracker().MarkTaskDirty(shadow_task_id_, + pxr::HdChangeTracker::DirtyParams); +} + +void LightTasksDelegate::set_shadows(bool const &enable_shadows) +{ + if (simple_task_params_.enableShadows == enable_shadows) { + return; + } + shadow_task_params_.depthBiasEnable = true; + simple_task_params_.enableShadows = enable_shadows; + GetRenderIndex().GetChangeTracker().MarkTaskDirty(simple_task_id_, + pxr::HdChangeTracker::DirtyParams); + + GetRenderIndex().GetChangeTracker().MarkTaskDirty(shadow_task_id_, + pxr::HdChangeTracker::DirtyParams); } void LightTasksDelegate::set_viewport(pxr::GfVec4d const &viewport) diff --git a/source/blender/render/hydra/light_tasks_delegate.h b/source/blender/render/hydra/light_tasks_delegate.h index d1131392d1c3..4b66df064eb0 100644 --- a/source/blender/render/hydra/light_tasks_delegate.h +++ b/source/blender/render/hydra/light_tasks_delegate.h @@ -4,6 +4,7 @@ #pragma once #include +#include #include #include @@ -19,14 +20,18 @@ class LightTasksDelegate : public pxr::HdSceneDelegate { pxr::HdTaskSharedPtr simple_task(); pxr::HdTaskSharedPtr skydome_task(); + pxr::HdTaskSharedPtr shadow_task(); void set_camera(pxr::SdfPath const &camera_id); void set_viewport(pxr::GfVec4d const &viewport); + void set_shadows(bool const &enable_shadows); private: pxr::SdfPath simple_task_id_; pxr::SdfPath skydome_task_id_; + pxr::SdfPath shadow_task_id_; pxr::HdxSimpleLightTaskParams simple_task_params_; pxr::HdxRenderTaskParams skydome_task_params_; + pxr::HdxShadowTaskParams shadow_task_params_; }; } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/viewport_engine.cc b/source/blender/render/hydra/viewport_engine.cc index ee0df57a2e8c..9bbf7ca75ff6 100644 --- a/source/blender/render/hydra/viewport_engine.cc +++ b/source/blender/render/hydra/viewport_engine.cc @@ -235,6 +235,7 @@ void ViewportEngine::render(Depsgraph *depsgraph, bContext *context) render_task_delegate_->set_viewport(viewport); if (light_tasks_delegate_) { light_tasks_delegate_->set_viewport(viewport); + light_tasks_delegate_->set_shadows(hydra_scene_delegate_->shading_settings.use_storm_shadows); } render_task_delegate_->add_aov(pxr::HdAovTokens->color); @@ -246,6 +247,7 @@ void ViewportEngine::render(Depsgraph *depsgraph, bContext *context) tasks.push_back(light_tasks_delegate_->skydome_task()); } tasks.push_back(light_tasks_delegate_->simple_task()); + tasks.push_back(light_tasks_delegate_->shadow_task()); } tasks.push_back(render_task_delegate_->task()); -- 2.30.2 From 92ede528281a79ac77d37900ededfa216c81e422 Mon Sep 17 00:00:00 2001 From: Vasyl-Pidhirskyi Date: Fri, 28 Jul 2023 16:03:48 +0300 Subject: [PATCH 05/13] Implemented ShadowMatrix class. Adjusted CMakeLists.txt. Setup shadowParams_ parameters for sunlight. --- source/blender/io/usd/CMakeLists.txt | 1 + source/blender/io/usd/hydra/light.cc | 47 +++++++++++++++--- source/blender/io/usd/hydra/shadow_matrix.h | 53 +++++++++++++++++++++ 3 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 source/blender/io/usd/hydra/shadow_matrix.h diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt index 65fb3c624c9d..9a1852df1c6e 100644 --- a/source/blender/io/usd/CMakeLists.txt +++ b/source/blender/io/usd/CMakeLists.txt @@ -160,6 +160,7 @@ if(WITH_HYDRA) hydra/camera.h hydra/curves.h hydra/hydra_scene_delegate.h + hydra/shadow_matrix.h hydra/id.h hydra/image.h hydra/instancer.h diff --git a/source/blender/io/usd/hydra/light.cc b/source/blender/io/usd/hydra/light.cc index 6b1e228181a4..52aa2ffac17e 100644 --- a/source/blender/io/usd/hydra/light.cc +++ b/source/blender/io/usd/hydra/light.cc @@ -2,12 +2,15 @@ * SPDX-FileCopyrightText: 2011-2022 Blender Foundation */ #include "light.h" +#include "shadow_matrix.h" #include #include +#include #include #include "DNA_light_types.h" +#include "DNA_scene_types.h" #include "BLI_math_rotation.h" @@ -92,6 +95,36 @@ void LightData::init() prim_type_ = prim_type(light); + /* Shadow section, only Sunlight is supported. + we verified if any of light's shadow is turned on, if yes shadow task will be added*/ + bool use_shadow = (light->mode & LA_SHADOW) && light->type == LA_SUN; + scene_delegate_->shading_settings.use_storm_shadows |= use_shadow; + if (use_shadow) { + data_[pxr::HdLightTokens->hasShadow] = use_shadow; + pxr::HdxShadowParams shadowParams_ = pxr::HdxShadowParams(); + + /* ShadowMatrix class is used to calculates shadow matrix from light frustum.*/ + ShadowMatrix *shadowMatrix = new ShadowMatrix(); + shadowMatrix->SetNearFar(0.1, light->cascade_max_dist); + shadowMatrix->SetTransform(gf_matrix_from_transform(((Object *)id)->object_to_world)); + + /* SetWindow sets size of projected shadow texture texture in + the approximate value is calculated using sun_angle property + 180 degrees is window size 1000 by 1000 */ + shadowMatrix->SetWindow(static_cast(light->sun_angle * 0.5f / M_PI * 1000), + static_cast(light->sun_angle * 0.5f / M_PI * 1000)); + shadowMatrix->CalculateMatrix(); + shadowParams_.enabled = use_shadow; + shadowParams_.resolution = scene_delegate_->scene->eevee.shadow_cascade_size; + shadowParams_.shadowMatrix = pxr::HdxShadowMatrixComputationSharedPtr(shadowMatrix); + shadowParams_.bias = -1.0 * light->bias; + shadowParams_.blur = light->cascade_fade; + + data_[pxr::HdLightTokens->shadowParams] = shadowParams_; + data_[pxr::HdLightTokens->shadowCollection] = pxr::HdRprimCollection( + pxr::HdTokens->geometry, pxr::HdReprSelector(pxr::HdReprTokens->refined)); + } + write_transform(); } @@ -112,7 +145,7 @@ void LightData::update() Object *object = (Object *)id; Light *light = (Light *)object->data; pxr::HdDirtyBits bits = pxr::HdLight::Clean; - if (id->recalc & ID_RECALC_GEOMETRY || light->id.recalc & ID_RECALC_GEOMETRY) { + if (id->recalc & ID_RECALC_GEOMETRY || light->id.recalc & ID_RECALC_GEOMETRY || scene_delegate_->shading_settings.use_storm_shadows) { if (prim_type(light) != prim_type_) { remove(); init(); @@ -155,27 +188,27 @@ pxr::TfToken LightData::prim_type(Light *light) switch (light->area_shape) { case LA_AREA_SQUARE: case LA_AREA_RECT: - return pxr::TfToken(pxr::HdPrimTypeTokens->rectLight); + return pxr::HdPrimTypeTokens->rectLight; case LA_AREA_DISK: case LA_AREA_ELLIPSE: - return pxr::TfToken(pxr::HdPrimTypeTokens->diskLight); + return pxr::HdPrimTypeTokens->diskLight; default: - return pxr::TfToken(pxr::HdPrimTypeTokens->rectLight); + return pxr::HdPrimTypeTokens->rectLight; } break; case LA_LOCAL: case LA_SPOT: - return pxr::TfToken(pxr::HdPrimTypeTokens->sphereLight); + return pxr::HdPrimTypeTokens->sphereLight; case LA_SUN: - return pxr::TfToken(pxr::HdPrimTypeTokens->distantLight); + return pxr::HdPrimTypeTokens->distantLight; default: BLI_assert_unreachable(); - return pxr::TfToken(pxr::HdPrimTypeTokens->sphereLight); + return pxr::HdPrimTypeTokens->sphereLight; } } diff --git a/source/blender/io/usd/hydra/shadow_matrix.h b/source/blender/io/usd/hydra/shadow_matrix.h new file mode 100644 index 000000000000..98cd057fcec3 --- /dev/null +++ b/source/blender/io/usd/hydra/shadow_matrix.h @@ -0,0 +1,53 @@ +#pragma once + +#include +#include + + +namespace blender::io::hydra { + +class ShadowMatrix : public pxr::HdxShadowMatrixComputation { + public: + ShadowMatrix() + { + _frustum = pxr::GfFrustum(); + _frustum.SetProjectionType(pxr::GfFrustum::Orthographic); + } + + std::vector Compute(const pxr::GfVec4f &viewport, + pxr::CameraUtilConformWindowPolicy policy) + { + return {_shadowMatrix}; + } + + std::vector Compute(const pxr::CameraUtilFraming &framing, + pxr::CameraUtilConformWindowPolicy policy) + { + return {_shadowMatrix}; + } + + void SetNearFar(const float &near_dist, const float &far_dist) + { + _frustum.SetNearFar(pxr::GfRange1d(near_dist, far_dist)); + } + + void SetTransform(const pxr::GfMatrix4d &transform) + { + _frustum.Transform(transform); + } + + void SetWindow(const double &x, const double &y) + { + _frustum.SetWindow(pxr::GfRange2d(pxr::GfVec2d(-x, -y), pxr::GfVec2d(x, y))); + } + + void CalculateMatrix() + { + _shadowMatrix = _frustum.ComputeViewMatrix() * _frustum.ComputeProjectionMatrix(); + } + + pxr::GfMatrix4d _shadowMatrix; + pxr::GfFrustum _frustum; +}; + +} // namespace blender::io::hydra -- 2.30.2 From 854c8210c2b591c3cb7c74089bbd1104d11ccb20 Mon Sep 17 00:00:00 2001 From: Vasyl-Pidhirskyi Date: Fri, 28 Jul 2023 16:42:58 +0300 Subject: [PATCH 06/13] Added condition for adding shadow_task. --- source/blender/render/hydra/final_engine.cc | 5 ++++- source/blender/render/hydra/viewport_engine.cc | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/source/blender/render/hydra/final_engine.cc b/source/blender/render/hydra/final_engine.cc index 34d6030c4739..bc3854207db4 100644 --- a/source/blender/render/hydra/final_engine.cc +++ b/source/blender/render/hydra/final_engine.cc @@ -64,7 +64,10 @@ void FinalEngine::render(Depsgraph *depsgraph) tasks.push_back(light_tasks_delegate_->skydome_task()); } tasks.push_back(light_tasks_delegate_->simple_task()); - tasks.push_back(light_tasks_delegate_->shadow_task()); + if (hydra_scene_delegate_->shading_settings.use_storm_shadows) + { + tasks.push_back(light_tasks_delegate_->shadow_task()); + } } tasks.push_back(render_task_delegate_->task()); diff --git a/source/blender/render/hydra/viewport_engine.cc b/source/blender/render/hydra/viewport_engine.cc index 9bbf7ca75ff6..592a11cdf44f 100644 --- a/source/blender/render/hydra/viewport_engine.cc +++ b/source/blender/render/hydra/viewport_engine.cc @@ -247,7 +247,10 @@ void ViewportEngine::render(Depsgraph *depsgraph, bContext *context) tasks.push_back(light_tasks_delegate_->skydome_task()); } tasks.push_back(light_tasks_delegate_->simple_task()); - tasks.push_back(light_tasks_delegate_->shadow_task()); + if (hydra_scene_delegate_->shading_settings.use_storm_shadows) + { + tasks.push_back(light_tasks_delegate_->shadow_task()); + } } tasks.push_back(render_task_delegate_->task()); -- 2.30.2 From ddef9b989783ee9a8ca84d9706f14b9b011a7b50 Mon Sep 17 00:00:00 2001 From: Vasyl-Pidhirskyi Date: Fri, 28 Jul 2023 16:44:52 +0300 Subject: [PATCH 07/13] Format. --- source/blender/io/usd/hydra/light.cc | 4 +++- source/blender/io/usd/hydra/shadow_matrix.h | 1 - source/blender/render/hydra/final_engine.cc | 3 +-- source/blender/render/hydra/viewport_engine.cc | 3 +-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/source/blender/io/usd/hydra/light.cc b/source/blender/io/usd/hydra/light.cc index 52aa2ffac17e..4159744ad361 100644 --- a/source/blender/io/usd/hydra/light.cc +++ b/source/blender/io/usd/hydra/light.cc @@ -145,7 +145,9 @@ void LightData::update() Object *object = (Object *)id; Light *light = (Light *)object->data; pxr::HdDirtyBits bits = pxr::HdLight::Clean; - if (id->recalc & ID_RECALC_GEOMETRY || light->id.recalc & ID_RECALC_GEOMETRY || scene_delegate_->shading_settings.use_storm_shadows) { + if (id->recalc & ID_RECALC_GEOMETRY || light->id.recalc & ID_RECALC_GEOMETRY || + scene_delegate_->shading_settings.use_storm_shadows) + { if (prim_type(light) != prim_type_) { remove(); init(); diff --git a/source/blender/io/usd/hydra/shadow_matrix.h b/source/blender/io/usd/hydra/shadow_matrix.h index 98cd057fcec3..f75b2b4c3af3 100644 --- a/source/blender/io/usd/hydra/shadow_matrix.h +++ b/source/blender/io/usd/hydra/shadow_matrix.h @@ -3,7 +3,6 @@ #include #include - namespace blender::io::hydra { class ShadowMatrix : public pxr::HdxShadowMatrixComputation { diff --git a/source/blender/render/hydra/final_engine.cc b/source/blender/render/hydra/final_engine.cc index bc3854207db4..83f0904701e8 100644 --- a/source/blender/render/hydra/final_engine.cc +++ b/source/blender/render/hydra/final_engine.cc @@ -64,8 +64,7 @@ void FinalEngine::render(Depsgraph *depsgraph) tasks.push_back(light_tasks_delegate_->skydome_task()); } tasks.push_back(light_tasks_delegate_->simple_task()); - if (hydra_scene_delegate_->shading_settings.use_storm_shadows) - { + if (hydra_scene_delegate_->shading_settings.use_storm_shadows) { tasks.push_back(light_tasks_delegate_->shadow_task()); } } diff --git a/source/blender/render/hydra/viewport_engine.cc b/source/blender/render/hydra/viewport_engine.cc index 592a11cdf44f..17cd4468ce54 100644 --- a/source/blender/render/hydra/viewport_engine.cc +++ b/source/blender/render/hydra/viewport_engine.cc @@ -247,8 +247,7 @@ void ViewportEngine::render(Depsgraph *depsgraph, bContext *context) tasks.push_back(light_tasks_delegate_->skydome_task()); } tasks.push_back(light_tasks_delegate_->simple_task()); - if (hydra_scene_delegate_->shading_settings.use_storm_shadows) - { + if (hydra_scene_delegate_->shading_settings.use_storm_shadows) { tasks.push_back(light_tasks_delegate_->shadow_task()); } } -- 2.30.2 From 479b8be3ef87c3e0910b68748bd2ecaeda391406 Mon Sep 17 00:00:00 2001 From: Vasyl-Pidhirskyi Date: Tue, 1 Aug 2023 15:35:22 +0300 Subject: [PATCH 08/13] Improved naming. --- source/blender/io/usd/hydra/light.cc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/source/blender/io/usd/hydra/light.cc b/source/blender/io/usd/hydra/light.cc index 4159744ad361..0d20c857a656 100644 --- a/source/blender/io/usd/hydra/light.cc +++ b/source/blender/io/usd/hydra/light.cc @@ -101,26 +101,26 @@ void LightData::init() scene_delegate_->shading_settings.use_storm_shadows |= use_shadow; if (use_shadow) { data_[pxr::HdLightTokens->hasShadow] = use_shadow; - pxr::HdxShadowParams shadowParams_ = pxr::HdxShadowParams(); + pxr::HdxShadowParams shadow_params = pxr::HdxShadowParams(); /* ShadowMatrix class is used to calculates shadow matrix from light frustum.*/ - ShadowMatrix *shadowMatrix = new ShadowMatrix(); - shadowMatrix->SetNearFar(0.1, light->cascade_max_dist); - shadowMatrix->SetTransform(gf_matrix_from_transform(((Object *)id)->object_to_world)); + ShadowMatrix *shadow_matrix = new ShadowMatrix(); + shadow_matrix->SetNearFar(0.1, light->cascade_max_dist); + shadow_matrix->SetTransform(gf_matrix_from_transform(((Object *)id)->object_to_world)); /* SetWindow sets size of projected shadow texture texture in the approximate value is calculated using sun_angle property 180 degrees is window size 1000 by 1000 */ - shadowMatrix->SetWindow(static_cast(light->sun_angle * 0.5f / M_PI * 1000), + shadow_matrix->SetWindow(static_cast(light->sun_angle * 0.5f / M_PI * 1000), static_cast(light->sun_angle * 0.5f / M_PI * 1000)); - shadowMatrix->CalculateMatrix(); - shadowParams_.enabled = use_shadow; - shadowParams_.resolution = scene_delegate_->scene->eevee.shadow_cascade_size; - shadowParams_.shadowMatrix = pxr::HdxShadowMatrixComputationSharedPtr(shadowMatrix); - shadowParams_.bias = -1.0 * light->bias; - shadowParams_.blur = light->cascade_fade; + shadow_matrix->CalculateMatrix(); + shadow_params.enabled = use_shadow; + shadow_params.resolution = scene_delegate_->scene->eevee.shadow_cascade_size; + shadow_params.shadowMatrix = pxr::HdxShadowMatrixComputationSharedPtr(shadow_matrix); + shadow_params.bias = -1.0 * light->bias; + shadow_params.blur = light->cascade_fade; - data_[pxr::HdLightTokens->shadowParams] = shadowParams_; + data_[pxr::HdLightTokens->shadowParams] = shadow_params; data_[pxr::HdLightTokens->shadowCollection] = pxr::HdRprimCollection( pxr::HdTokens->geometry, pxr::HdReprSelector(pxr::HdReprTokens->refined)); } -- 2.30.2 From e61f89ba11a2534774054f8ffac23e71eda24421 Mon Sep 17 00:00:00 2001 From: Vasyl-Pidhirskyi Date: Tue, 1 Aug 2023 16:38:06 +0300 Subject: [PATCH 09/13] Moved shadow setup to method write_shadow_params(). --- source/blender/io/usd/hydra/light.cc | 16 ++++++++++------ source/blender/io/usd/hydra/light.h | 1 + 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/source/blender/io/usd/hydra/light.cc b/source/blender/io/usd/hydra/light.cc index 0d20c857a656..45146a90c89e 100644 --- a/source/blender/io/usd/hydra/light.cc +++ b/source/blender/io/usd/hydra/light.cc @@ -95,8 +95,15 @@ void LightData::init() prim_type_ = prim_type(light); + write_shadow_params(); + write_transform(); +} + +void LightData::write_shadow_params() +{ /* Shadow section, only Sunlight is supported. we verified if any of light's shadow is turned on, if yes shadow task will be added*/ + Light *light = (Light *)((Object *)id)->data; bool use_shadow = (light->mode & LA_SHADOW) && light->type == LA_SUN; scene_delegate_->shading_settings.use_storm_shadows |= use_shadow; if (use_shadow) { @@ -112,7 +119,7 @@ void LightData::init() the approximate value is calculated using sun_angle property 180 degrees is window size 1000 by 1000 */ shadow_matrix->SetWindow(static_cast(light->sun_angle * 0.5f / M_PI * 1000), - static_cast(light->sun_angle * 0.5f / M_PI * 1000)); + static_cast(light->sun_angle * 0.5f / M_PI * 1000)); shadow_matrix->CalculateMatrix(); shadow_params.enabled = use_shadow; shadow_params.resolution = scene_delegate_->scene->eevee.shadow_cascade_size; @@ -124,8 +131,6 @@ void LightData::init() data_[pxr::HdLightTokens->shadowCollection] = pxr::HdRprimCollection( pxr::HdTokens->geometry, pxr::HdReprSelector(pxr::HdReprTokens->refined)); } - - write_transform(); } void LightData::insert() @@ -145,9 +150,7 @@ void LightData::update() Object *object = (Object *)id; Light *light = (Light *)object->data; pxr::HdDirtyBits bits = pxr::HdLight::Clean; - if (id->recalc & ID_RECALC_GEOMETRY || light->id.recalc & ID_RECALC_GEOMETRY || - scene_delegate_->shading_settings.use_storm_shadows) - { + if (id->recalc & ID_RECALC_GEOMETRY || light->id.recalc & ID_RECALC_GEOMETRY) { if (prim_type(light) != prim_type_) { remove(); init(); @@ -158,6 +161,7 @@ void LightData::update() bits = pxr::HdLight::AllDirty; } else if (id->recalc & ID_RECALC_TRANSFORM) { + write_shadow_params(); write_transform(); bits = pxr::HdLight::DirtyTransform; } diff --git a/source/blender/io/usd/hydra/light.h b/source/blender/io/usd/hydra/light.h index a5fe919777a5..d8cae3bfba0a 100644 --- a/source/blender/io/usd/hydra/light.h +++ b/source/blender/io/usd/hydra/light.h @@ -30,6 +30,7 @@ class LightData : public ObjectData { void remove() override; void update() override; + void write_shadow_params(); pxr::VtValue get_data(pxr::TfToken const &key) const override; protected: -- 2.30.2 From 088eb5a0f890f17d15166734674c597e3626c932 Mon Sep 17 00:00:00 2001 From: Vasyl-Pidhirskyi Date: Tue, 1 Aug 2023 18:17:50 +0300 Subject: [PATCH 10/13] Moved ShadowMatrix to light.cc. Improved naming. Improved shadow updates. --- source/blender/io/usd/CMakeLists.txt | 1 - source/blender/io/usd/hydra/light.cc | 66 ++++++++++++++++++--- source/blender/io/usd/hydra/shadow_matrix.h | 52 ---------------- 3 files changed, 57 insertions(+), 62 deletions(-) delete mode 100644 source/blender/io/usd/hydra/shadow_matrix.h diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt index 9a1852df1c6e..65fb3c624c9d 100644 --- a/source/blender/io/usd/CMakeLists.txt +++ b/source/blender/io/usd/CMakeLists.txt @@ -160,7 +160,6 @@ if(WITH_HYDRA) hydra/camera.h hydra/curves.h hydra/hydra_scene_delegate.h - hydra/shadow_matrix.h hydra/id.h hydra/image.h hydra/instancer.h diff --git a/source/blender/io/usd/hydra/light.cc b/source/blender/io/usd/hydra/light.cc index 45146a90c89e..f4b1abf4da0f 100644 --- a/source/blender/io/usd/hydra/light.cc +++ b/source/blender/io/usd/hydra/light.cc @@ -2,10 +2,11 @@ * SPDX-FileCopyrightText: 2011-2022 Blender Foundation */ #include "light.h" -#include "shadow_matrix.h" +#include #include #include +#include #include #include @@ -18,6 +19,48 @@ namespace blender::io::hydra { +class ShadowMatrix : public pxr::HdxShadowMatrixComputation { + public: + ShadowMatrix() + { + _frustum = pxr::GfFrustum(); + } + + std::vector Compute(const pxr::GfVec4f &viewport, + pxr::CameraUtilConformWindowPolicy policy) override + { + return {_frustum.ComputeViewMatrix() * _frustum.ComputeProjectionMatrix()}; + } + + std::vector Compute(const pxr::CameraUtilFraming &framing, + pxr::CameraUtilConformWindowPolicy policy) override + { + return {_frustum.ComputeViewMatrix() * _frustum.ComputeProjectionMatrix()}; + } + + void set_projection_type(const pxr::GfFrustum::ProjectionType projection_type) + { + _frustum.SetProjectionType(projection_type); + } + + void set_near_far(const float near_dist, const float far_dist) + { + _frustum.SetNearFar(pxr::GfRange1d(near_dist, far_dist)); + } + + void set_transform(const pxr::GfMatrix4d &transform) + { + _frustum.Transform(transform); + } + + void set_window(const float x, const float y) + { + _frustum.SetWindow(pxr::GfRange2d(pxr::GfVec2d(-x, -y), pxr::GfVec2d(x, y))); + } + + pxr::GfFrustum _frustum; +}; + LightData::LightData(HydraSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id) @@ -112,15 +155,15 @@ void LightData::write_shadow_params() /* ShadowMatrix class is used to calculates shadow matrix from light frustum.*/ ShadowMatrix *shadow_matrix = new ShadowMatrix(); - shadow_matrix->SetNearFar(0.1, light->cascade_max_dist); - shadow_matrix->SetTransform(gf_matrix_from_transform(((Object *)id)->object_to_world)); + shadow_matrix->set_near_far(0.1, light->cascade_max_dist); + shadow_matrix->set_transform(gf_matrix_from_transform(((Object *)id)->object_to_world)); /* SetWindow sets size of projected shadow texture texture in the approximate value is calculated using sun_angle property 180 degrees is window size 1000 by 1000 */ - shadow_matrix->SetWindow(static_cast(light->sun_angle * 0.5f / M_PI * 1000), - static_cast(light->sun_angle * 0.5f / M_PI * 1000)); - shadow_matrix->CalculateMatrix(); + shadow_matrix->set_window(light->sun_angle * 0.5f / M_PI * 1000, + light->sun_angle * 0.5f / M_PI * 1000); + shadow_matrix->set_projection_type(pxr::GfFrustum::Orthographic); shadow_params.enabled = use_shadow; shadow_params.resolution = scene_delegate_->scene->eevee.shadow_cascade_size; shadow_params.shadowMatrix = pxr::HdxShadowMatrixComputationSharedPtr(shadow_matrix); @@ -161,9 +204,14 @@ void LightData::update() bits = pxr::HdLight::AllDirty; } else if (id->recalc & ID_RECALC_TRANSFORM) { - write_shadow_params(); - write_transform(); - bits = pxr::HdLight::DirtyTransform; + if (light->mode & LA_SHADOW) { + init(); + bits = pxr::HdLight::AllDirty; + } + else { + write_transform(); + bits = pxr::HdLight::DirtyTransform; + } } if (bits != pxr::HdChangeTracker::Clean) { scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id, bits); diff --git a/source/blender/io/usd/hydra/shadow_matrix.h b/source/blender/io/usd/hydra/shadow_matrix.h deleted file mode 100644 index f75b2b4c3af3..000000000000 --- a/source/blender/io/usd/hydra/shadow_matrix.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include -#include - -namespace blender::io::hydra { - -class ShadowMatrix : public pxr::HdxShadowMatrixComputation { - public: - ShadowMatrix() - { - _frustum = pxr::GfFrustum(); - _frustum.SetProjectionType(pxr::GfFrustum::Orthographic); - } - - std::vector Compute(const pxr::GfVec4f &viewport, - pxr::CameraUtilConformWindowPolicy policy) - { - return {_shadowMatrix}; - } - - std::vector Compute(const pxr::CameraUtilFraming &framing, - pxr::CameraUtilConformWindowPolicy policy) - { - return {_shadowMatrix}; - } - - void SetNearFar(const float &near_dist, const float &far_dist) - { - _frustum.SetNearFar(pxr::GfRange1d(near_dist, far_dist)); - } - - void SetTransform(const pxr::GfMatrix4d &transform) - { - _frustum.Transform(transform); - } - - void SetWindow(const double &x, const double &y) - { - _frustum.SetWindow(pxr::GfRange2d(pxr::GfVec2d(-x, -y), pxr::GfVec2d(x, y))); - } - - void CalculateMatrix() - { - _shadowMatrix = _frustum.ComputeViewMatrix() * _frustum.ComputeProjectionMatrix(); - } - - pxr::GfMatrix4d _shadowMatrix; - pxr::GfFrustum _frustum; -}; - -} // namespace blender::io::hydra -- 2.30.2 From f6c9fc6e724d798c0985429b6f2ad0cc29411d40 Mon Sep 17 00:00:00 2001 From: Vasyl-Pidhirskyi Date: Tue, 1 Aug 2023 21:42:55 +0300 Subject: [PATCH 11/13] Implemented HydraSceneDelegate::has_shadows. Code improvements. --- .../io/usd/hydra/hydra_scene_delegate.cc | 34 +++++++++++++ .../io/usd/hydra/hydra_scene_delegate.h | 2 +- source/blender/io/usd/hydra/light.cc | 50 +++++++++---------- source/blender/render/hydra/final_engine.cc | 5 +- .../blender/render/hydra/viewport_engine.cc | 6 ++- 5 files changed, 67 insertions(+), 30 deletions(-) diff --git a/source/blender/io/usd/hydra/hydra_scene_delegate.cc b/source/blender/io/usd/hydra/hydra_scene_delegate.cc index 7dc15ccf700f..93bd4e30c590 100644 --- a/source/blender/io/usd/hydra/hydra_scene_delegate.cc +++ b/source/blender/io/usd/hydra/hydra_scene_delegate.cc @@ -5,6 +5,7 @@ #include +#include "DNA_light_types.h" #include "DNA_scene_types.h" #include "BLI_set.hh" @@ -238,6 +239,39 @@ void HydraSceneDelegate::clear() view3d = nullptr; } +bool HydraSceneDelegate::has_shadows() +{ + + bool has_shadows = false; + + DEGObjectIterSettings settings = {0}; + settings.depsgraph = depsgraph; + settings.flags = DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS; + DEGObjectIterData data = {0}; + data.settings = &settings; + data.graph = settings.depsgraph; + data.flag = settings.flags; + + ITER_BEGIN (DEG_iterator_objects_begin, + DEG_iterator_objects_next, + DEG_iterator_objects_end, + &data, + Object *, + object) + { + if (object->type == OB_LAMP) { + Light *light = (Light *)object->data; + has_shadows |= light->mode & LA_SHADOW; + if (has_shadows) { + break; + } + } + } + ITER_END; + + return has_shadows; +} + pxr::SdfPath HydraSceneDelegate::prim_id(ID *id, const char *prefix) const { /* Making id of object in form like _ */ diff --git a/source/blender/io/usd/hydra/hydra_scene_delegate.h b/source/blender/io/usd/hydra/hydra_scene_delegate.h index 9299e2657b0a..2b97ee230aaf 100644 --- a/source/blender/io/usd/hydra/hydra_scene_delegate.h +++ b/source/blender/io/usd/hydra/hydra_scene_delegate.h @@ -44,7 +44,6 @@ class HydraSceneDelegate : public pxr::HdSceneDelegate { std::string studiolight_name; float studiolight_rotation; float studiolight_intensity; - bool use_storm_shadows = false; bool operator==(const ShadingSettings &other); }; @@ -91,6 +90,7 @@ class HydraSceneDelegate : public pxr::HdSceneDelegate { void populate(Depsgraph *depsgraph, View3D *v3d); void clear(); + bool has_shadows(); private: pxr::SdfPath prim_id(ID *id, const char *prefix) const; diff --git a/source/blender/io/usd/hydra/light.cc b/source/blender/io/usd/hydra/light.cc index f4b1abf4da0f..c691cacd9519 100644 --- a/source/blender/io/usd/hydra/light.cc +++ b/source/blender/io/usd/hydra/light.cc @@ -148,32 +148,32 @@ void LightData::write_shadow_params() we verified if any of light's shadow is turned on, if yes shadow task will be added*/ Light *light = (Light *)((Object *)id)->data; bool use_shadow = (light->mode & LA_SHADOW) && light->type == LA_SUN; - scene_delegate_->shading_settings.use_storm_shadows |= use_shadow; - if (use_shadow) { - data_[pxr::HdLightTokens->hasShadow] = use_shadow; - pxr::HdxShadowParams shadow_params = pxr::HdxShadowParams(); - - /* ShadowMatrix class is used to calculates shadow matrix from light frustum.*/ - ShadowMatrix *shadow_matrix = new ShadowMatrix(); - shadow_matrix->set_near_far(0.1, light->cascade_max_dist); - shadow_matrix->set_transform(gf_matrix_from_transform(((Object *)id)->object_to_world)); - - /* SetWindow sets size of projected shadow texture texture in - the approximate value is calculated using sun_angle property - 180 degrees is window size 1000 by 1000 */ - shadow_matrix->set_window(light->sun_angle * 0.5f / M_PI * 1000, - light->sun_angle * 0.5f / M_PI * 1000); - shadow_matrix->set_projection_type(pxr::GfFrustum::Orthographic); - shadow_params.enabled = use_shadow; - shadow_params.resolution = scene_delegate_->scene->eevee.shadow_cascade_size; - shadow_params.shadowMatrix = pxr::HdxShadowMatrixComputationSharedPtr(shadow_matrix); - shadow_params.bias = -1.0 * light->bias; - shadow_params.blur = light->cascade_fade; - - data_[pxr::HdLightTokens->shadowParams] = shadow_params; - data_[pxr::HdLightTokens->shadowCollection] = pxr::HdRprimCollection( - pxr::HdTokens->geometry, pxr::HdReprSelector(pxr::HdReprTokens->refined)); + data_[pxr::HdLightTokens->hasShadow] = use_shadow; + if (!use_shadow) { + return; } + pxr::HdxShadowParams shadow_params = pxr::HdxShadowParams(); + + /* ShadowMatrix class is used to calculates shadow matrix from light frustum.*/ + ShadowMatrix *shadow_matrix = new ShadowMatrix(); + shadow_matrix->set_near_far(0.1, light->cascade_max_dist); + shadow_matrix->set_transform(gf_matrix_from_transform(((Object *)id)->object_to_world)); + + /* SetWindow sets size of projected shadow texture texture in + the approximate value is calculated using sun_angle property + 180 degrees is window size 1000 by 1000 */ + shadow_matrix->set_window(light->sun_angle * 0.5f / M_PI * 1000, + light->sun_angle * 0.5f / M_PI * 1000); + shadow_matrix->set_projection_type(pxr::GfFrustum::Orthographic); + shadow_params.enabled = use_shadow; + shadow_params.resolution = scene_delegate_->scene->eevee.shadow_cascade_size; + shadow_params.shadowMatrix = pxr::HdxShadowMatrixComputationSharedPtr(shadow_matrix); + shadow_params.bias = -1.0 * light->bias; + shadow_params.blur = light->cascade_fade; + + data_[pxr::HdLightTokens->shadowParams] = shadow_params; + data_[pxr::HdLightTokens->shadowCollection] = pxr::HdRprimCollection( + pxr::HdTokens->geometry, pxr::HdReprSelector(pxr::HdReprTokens->refined)); } void LightData::insert() diff --git a/source/blender/render/hydra/final_engine.cc b/source/blender/render/hydra/final_engine.cc index 00926e5c5336..05722425093e 100644 --- a/source/blender/render/hydra/final_engine.cc +++ b/source/blender/render/hydra/final_engine.cc @@ -27,6 +27,7 @@ void FinalEngine::render(Depsgraph *depsgraph) { const Scene *scene = DEG_get_evaluated_scene(depsgraph); const ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); + bool has_shadows = hydra_scene_delegate_->has_shadows(); char scene_name[MAX_ID_FULL_NAME]; BKE_id_full_name_get(scene_name, &scene->id, 0); @@ -50,7 +51,7 @@ void FinalEngine::render(Depsgraph *depsgraph) render_task_delegate_->set_viewport(pxr::GfVec4d(0, 0, resolution_[0], resolution_[1])); if (light_tasks_delegate_) { light_tasks_delegate_->set_viewport(pxr::GfVec4d(0, 0, resolution_[0], resolution_[1])); - light_tasks_delegate_->set_shadows(hydra_scene_delegate_->shading_settings.use_storm_shadows); + light_tasks_delegate_->set_shadows(has_shadows); } render_task_delegate_->add_aov(pxr::HdAovTokens->color); @@ -73,7 +74,7 @@ void FinalEngine::render(Depsgraph *depsgraph) tasks.push_back(light_tasks_delegate_->skydome_task()); } tasks.push_back(light_tasks_delegate_->simple_task()); - if (hydra_scene_delegate_->shading_settings.use_storm_shadows) { + if (has_shadows) { tasks.push_back(light_tasks_delegate_->shadow_task()); } } diff --git a/source/blender/render/hydra/viewport_engine.cc b/source/blender/render/hydra/viewport_engine.cc index 37136c08bc06..cd4a593a16af 100644 --- a/source/blender/render/hydra/viewport_engine.cc +++ b/source/blender/render/hydra/viewport_engine.cc @@ -219,6 +219,8 @@ void ViewportEngine::render(Depsgraph *depsgraph, bContext *context) { ViewSettings view_settings(context); const Scene *scene = DEG_get_evaluated_scene(depsgraph); + bool has_shadows = hydra_scene_delegate_->has_shadows(); + if (view_settings.width() * view_settings.height() == 0) { return; }; @@ -233,7 +235,7 @@ void ViewportEngine::render(Depsgraph *depsgraph, bContext *context) render_task_delegate_->set_viewport(viewport); if (light_tasks_delegate_) { light_tasks_delegate_->set_viewport(viewport); - light_tasks_delegate_->set_shadows(hydra_scene_delegate_->shading_settings.use_storm_shadows); + light_tasks_delegate_->set_shadows(has_shadows); } render_task_delegate_->add_aov(pxr::HdAovTokens->color); @@ -245,7 +247,7 @@ void ViewportEngine::render(Depsgraph *depsgraph, bContext *context) tasks.push_back(light_tasks_delegate_->skydome_task()); } tasks.push_back(light_tasks_delegate_->simple_task()); - if (hydra_scene_delegate_->shading_settings.use_storm_shadows) { + if (has_shadows) { tasks.push_back(light_tasks_delegate_->shadow_task()); } } -- 2.30.2 From 9a0a3a6b49d8b1cfd271f0de4d833da34231aa36 Mon Sep 17 00:00:00 2001 From: Vasyl-Pidhirskyi Date: Wed, 2 Aug 2023 10:46:55 +0300 Subject: [PATCH 12/13] Fixed merge. --- source/blender/render/hydra/render_task_delegate.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/render/hydra/render_task_delegate.cc b/source/blender/render/hydra/render_task_delegate.cc index 5dd5d901a309..6772920e1d3b 100644 --- a/source/blender/render/hydra/render_task_delegate.cc +++ b/source/blender/render/hydra/render_task_delegate.cc @@ -273,7 +273,9 @@ void GPURenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, GPUTexture *te void GPURenderTaskDelegate::bind() { - framebuffer_ = GPU_framebuffer_create("fb_render_hydra"); + if (!framebuffer_) { + framebuffer_ = GPU_framebuffer_create("fb_render_hydra"); + } GPU_framebuffer_ensure_config( &framebuffer_, {GPU_ATTACHMENT_TEXTURE(tex_depth_), GPU_ATTACHMENT_TEXTURE(tex_color_)}); GPU_framebuffer_bind(framebuffer_); -- 2.30.2 From 4b99d62d33c92b5ac71a245292f4eeed26410a38 Mon Sep 17 00:00:00 2001 From: Vasyl-Pidhirskyi Date: Wed, 2 Aug 2023 12:10:34 +0300 Subject: [PATCH 13/13] Code improvements. --- source/blender/render/hydra/engine.cc | 3 +-- source/blender/render/hydra/final_engine.cc | 3 +-- source/blender/render/hydra/viewport_engine.cc | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/source/blender/render/hydra/engine.cc b/source/blender/render/hydra/engine.cc index 135536261c85..e5849e5ea072 100644 --- a/source/blender/render/hydra/engine.cc +++ b/source/blender/render/hydra/engine.cc @@ -135,7 +135,6 @@ float Engine::renderer_percent_done() pxr::HdTaskSharedPtrVector Engine::tasks() { - bool has_shadows = hydra_scene_delegate_->has_shadows(); pxr::HdTaskSharedPtrVector res; if (light_tasks_delegate_) { if (scene_->r.alphamode != R_ALPHAPREMUL) { @@ -147,7 +146,7 @@ pxr::HdTaskSharedPtrVector Engine::tasks() #endif } res.push_back(light_tasks_delegate_->simple_task()); - if (has_shadows) { + if (hydra_scene_delegate_->has_shadows()) { res.push_back(light_tasks_delegate_->shadow_task()); } } diff --git a/source/blender/render/hydra/final_engine.cc b/source/blender/render/hydra/final_engine.cc index 904534d7d17e..a084ae966e29 100644 --- a/source/blender/render/hydra/final_engine.cc +++ b/source/blender/render/hydra/final_engine.cc @@ -26,7 +26,6 @@ namespace blender::render::hydra { void FinalEngine::render() { const ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph_); - bool has_shadows = hydra_scene_delegate_->has_shadows(); char scene_name[MAX_ID_FULL_NAME]; BKE_id_full_name_get(scene_name, &scene_->id, 0); @@ -49,7 +48,7 @@ void FinalEngine::render() render_task_delegate_->set_viewport(pxr::GfVec4d(0, 0, width, height)); if (light_tasks_delegate_) { light_tasks_delegate_->set_viewport(pxr::GfVec4d(0, 0, width, height)); - light_tasks_delegate_->set_shadows(has_shadows); + light_tasks_delegate_->set_shadows(hydra_scene_delegate_->has_shadows()); } RenderResult *rr = RE_engine_get_result(bl_engine_); diff --git a/source/blender/render/hydra/viewport_engine.cc b/source/blender/render/hydra/viewport_engine.cc index 4ba1cb36e5ed..b4383e08d5a2 100644 --- a/source/blender/render/hydra/viewport_engine.cc +++ b/source/blender/render/hydra/viewport_engine.cc @@ -213,7 +213,6 @@ GPUTexture *DrawTexture::texture() const void ViewportEngine::render() { ViewSettings view_settings(context_); - bool has_shadows = hydra_scene_delegate_->has_shadows(); if (view_settings.width() * view_settings.height() == 0) { return; }; @@ -228,7 +227,7 @@ void ViewportEngine::render() render_task_delegate_->set_viewport(viewport); if (light_tasks_delegate_) { light_tasks_delegate_->set_viewport(viewport); - light_tasks_delegate_->set_shadows(has_shadows); + light_tasks_delegate_->set_shadows(hydra_scene_delegate_->has_shadows()); } render_task_delegate_->add_aov(pxr::HdAovTokens->color); -- 2.30.2