Differential D16826 Diff 59819 source/blender/draw/engines/workbench/shaders/workbench_shadow_visibility_comp.glsl
Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/engines/workbench/shaders/workbench_shadow_visibility_comp.glsl
- This file was added.
| #pragma BLENDER_REQUIRE(common_math_lib.glsl) | |||||
| #pragma BLENDER_REQUIRE(common_intersect_lib.glsl) | |||||
| shared uint shared_result; | |||||
| #ifdef DYNAMIC_PASS_SELECTION | |||||
| void set_visibility(bool pass, bool fail) | |||||
| { | |||||
| if (!pass) { | |||||
| atomicAnd(pass_visibility_buf[gl_WorkGroupID.x], ~(1u << gl_LocalInvocationID.x)); | |||||
| } | |||||
| if (!fail) { | |||||
| atomicAnd(fail_visibility_buf[gl_WorkGroupID.x], ~(1u << gl_LocalInvocationID.x)); | |||||
| } | |||||
| } | |||||
| #else | |||||
| void set_visibility(bool visibility) | |||||
| { | |||||
| if (!visibility) { | |||||
| atomicAnd(visibility_buf[gl_WorkGroupID.x], ~(1u << gl_LocalInvocationID.x)); | |||||
| } | |||||
| } | |||||
| #endif | |||||
| bool is_visible(IsectBox box) | |||||
| { | |||||
| for (int i_plane = 0; i_plane < extruded_frustum.planes_count; i_plane++) { | |||||
| vec4 plane = extruded_frustum.planes[i_plane]; | |||||
| bool separating_axis = true; | |||||
| for (int i_corner = 0; i_corner < 8; i_corner++) { | |||||
| float signed_distance = dot(box.corners[i_corner], plane.xyz) - plane.w; | |||||
| if (signed_distance <= 0) { | |||||
| separating_axis = false; | |||||
| break; | |||||
| } | |||||
| } | |||||
| if (separating_axis) { | |||||
| return false; | |||||
| } | |||||
| } | |||||
| return true; | |||||
| } | |||||
| bool intersects_near_plane(IsectBox box) | |||||
| { | |||||
| vec4 near_plane = drw_view_culling.planes[4]; | |||||
| bool on_positive_side = false; | |||||
| bool on_negative_side = false; | |||||
| for (int i_corner = 0; i_corner < 8; i_corner++) { | |||||
| for (int i_displace = 0; i_displace < 2; i_displace++) { | |||||
| vec3 corner = box.corners[i_corner] + (shadow_direction * 1e5f * i_displace); | |||||
| float signed_distance = dot(corner, -near_plane.xyz) - near_plane.w; | |||||
| if (signed_distance <= 0) { | |||||
| on_negative_side = true; | |||||
| } | |||||
| else { | |||||
| on_positive_side = true; | |||||
| } | |||||
| if (on_negative_side && on_positive_side) { | |||||
| return true; | |||||
| } | |||||
| } | |||||
| } | |||||
| return false; | |||||
| } | |||||
| void main() | |||||
| { | |||||
| if (gl_GlobalInvocationID.x >= resource_len) { | |||||
| return; | |||||
| } | |||||
| ObjectBounds bounds = bounds_buf[gl_GlobalInvocationID.x]; | |||||
| IsectBox box = isect_data_setup(bounds.bounding_corners[0].xyz, | |||||
| bounds.bounding_corners[1].xyz, | |||||
| bounds.bounding_corners[2].xyz, | |||||
| bounds.bounding_corners[3].xyz); | |||||
| #ifdef DYNAMIC_PASS_SELECTION | |||||
| if (is_visible(box)) { | |||||
| bool use_fail_pass = force_fail_method || intersects_near_plane(box); | |||||
| set_visibility(!use_fail_pass, use_fail_pass); | |||||
| } | |||||
| else { | |||||
| set_visibility(false, false); | |||||
| } | |||||
| #else | |||||
| set_visibility(is_visible(box)); | |||||
| #endif | |||||
| } | |||||