EEVEE Next: Tag shadowmap usage for transparent object volumes #104580

Merged
Miguel Pozo merged 31 commits from pragma37/blender:pull-eevee-shadows-tag-usage-transparent into main 2023-03-08 13:51:35 +01:00
3 changed files with 16 additions and 15 deletions
Showing only changes of commit 07a8d43728 - Show all commits

View File

@ -1100,7 +1100,7 @@ void ShadowModule::set_view(View &view)
tilemap_projection_ratio_ = tilemap_pixel_radius() / pixel_world_radius_;
usage_tag_fb_resolution_ = math::divide_ceil(int2(target_size),
int2(std::pow(2, usage_tag_fb_lod_)));
int2(std::exp2(usage_tag_fb_lod_)));
usage_tag_debug_tx_.ensure_2d(GPU_RGB16F, usage_tag_fb_resolution_);
usage_tag_debug_tx_.clear(float4(0));
usage_tag_fb.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(usage_tag_debug_tx_));
@ -1156,7 +1156,7 @@ void ShadowModule::set_view(View &view)
void ShadowModule::debug_draw(View &view, GPUFrameBuffer *view_fb)
{
GPU_texture_copy(inst_.render_buffers.combined_tx, usage_tag_debug_tx_);
// GPU_texture_copy(inst_.render_buffers.combined_tx, usage_tag_debug_tx_);
if (!ELEM(inst_.debug_mode,
eDebugMode::DEBUG_SHADOW_TILEMAPS,

View File

@ -20,18 +20,18 @@ float ray_aabb(vec3 ray_origin, vec3 ray_direction, vec3 aabb_min, vec3 aabb_max
float t_max = min_v3(max(t_mins, t_maxs));
/* AABB is in the opposite direction. */
if (t_max < 0.0f) {
return -1.0f;
if (t_max < 0.0) {
return -1.0;
}
/* No intersection. */
if (t_min > t_max) {
return -1.0f;
return -1.0;
}
/* The ray origin is inside the aabb. */
if (t_min < 0.0f) {
if (t_min < 0.0) {
/* For regular ray casting we would return t_max here,
* but we want to ray cast against the box volume, not just the surface. */
return 0.0f;
return 0.0;
}
return t_min;
}
@ -68,9 +68,9 @@ void main()
#else
outDebug.rgb = ws_near_plane + (ws_view_direction * near_box_t);
#endif
outDebug.a = 1.0f;
outDebug.a = 1.0;
float step_size = 0.1f;
float step_size = 0.1;
for (float t = near_box_t; t <= far_box_t; t += step_size) {
/* Ensure we don't get past far_box_t. */
t = min(t, far_box_t);
@ -78,14 +78,14 @@ void main()
vec3 P = ws_near_plane + (ws_view_direction * t);
vec3 vP = vs_near_plane + (vs_view_direction * t);
/* TODO (Miguel Pozo): Pass step size to ensure conservative enough LOD selection */
shadow_tag_usage(vP, P, gl_FragCoord.xy * pow(2, fb_lod));
shadow_tag_usage(vP, P, gl_FragCoord.xy * exp2(fb_lod));
pragma37 marked this conversation as resolved

Use exp2 instead of pow(2, x). Try to apply this everywhere.

Use `exp2` instead of `pow(2, x)`. Try to apply this everywhere.
/* Ensure that step_size is as large as possible,
* but (hopefully) not larger than the smallest possible page size. */
step_size = pixel_world_radius * SHADOW_PAGE_RES * 0.5;
bool is_persp = (ProjectionMatrix[3][3] == 0.0);
if (is_persp) {
step_size *= max(0.01f, t);
step_size *= max(0.01, t);
}
}
}

View File

@ -14,16 +14,17 @@ void inflate_bounds(vec3 ls_center, inout vec3 P, inout vec3 lP)
{
vec3 vP = point_world_to_view(P);
float inflate_scale = pixel_world_radius * pow(2, fb_lod);
float inflate_scale = pixel_world_radius * exp2(fb_lod);
bool is_persp = (ProjectionMatrix[3][3] == 0.0);
if (is_persp) {
inflate_scale *= -vP.z;
}
inflate_scale *= 0.5f; /* Half pixel. */
inflate_scale *= 0.5; /* Half pixel. */
pragma37 marked this conversation as resolved

I think we need a fullpixel here.

Imagine a really tiny box.

      tagged    |   not tagged    < Tiles tagging. Tilemap boundary at the middle
 --------------T|---------------  < the shadow tilemap at the correct LOD
            |----x----|           < the half inflated bounds (covers 1 pixel)
                 x                < the object (infinitesimal)
|----x----|----x----|----x----|   < Screen LOD where we raster the bboxes

A tile map boundary cannot be mitigated by tagging a lower LOD selection.

Inflating a whole pixel:

      tagged    |    tagged       < Tiles tagging. Tilemap boundary at the middle
 --------------T|--------T------  < the shadow tilemap at the correct LOD
       |---------x--------|       < the FULL inflated bounds (covers 2 pixel)
                 x                < the object (infinitesimal)
|----x----|----x----|----x----|   < Screen LOD where we raster the bboxes
I think we need a fullpixel here. Imagine a really tiny box. ``` tagged | not tagged < Tiles tagging. Tilemap boundary at the middle --------------T|--------------- < the shadow tilemap at the correct LOD |----x----| < the half inflated bounds (covers 1 pixel) x < the object (infinitesimal) |----x----|----x----|----x----| < Screen LOD where we raster the bboxes ``` A tile map boundary cannot be mitigated by tagging a lower LOD selection. Inflating a whole pixel: ``` tagged | tagged < Tiles tagging. Tilemap boundary at the middle --------------T|--------T------ < the shadow tilemap at the correct LOD |---------x--------| < the FULL inflated bounds (covers 2 pixel) x < the object (infinitesimal) |----x----|----x----|----x----| < Screen LOD where we raster the bboxes ```
vec3 vs_inflate_vector = normal_object_to_view(sign(lP - ls_center));
vs_inflate_vector.z = 0;
vs_inflate_vector /= max_v2(abs(vs_inflate_vector));
/* Scale the vector so the largest axis length is 1 */
pragma37 marked this conversation as resolved

This only works because max_v2 is a define. Use vs_inflate_vector.xy to avoid the confusion.
Also not entierly sure what's this about. Can you add a comment on this?

This only works because `max_v2` is a define. Use `vs_inflate_vector.xy` to avoid the confusion. Also not entierly sure what's this about. Can you add a comment on this?
vs_inflate_vector /= max_v2(abs(vs_inflate_vector.xy));
vs_inflate_vector *= inflate_scale;
vP += vs_inflate_vector;
@ -48,7 +49,7 @@ void main()
vec3 ws_aabb_max = bounds.bounding_corners[0].xyz + bounds.bounding_corners[1].xyz +
bounds.bounding_corners[2].xyz + bounds.bounding_corners[3].xyz;
vec3 ls_center = point_world_to_object((ws_aabb_min + ws_aabb_max) / 2.0f);
vec3 ls_center = point_world_to_object((ws_aabb_min + ws_aabb_max) / 2.0);
vec3 ls_conservative_min = vec3(FLT_MAX);
vec3 ls_conservative_max = vec3(-FLT_MAX);