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.
3 changed files with 94 additions and 7 deletions
Showing only changes of commit 92ede52828 - Show all commits

View File

@ -160,6 +160,7 @@ if(WITH_HYDRA)
hydra/camera.h hydra/camera.h
hydra/curves.h hydra/curves.h
hydra/hydra_scene_delegate.h hydra/hydra_scene_delegate.h
hydra/shadow_matrix.h
hydra/id.h hydra/id.h
hydra/image.h hydra/image.h
hydra/instancer.h hydra/instancer.h

View File

@ -2,12 +2,15 @@
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */ * SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
#include "light.h" #include "light.h"
#include "shadow_matrix.h"
#include <pxr/imaging/hd/light.h> #include <pxr/imaging/hd/light.h>
#include <pxr/imaging/hd/tokens.h> #include <pxr/imaging/hd/tokens.h>
#include <pxr/imaging/hdx/simpleLightTask.h>
#include <pxr/usd/usdLux/tokens.h> #include <pxr/usd/usdLux/tokens.h>
#include "DNA_light_types.h" #include "DNA_light_types.h"
#include "DNA_scene_types.h"
#include "BLI_math_rotation.h" #include "BLI_math_rotation.h"
@ -92,6 +95,36 @@ void LightData::init()
prim_type_ = prim_type(light); 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<int>(light->sun_angle * 0.5f / M_PI * 1000),
static_cast<int>(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(); write_transform();
} }
@ -112,7 +145,7 @@ void LightData::update()
Object *object = (Object *)id; Object *object = (Object *)id;
Light *light = (Light *)object->data; Light *light = (Light *)object->data;
pxr::HdDirtyBits bits = pxr::HdLight::Clean; 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_) { if (prim_type(light) != prim_type_) {
remove(); remove();
init(); init();
@ -155,27 +188,27 @@ pxr::TfToken LightData::prim_type(Light *light)
switch (light->area_shape) { switch (light->area_shape) {
case LA_AREA_SQUARE: case LA_AREA_SQUARE:
case LA_AREA_RECT: case LA_AREA_RECT:
return pxr::TfToken(pxr::HdPrimTypeTokens->rectLight); return pxr::HdPrimTypeTokens->rectLight;
case LA_AREA_DISK: case LA_AREA_DISK:
case LA_AREA_ELLIPSE: case LA_AREA_ELLIPSE:
return pxr::TfToken(pxr::HdPrimTypeTokens->diskLight); return pxr::HdPrimTypeTokens->diskLight;
default: default:
return pxr::TfToken(pxr::HdPrimTypeTokens->rectLight); return pxr::HdPrimTypeTokens->rectLight;
} }
break; break;
case LA_LOCAL: case LA_LOCAL:
case LA_SPOT: case LA_SPOT:
return pxr::TfToken(pxr::HdPrimTypeTokens->sphereLight); return pxr::HdPrimTypeTokens->sphereLight;
case LA_SUN: case LA_SUN:
return pxr::TfToken(pxr::HdPrimTypeTokens->distantLight); return pxr::HdPrimTypeTokens->distantLight;
default: default:
BLI_assert_unreachable(); BLI_assert_unreachable();
return pxr::TfToken(pxr::HdPrimTypeTokens->sphereLight); return pxr::HdPrimTypeTokens->sphereLight;
} }
} }

View File

@ -0,0 +1,53 @@
#pragma once
#include <pxr/base/gf/frustum.h>
#include <pxr/imaging/hdx/shadowMatrixComputation.h>
namespace blender::io::hydra {
class ShadowMatrix : public pxr::HdxShadowMatrixComputation {
public:
ShadowMatrix()
{
_frustum = pxr::GfFrustum();
_frustum.SetProjectionType(pxr::GfFrustum::Orthographic);
}
std::vector<pxr::GfMatrix4d> Compute(const pxr::GfVec4f &viewport,
pxr::CameraUtilConformWindowPolicy policy)
{
return {_shadowMatrix};
}
std::vector<pxr::GfMatrix4d> 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