29void ShadowPass::ShadowView::setup(
View &
view,
float3 light_direction,
bool force_fail_method)
31 force_fail_method_ = force_fail_method;
32 light_direction_ = light_direction;
62 const int3 corner_faces[8] = {
63 {x_neg, y_neg, z_pos},
64 {x_neg, y_neg, z_neg},
65 {x_neg, y_pos, z_neg},
66 {x_neg, y_pos, z_pos},
67 {x_pos, y_neg, z_pos},
68 {x_pos, y_neg, z_neg},
69 {x_pos, y_pos, z_neg},
70 {x_pos, y_pos, z_pos},
73 const int2 edge_faces[12] = {
88 const int2 edge_corners[12] = {
106 Vector<float4> faces_result;
107 Vector<float3> corners_result;
112 for (
int i : IndexRange(6)) {
114 frustum_planes[
i] *=
float4(-1, -1, -1, 1);
118 faces_result.
append(frustum_planes[
i]);
124 for (
int i : IndexRange(12)) {
125 int2 f = edge_faces[
i];
126 bool a_lit = face_lit[f[0]];
127 bool b_lit = face_lit[f[1]];
128 if (a_lit != b_lit) {
130 float3 corner_a = frustum_corners[edge_corners[
i][0]];
131 float3 corner_b = frustum_corners[edge_corners[
i][1]];
138 bool flipped =
false;
139 for (
float3 corner : frustum_corners) {
148 faces_result.
append(extruded_face);
152 for (
int i_corner : IndexRange(8)) {
154 for (
int i_face : IndexRange(3)) {
155 lit_faces += face_lit[corner_faces[i_corner][i_face]] ? 1 : 0;
159 corners_result.
append(frustum_corners[i_corner]);
163 corners_result.
append(
float3(frustum_corners[i_corner]) - (light_direction_ * 1e4f));
169 extruded_frustum_.corners[
i] =
float4(corners_result[
i], 1);
171 extruded_frustum_.corners_count = corners_result.
size();
174 extruded_frustum_.planes[
i] = faces_result[
i];
176 extruded_frustum_.planes_count = faces_result.
size();
178 extruded_frustum_.push_update();
181bool ShadowPass::ShadowView::debug_object_culling(
Object *ob)
186 for (
int p : IndexRange(extruded_frustum_.planes_count)) {
187 float4 plane = extruded_frustum_.planes[p];
188 bool separating_axis =
true;
189 for (
float3 corner : corners) {
192 if (signed_distance <= 0) {
193 separating_axis =
false;
197 if (separating_axis) {
198 printf(
"Separating Axis >>> x: %f, y: %f, z: %f, w: %f \n",
UNPACK4(plane));
205void ShadowPass::ShadowView::set_mode(ShadowPass::PassType type)
207 current_pass_type_ = type;
209 manager_fingerprint_ = 0;
212void ShadowPass::ShadowView::compute_visibility(
ObjectBoundsBuf &bounds,
221 uint word_per_draw = this->visibility_word_per_draw();
224 resource_len * word_per_draw;
228 if (current_pass_type_ == ShadowPass::PASS) {
230 pass_visibility_buf_.resize(words_len);
232 fail_visibility_buf_.resize(words_len);
235 else if (current_pass_type_ == ShadowPass::FAIL) {
241 visibility_buf_.resize(words_len);
245 if (do_visibility_) {
247 gpu::Shader *shader = current_pass_type_ == ShadowPass::FORCED_FAIL ?
258 if (current_pass_type_ == ShadowPass::FORCED_FAIL) {
277 switch (current_pass_type_) {
278 case ShadowPass::PASS:
279 return pass_visibility_buf_;
280 case ShadowPass::FAIL:
281 return fail_visibility_buf_;
282 case ShadowPass::FORCED_FAIL:
283 return visibility_buf_;
287 return visibility_buf_;
290PassMain::Sub *&ShadowPass::get_pass_ptr(PassType type,
bool manifold,
bool cap )
292 return passes_[type][manifold][cap];
307 std::swap(direction_ws.y, direction_ws.z);
308 direction_ws *=
float3(-1, 1, -1);
312 pass_data_.light_direction_ws = direction_ws;
313 pass_data_.far_plane = planes[2] *
float4(-1, -1, -1, 1);
314 pass_data_.push_update();
335#if DEBUG_SHADOW_VOLUME
346 pass_ps_.state_set(depth_pass_state);
347 pass_ps_.state_stencil(0xFF, 0xFF, 0xFF);
350 fail_ps_.state_set(depth_fail_state);
351 fail_ps_.state_stencil(0xFF, 0xFF, 0xFF);
353 forced_fail_ps_.init();
354 forced_fail_ps_.state_set(depth_fail_state);
355 forced_fail_ps_.state_stencil(0xFF, 0xFF, 0xFF);
358 for (
bool manifold : {
false,
true}) {
360 ps = &pass_ps_.
sub(manifold ?
"manifold" :
"non_manifold");
362 ps->
bind_ubo(
"pass_data", pass_data_);
364 for (PassType fail_type : {FAIL, FORCED_FAIL}) {
365 PassMain &ps_main = fail_type == FAIL ? fail_ps_ : forced_fail_ps_;
367 PassMain::Sub *&ps = get_pass_ptr(fail_type, manifold,
false);
368 ps = &ps_main.
sub(manifold ?
"NoCaps.manifold" :
"NoCaps.non_manifold");
370 ps->
bind_ubo(
"pass_data", pass_data_);
372 PassMain::Sub *&caps_ps = get_pass_ptr(fail_type, manifold,
true);
373 caps_ps = &ps_main.
sub(manifold ?
"Caps.manifold" :
"Caps.non_manifold");
375 caps_ps->
bind_ubo(
"pass_data", pass_data_);
383 const bool has_transp_mat)
392 if (geom_shadow ==
nullptr) {
396#define DEBUG_CULLING 0
399 ShadowView shadow_view = ShadowView(
"ShadowView",
view, pass_data_.light_direction_ws);
401 "%s culling : %s\n", ob->
id.
name, shadow_view.debug_object_culling(ob) ?
"true" :
"false");
406 bool force_fail_pass = has_transp_mat || (!is_manifold && (scene_state.
cull_state != 0));
408 PassType fail_type = force_fail_pass ? FORCED_FAIL : FAIL;
414 int tri_len = is_manifold ? 2 : 4;
416 if (!force_fail_pass) {
418 ps.
draw_expand(geom_shadow, prim, tri_len, 1, handle);
423 get_pass_ptr(fail_type, is_manifold,
true)->draw_expand(geom_faces, prim, 2, 1, handle);
425 get_pass_ptr(fail_type, is_manifold,
false)->draw_expand(geom_shadow, prim, tri_len, 1, handle);
432 bool force_fail_method)
442 view_.setup(
view, pass_data_.light_direction_ws, force_fail_method);
444 view_.set_mode(PASS);
445 manager.
submit(pass_ps_, view_);
446 view_.set_mode(FAIL);
447 manager.
submit(fail_ps_, view_);
448 view_.set_mode(FORCED_FAIL);
449 manager.
submit(forced_fail_ps_, view_);
General operations, lookup, etc. for blender objects.
std::optional< blender::Bounds< blender::float3 > > BKE_object_boundbox_get(const Object *ob)
#define BLI_assert_unreachable()
MINLINE uint ceil_to_multiple_u(uint a, uint b)
MINLINE uint divide_ceil_u(uint a, uint b)
MINLINE float clamp_f(float value, float min, float max)
MINLINE int max_ii(int a, int b)
#define UNUSED_VARS_NDEBUG(...)
static void View(GHOST_IWindow *window, bool stereo, int eye=0)
void GPU_compute_dispatch(blender::gpu::Shader *shader, uint groups_x_len, uint groups_y_len, uint groups_z_len, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
void GPU_debug_group_end()
void GPU_debug_group_begin(const char *name)
#define GPU_ATTACHMENT_TEXTURE(_texture)
int GPU_shader_get_ubo_binding(blender::gpu::Shader *shader, const char *name)
void GPU_shader_uniform_1b(blender::gpu::Shader *sh, const char *name, bool value)
void GPU_shader_uniform_3fv(blender::gpu::Shader *sh, const char *name, const float data[3])
void GPU_shader_bind(blender::gpu::Shader *shader, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
int GPU_shader_get_ssbo_binding(blender::gpu::Shader *shader, const char *name)
void GPU_shader_uniform_1i(blender::gpu::Shader *sh, const char *name, int value)
@ GPU_BARRIER_SHADER_STORAGE
void GPU_memory_barrier(GPUBarrier barrier)
void GPU_storagebuf_clear(blender::gpu::StorageBuf *ssbo, uint32_t clear_value)
void GPU_storagebuf_bind(blender::gpu::StorageBuf *ssbo, int slot)
BMesh const char void * data
void append(const T &value)
IndexRange index_range() const
void submit(PassSimple &pass, View &view)
const float4x4 & viewmat(int view_id=0) const
static View & default_get()
virtual VisibilityBuf & get_visibility_buffer()
std::array< float3, 8 > frustum_corners_get(int view_id=0)
std::array< float4, 6 > frustum_planes_get(int view_id=0)
void shader_set(gpu::Shader *shader)
PassBase< DrawCommandBufType > & sub(const char *name)
void draw_expand(gpu::Batch *batch, GPUPrimType primitive_type, uint primitive_len, uint instance_len, uint vertex_len, uint vertex_first, ResourceIndexRange res_index={}, uint custom_id=0)
void bind_ubo(const char *name, gpu::UniformBuf *buffer)
detail::PassBase< command::DrawMultiBuf > Sub
blender::gpu::Shader * get()
StaticShader shadow_visibility_static
StaticShader shadow_visibility_dynamic
static ShaderCache & get()
void init(const SceneState &scene_state, SceneResources &resources)
void object_sync(SceneState &scene_state, ObjectRef &ob_ref, ResourceHandleRange handle, const bool has_transp_mat)
void draw(Manager &manager, View &view, SceneResources &resources, gpu::Texture &depth_stencil_tx, bool force_fail_method)
#define DRW_VISIBILITY_GROUP_SIZE
#define DRW_VIEW_UBO_SLOT
@ DRW_STATE_STENCIL_ALWAYS
@ DRW_STATE_DEPTH_GREATER_EQUAL
@ DRW_STATE_WRITE_STENCIL_SHADOW_FAIL
@ DRW_STATE_BLEND_ADD_FULL
@ DRW_STATE_WRITE_STENCIL_SHADOW_PASS
std::array< VecBase< T, 3 >, 8 > corners(const Bounds< VecBase< T, 3 > > &bounds)
detail::Pass< command::DrawMultiBuf > PassMain
gpu::Batch * DRW_cache_object_surface_get(Object *ob)
StorageArrayBuffer< ObjectBounds, 128 > ObjectBoundsBuf
gpu::Batch * DRW_cache_object_edge_detection_get(Object *ob, bool *r_is_manifold)
StorageArrayBuffer< ObjectInfos, 128 > ObjectInfosBuf
StorageArrayBuffer< uint, 4, true > VisibilityBuf
T dot(const QuaternionBase< T > &a, const QuaternionBase< T > &b)
AxisSigned cross(const AxisSigned a, const AxisSigned b)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
VecBase< T, 3 > transform_direction(const MatBase< T, 3, 3 > &mat, const VecBase< T, 3 > &direction)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
MatBase< float, 4, 4 > float4x4
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
VecBase< int32_t, 3 > int3
VecBase< float, 3 > float3
struct SceneDisplay display
float4 shadow_direction_vs
UniformBuffer< WorldData > world_buf
#define DEBUG_SHADOW_VOLUME