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] = {
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) {
140 if (
math::dot(
float3(extruded_face), corner) > (extruded_face.w + 0.1)) {
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)
187 for (
int p : IndexRange(extruded_frustum_.planes_count)) {
188 float4 plane = extruded_frustum_.planes[p];
189 bool separating_axis =
true;
193 if (signed_distance <= 0) {
194 separating_axis =
false;
198 if (separating_axis) {
199 printf(
"Sepatating Axis >>> x: %f, y: %f, z: %f, w: %f \n",
UNPACK4(plane));
206void ShadowPass::ShadowView::set_mode(ShadowPass::PassType type)
208 current_pass_type_ = type;
210 manager_fingerprint_ = 0;
213void ShadowPass::ShadowView::compute_visibility(
ObjectBoundsBuf &bounds,
222 uint word_per_draw = this->visibility_word_per_draw();
225 resource_len * word_per_draw;
229 if (current_pass_type_ == ShadowPass::PASS) {
231 pass_visibility_buf_.resize(words_len);
233 fail_visibility_buf_.resize(words_len);
236 else if (current_pass_type_ == ShadowPass::FAIL) {
242 visibility_buf_.resize(words_len);
246 if (do_visibility_) {
248 GPUShader *shader = current_pass_type_ == ShadowPass::FORCED_FAIL ?
259 if (current_pass_type_ == ShadowPass::FORCED_FAIL) {
278 switch (current_pass_type_) {
279 case ShadowPass::PASS:
280 return pass_visibility_buf_;
281 case ShadowPass::FAIL:
282 return fail_visibility_buf_;
283 case ShadowPass::FORCED_FAIL:
284 return visibility_buf_;
288 return visibility_buf_;
291PassMain::Sub *&ShadowPass::get_pass_ptr(PassType type,
bool manifold,
bool cap )
293 return passes_[type][manifold][cap];
308 std::swap(direction_ws.y, direction_ws.z);
309 direction_ws *=
float3(-1, 1, -1);
313 pass_data_.light_direction_ws = direction_ws;
314 pass_data_.far_plane = planes[2] *
float4(-1, -1, -1, 1);
315 pass_data_.push_update();
336#if DEBUG_SHADOW_VOLUME
347 pass_ps_.state_set(depth_pass_state);
348 pass_ps_.state_stencil(0xFF, 0xFF, 0xFF);
351 fail_ps_.state_set(depth_fail_state);
352 fail_ps_.state_stencil(0xFF, 0xFF, 0xFF);
354 forced_fail_ps_.init();
355 forced_fail_ps_.state_set(depth_fail_state);
356 forced_fail_ps_.state_stencil(0xFF, 0xFF, 0xFF);
359 for (
bool manifold : {
false,
true}) {
361 ps = &pass_ps_.
sub(manifold ?
"manifold" :
"non_manifold");
363 ps->
bind_ubo(
"pass_data", pass_data_);
365 for (PassType fail_type : {FAIL, FORCED_FAIL}) {
366 PassMain &ps_main = fail_type == FAIL ? fail_ps_ : forced_fail_ps_;
368 PassMain::Sub *&ps = get_pass_ptr(fail_type, manifold,
false);
369 ps = &ps_main.
sub(manifold ?
"NoCaps.manifold" :
"NoCaps.non_manifold");
371 ps->
bind_ubo(
"pass_data", pass_data_);
373 PassMain::Sub *&caps_ps = get_pass_ptr(fail_type, manifold,
true);
374 caps_ps = &ps_main.
sub(manifold ?
"Caps.manifold" :
"Caps.non_manifold");
376 caps_ps->
bind_ubo(
"pass_data", pass_data_);
384 const bool has_transp_mat)
393 if (geom_shadow ==
nullptr) {
397#define DEBUG_CULLING 0
400 ShadowView shadow_view = ShadowView(
"ShadowView",
view, pass_data_.light_direction_ws);
402 "%s culling : %s\n", ob->
id.
name, shadow_view.debug_object_culling(ob) ?
"true" :
"false");
407 bool force_fail_pass = has_transp_mat || (!is_manifold && (scene_state.
cull_state != 0));
409 PassType fail_type = force_fail_pass ? FORCED_FAIL : FAIL;
415 int tri_len = is_manifold ? 2 : 4;
417 if (!force_fail_pass) {
419 ps.
draw_expand(geom_shadow, prim, tri_len, 1, handle);
424 get_pass_ptr(fail_type, is_manifold,
true)->draw_expand(geom_faces, prim, 2, 1, handle);
426 get_pass_ptr(fail_type, is_manifold,
false)->draw_expand(geom_shadow, prim, tri_len, 1, handle);
432 GPUTexture &depth_stencil_tx,
433 bool force_fail_method)
443 view_.setup(
view, pass_data_.light_direction_ws, force_fail_method);
445 view_.set_mode(PASS);
446 manager.
submit(pass_ps_, view_);
447 view_.set_mode(FAIL);
448 manager.
submit(fail_ps_, view_);
449 view_.set_mode(FORCED_FAIL);
450 manager.
submit(forced_fail_ps_, view_);
General operations, lookup, etc. for blender objects.
void BKE_boundbox_init_from_minmax(BoundBox *bb, const float min[3], const float max[3])
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(GPUShader *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)
void GPU_shader_uniform_1i(GPUShader *sh, const char *name, int value)
int GPU_shader_get_ubo_binding(GPUShader *shader, const char *name)
void GPU_shader_bind(GPUShader *shader, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
void GPU_shader_uniform_3fv(GPUShader *sh, const char *name, const float data[3])
int GPU_shader_get_ssbo_binding(GPUShader *shader, const char *name)
void GPU_shader_uniform_1b(GPUShader *sh, const char *name, bool value)
void GPU_memory_barrier(eGPUBarrier barrier)
@ GPU_BARRIER_SHADER_STORAGE
void GPU_storagebuf_bind(GPUStorageBuf *ssbo, int slot)
void GPU_storagebuf_clear(GPUStorageBuf *ssbo, uint32_t clear_value)
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)
PassBase< DrawCommandBufType > & sub(const char *name)
void draw_expand(gpu::Batch *batch, GPUPrimType primitive_type, uint primitive_len, uint instance_len, uint vertex_len=-1, uint vertex_first=-1, ResourceHandleRange handle={0}, uint custom_id=0)
void bind_ubo(const char *name, GPUUniformBuf *buffer)
void shader_set(GPUShader *shader)
detail::PassBase< command::DrawMultiBuf > Sub
StaticShader shadow_visibility_static
StaticShader shadow_visibility_dynamic
static ShaderCache & get()
void init(const SceneState &scene_state, SceneResources &resources)
void draw(Manager &manager, View &view, SceneResources &resources, GPUTexture &depth_stencil_tx, bool force_fail_method)
void object_sync(SceneState &scene_state, ObjectRef &ob_ref, ResourceHandle handle, const bool has_transp_mat)
#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
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