Fix: EEVEE-Next: Shadow: Casters behind area lights cast shadow #120992
|
@ -245,7 +245,7 @@
|
|||
/* Only during shadow rendering. */
|
||||
#define SHADOW_RENDER_MAP_BUF_SLOT 3
|
||||
#define SHADOW_PAGE_INFO_SLOT 4
|
||||
#define SHADOW_VIEWPORT_INDEX_BUF_SLOT 5
|
||||
#define SHADOW_RENDER_VIEW_BUF_SLOT 5
|
||||
|
||||
/* Only during pre-pass. */
|
||||
#define VELOCITY_OBJ_PREV_BUF_SLOT 0
|
||||
|
|
|
@ -204,7 +204,7 @@ void ShadowPipeline::sync()
|
|||
draw::PassMain::Sub &pass = render_ps_.sub("Shadow.Surface");
|
||||
pass.state_set(state);
|
||||
pass.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
|
||||
pass.bind_ssbo(SHADOW_VIEWPORT_INDEX_BUF_SLOT, &inst_.shadows.viewport_index_buf_);
|
||||
pass.bind_ssbo(SHADOW_RENDER_VIEW_BUF_SLOT, &inst_.shadows.render_view_buf_);
|
||||
if (!shadow_update_tbdr) {
|
||||
/* We do not need all of the shadow information when using the TBDR-optimized approach. */
|
||||
pass.bind_image(SHADOW_ATLAS_IMG_SLOT, inst_.shadows.atlas_tx_);
|
||||
|
|
|
@ -1146,9 +1146,12 @@ struct ShadowTileMapData {
|
|||
int clip_data_index;
|
||||
/** Bias LOD to tag for usage to lower the amount of tile used. */
|
||||
float lod_bias;
|
||||
int _pad0;
|
||||
int _pad1;
|
||||
int _pad2;
|
||||
/** Light type this tilemap is from. */
|
||||
eLightType light_type;
|
||||
/** True if the tilemap is part of area light shadow and is one of the side projections. */
|
||||
bool32_t is_area_side;
|
||||
/** Distance behind the area light a shadow is shifted. */
|
||||
float area_shift;
|
||||
/** Near and far clip distances for punctual. */
|
||||
float clip_near;
|
||||
float clip_far;
|
||||
|
@ -1159,8 +1162,29 @@ struct ShadowTileMapData {
|
|||
};
|
||||
BLI_STATIC_ASSERT_ALIGN(ShadowTileMapData, 16)
|
||||
|
||||
/**
|
||||
* Lightweight version of ShadowTileMapData that only contains data used for rendering the shadow.
|
||||
*/
|
||||
struct ShadowRenderView {
|
||||
/**
|
||||
* Is either:
|
||||
* - positive radial distance for point lights.
|
||||
* - negative distance to light plane (divided by sqrt3) for area lights side projections.
|
||||
* - zero if disabled.
|
||||
* Use sign to determine with case we are in.
|
||||
*/
|
||||
float clip_distance_inv;
|
||||
/* Viewport to submit the geometry of this tilemap view to. */
|
||||
uint viewport_index;
|
||||
|
||||
uint _pad0;
|
||||
uint _pad1;
|
||||
};
|
||||
BLI_STATIC_ASSERT_ALIGN(ShadowRenderView, 16)
|
||||
|
||||
/**
|
||||
* Per tilemap data persistent on GPU.
|
||||
* Kept separately for easier clearing on GPU.
|
||||
*/
|
||||
struct ShadowTileMapClip {
|
||||
/** Clip distances that were used to render the pages. */
|
||||
|
@ -1976,6 +2000,7 @@ using ShadowPageCacheBuf = draw::StorageArrayBuffer<uint2, SHADOW_MAX_PAGE, true
|
|||
using ShadowTileMapDataBuf = draw::StorageVectorBuffer<ShadowTileMapData, SHADOW_MAX_TILEMAP>;
|
||||
using ShadowTileMapClipBuf = draw::StorageArrayBuffer<ShadowTileMapClip, SHADOW_MAX_TILEMAP, true>;
|
||||
using ShadowTileDataBuf = draw::StorageArrayBuffer<ShadowTileDataPacked, SHADOW_MAX_TILE, true>;
|
||||
using ShadowRenderViewBuf = draw::StorageArrayBuffer<ShadowRenderView, SHADOW_VIEW_MAX, true>;
|
||||
using SurfelBuf = draw::StorageArrayBuffer<Surfel, 64>;
|
||||
using SurfelRadianceBuf = draw::StorageArrayBuffer<SurfelRadiance, 64>;
|
||||
using CaptureInfoBuf = draw::StorageBuffer<CaptureInfoData>;
|
||||
|
|
|
@ -37,6 +37,8 @@ void ShadowTileMap::sync_orthographic(const float4x4 &object_mat_,
|
|||
}
|
||||
projection_type = projection_type_;
|
||||
level = clipmap_level;
|
||||
light_type = eLightType::LIGHT_SUN;
|
||||
is_area_side = false;
|
||||
|
||||
if (grid_shift == int2(0)) {
|
||||
/* Only replace shift if it is not already dirty. */
|
||||
|
@ -69,7 +71,8 @@ void ShadowTileMap::sync_orthographic(const float4x4 &object_mat_,
|
|||
1.0);
|
||||
}
|
||||
|
||||
void ShadowTileMap::sync_cubeface(const float4x4 &object_mat_,
|
||||
void ShadowTileMap::sync_cubeface(eLightType light_type_,
|
||||
const float4x4 &object_mat_,
|
||||
float near_,
|
||||
float far_,
|
||||
float side_,
|
||||
|
@ -84,6 +87,8 @@ void ShadowTileMap::sync_cubeface(const float4x4 &object_mat_,
|
|||
cubeface = face;
|
||||
grid_offset = int2(0);
|
||||
lod_bias = lod_bias_;
|
||||
light_type = light_type_;
|
||||
is_area_side = is_area_light(light_type) && (face != eCubeFace::Z_NEG);
|
||||
|
||||
if ((clip_near != near_) || (clip_far != far_) || (half_size != side_)) {
|
||||
set_dirty();
|
||||
|
@ -91,6 +96,7 @@ void ShadowTileMap::sync_cubeface(const float4x4 &object_mat_,
|
|||
|
||||
clip_near = near_;
|
||||
clip_far = far_;
|
||||
area_shift = shift;
|
||||
half_size = side_;
|
||||
center_offset = float2(0.0f);
|
||||
|
||||
|
@ -259,25 +265,27 @@ void ShadowPunctual::release_excess_tilemaps()
|
|||
tilemaps_ = span.take_front(tilemaps_needed_);
|
||||
}
|
||||
|
||||
void ShadowPunctual::compute_projection_boundaries(float light_radius,
|
||||
void ShadowPunctual::compute_projection_boundaries(eLightType light_type,
|
||||
float light_radius,
|
||||
float shadow_radius,
|
||||
float max_lit_distance,
|
||||
float &near,
|
||||
float &far,
|
||||
float &side)
|
||||
float &side,
|
||||
float &back_shift)
|
||||
{
|
||||
/**
|
||||
/*
|
||||
* In order to make sure we can trace any ray in its entirety using a single tile-map, we have
|
||||
* to make sure that the tile-map cover all potential occluder that can intersect any ray shot
|
||||
* in this particular shadow quadrant.
|
||||
*
|
||||
* To this end, we shift the tile-map perspective origin behind the light shape and make sure the
|
||||
* To this end, we inflate the tile-map perspective sides to make sure the
|
||||
* tile-map frustum starts where the rays cannot go.
|
||||
*
|
||||
* We are interesting in finding `I` the new origin and `n` the new near plane distances.
|
||||
*
|
||||
* I .... Shifted light center
|
||||
* /|
|
||||
* I .... Intersection between tangent and
|
||||
* /| projection center axis
|
||||
* / |
|
||||
* / |
|
||||
* / |
|
||||
|
@ -292,22 +300,22 @@ void ShadowPunctual::compute_projection_boundaries(float light_radius,
|
|||
* / ... |
|
||||
* /. |
|
||||
* / |
|
||||
* Tangent to light shape .... T\--------------N .... Shifted near plane
|
||||
* Tangent to light shape .... T\--------------N
|
||||
* / --\ Beta |
|
||||
* / -\ |
|
||||
* / --\ |
|
||||
* /. --\ |
|
||||
* / . -\ |
|
||||
* / . Alpha -O .... Light center
|
||||
* / . --/ |
|
||||
* / . --/ |
|
||||
* / . -/ |
|
||||
* / . --/ |
|
||||
* /-------------/------------x .... Desired near plane (inscribed cube)
|
||||
* / --/ .. |
|
||||
* / --/ ... |
|
||||
* / --/ .... |
|
||||
* / -/ ....|
|
||||
* / . /-/ |
|
||||
* Inflated side / . /--- -/ |
|
||||
* . / . /---- --/ |
|
||||
* . / /---- . --/ |
|
||||
* /-------------/------------X .... Desired near plane (inscribed cube)
|
||||
* /---- --/ .. |
|
||||
* /---- / --/ ... |
|
||||
* /---- / --/ .... |
|
||||
* / -/ ....| .... Shadow radius
|
||||
* / --/ |
|
||||
* /--/ |
|
||||
* F .... Most distant shadow receiver possible.
|
||||
|
@ -315,18 +323,36 @@ void ShadowPunctual::compute_projection_boundaries(float light_radius,
|
|||
* F: The most distant shadowed point at the edge of the 45° cube-face pyramid.
|
||||
* O: The light origin.
|
||||
* T: The tangent to the circle of radius `radius` centered at the origin and passing through F.
|
||||
* I: The shifted light origin.
|
||||
* I: Intersection between tangent and the projection center axis.
|
||||
* N: The shifted near plane center.
|
||||
* X: Intersection between the near plane and the projection center axis.
|
||||
* Alpha: FOT angle.
|
||||
* Beta: OTN angle.
|
||||
*
|
||||
* TODO(fclem): Explain derivation.
|
||||
* Note: FTO, ONT and TNI are right angles.
|
||||
*/
|
||||
float cos_alpha = shadow_radius / max_lit_distance;
|
||||
float sin_alpha = sqrt(1.0f - math::square(cos_alpha));
|
||||
float near_shift = M_SQRT2 * shadow_radius * 0.5f * (sin_alpha - cos_alpha);
|
||||
float side_shift = M_SQRT2 * shadow_radius * 0.5f * (sin_alpha + cos_alpha);
|
||||
float origin_shift = M_SQRT2 * shadow_radius / (sin_alpha - cos_alpha);
|
||||
/* Make near plane to be inside the inscribed cube of the sphere. */
|
||||
near = max_ff(light_radius, max_lit_distance / 4000.0f) / M_SQRT3;
|
||||
|
||||
float min_near = (max_lit_distance / 4000.0f) / M_SQRT3;
|
||||
|
||||
if (is_area_light(light_type)) {
|
||||
/* Make near plane be inside the inscribed cube of the shadow sphere. */
|
||||
near = max_ff(shadow_radius / M_SQRT3, min_near);
|
||||
/* Subtract min_near to make the shadow center match the light center if there is no shadow
|
||||
* tracing required. This avoid light leaking issues near the light plane caused by the
|
||||
* shadow discard clipping. */
|
||||
back_shift = (near - min_near);
|
||||
}
|
||||
else {
|
||||
/* Make near plane be inside the inscribed cube of the light sphere. */
|
||||
near = max_ff(light_radius / M_SQRT3, min_near);
|
||||
back_shift = 0.0f;
|
||||
}
|
||||
|
||||
far = max_lit_distance;
|
||||
if (shadow_radius > 1e-5f) {
|
||||
side = ((side_shift / (origin_shift - near_shift)) * (origin_shift + near));
|
||||
|
@ -340,11 +366,9 @@ void ShadowPunctual::end_sync(Light &light, float lod_bias)
|
|||
{
|
||||
ShadowTileMapPool &tilemap_pool = shadows_.tilemap_pool;
|
||||
|
||||
float side, near, far;
|
||||
compute_projection_boundaries(light_radius_, shadow_radius_, max_distance_, near, far, side);
|
||||
|
||||
/* Shift shadow map origin for area light to avoid clipping nearby geometry. */
|
||||
float shift = is_area_light(light.type) ? near : 0.0f;
|
||||
float side, near, far, shift;
|
||||
compute_projection_boundaries(
|
||||
light.type, light_radius_, shadow_radius_, max_distance_, near, far, side, shift);
|
||||
|
||||
float4x4 obmat_tmp = light.object_mat;
|
||||
|
||||
|
@ -357,15 +381,20 @@ void ShadowPunctual::end_sync(Light &light, float lod_bias)
|
|||
tilemaps_.append(tilemap_pool.acquire());
|
||||
}
|
||||
|
||||
tilemaps_[Z_NEG]->sync_cubeface(obmat_tmp, near, far, side, shift, Z_NEG, lod_bias);
|
||||
tilemaps_[Z_NEG]->sync_cubeface(light.type, obmat_tmp, near, far, side, shift, Z_NEG, lod_bias);
|
||||
if (tilemaps_needed_ >= 5) {
|
||||
tilemaps_[X_POS]->sync_cubeface(obmat_tmp, near, far, side, shift, X_POS, lod_bias);
|
||||
tilemaps_[X_NEG]->sync_cubeface(obmat_tmp, near, far, side, shift, X_NEG, lod_bias);
|
||||
tilemaps_[Y_POS]->sync_cubeface(obmat_tmp, near, far, side, shift, Y_POS, lod_bias);
|
||||
tilemaps_[Y_NEG]->sync_cubeface(obmat_tmp, near, far, side, shift, Y_NEG, lod_bias);
|
||||
tilemaps_[X_POS]->sync_cubeface(
|
||||
light.type, obmat_tmp, near, far, side, shift, X_POS, lod_bias);
|
||||
tilemaps_[X_NEG]->sync_cubeface(
|
||||
light.type, obmat_tmp, near, far, side, shift, X_NEG, lod_bias);
|
||||
tilemaps_[Y_POS]->sync_cubeface(
|
||||
light.type, obmat_tmp, near, far, side, shift, Y_POS, lod_bias);
|
||||
tilemaps_[Y_NEG]->sync_cubeface(
|
||||
light.type, obmat_tmp, near, far, side, shift, Y_NEG, lod_bias);
|
||||
}
|
||||
if (tilemaps_needed_ == 6) {
|
||||
tilemaps_[Z_POS]->sync_cubeface(obmat_tmp, near, far, side, shift, Z_POS, lod_bias);
|
||||
tilemaps_[Z_POS]->sync_cubeface(
|
||||
light.type, obmat_tmp, near, far, side, shift, Z_POS, lod_bias);
|
||||
}
|
||||
|
||||
light.tilemap_index = tilemap_pool.tilemaps_data.size();
|
||||
|
@ -1195,7 +1224,7 @@ void ShadowModule::end_sync()
|
|||
sub.bind_ssbo("dst_coord_buf", dst_coord_buf_);
|
||||
sub.bind_ssbo("src_coord_buf", src_coord_buf_);
|
||||
sub.bind_ssbo("render_map_buf", render_map_buf_);
|
||||
sub.bind_ssbo("viewport_index_buf", viewport_index_buf_);
|
||||
sub.bind_ssbo("render_view_buf", render_view_buf_);
|
||||
sub.bind_ssbo("pages_infos_buf", pages_infos_data_);
|
||||
sub.bind_image("tilemaps_img", tilemap_pool.tilemap_tx);
|
||||
sub.dispatch(int3(1, 1, tilemap_pool.tilemaps_data.size()));
|
||||
|
|
|
@ -103,7 +103,8 @@ struct ShadowTileMap : public ShadowTileMapData {
|
|||
float lod_bias_,
|
||||
eShadowProjectionType projection_type_);
|
||||
|
||||
void sync_cubeface(const float4x4 &object_mat,
|
||||
void sync_cubeface(eLightType light_type_,
|
||||
const float4x4 &object_mat,
|
||||
float near,
|
||||
float far,
|
||||
float side,
|
||||
|
@ -252,8 +253,8 @@ class ShadowModule {
|
|||
StorageArrayBuffer<uint, SHADOW_RENDER_MAP_SIZE, true> src_coord_buf_ = {"src_coord_buf"};
|
||||
/** Same as dst_coord_buf_ but is not compact. More like a linear texture. */
|
||||
StorageArrayBuffer<uint, SHADOW_RENDER_MAP_SIZE, true> render_map_buf_ = {"render_map_buf"};
|
||||
/** View to viewport index mapping. */
|
||||
StorageArrayBuffer<uint, SHADOW_VIEW_MAX, true> viewport_index_buf_ = {"viewport_index_buf"};
|
||||
/** View to viewport index mapping and other render-only related data. */
|
||||
ShadowRenderViewBuf render_view_buf_ = {"render_view_buf"};
|
||||
|
||||
int3 dispatch_depth_scan_size_;
|
||||
float pixel_world_radius_;
|
||||
|
@ -453,12 +454,14 @@ class ShadowPunctual : public NonCopyable, NonMovable {
|
|||
* Make sure that the projection encompass all possible rays that can start in the projection
|
||||
* quadrant.
|
||||
*/
|
||||
void compute_projection_boundaries(float light_radius,
|
||||
void compute_projection_boundaries(eLightType light_type,
|
||||
float light_radius,
|
||||
float shadow_radius,
|
||||
float max_lit_distance,
|
||||
float &near,
|
||||
float &far,
|
||||
float &side);
|
||||
float &side,
|
||||
float &back_shift);
|
||||
};
|
||||
|
||||
class ShadowDirectional : public NonCopyable, NonMovable {
|
||||
|
|
|
@ -13,7 +13,7 @@ void main()
|
|||
{
|
||||
DRW_VIEW_FROM_RESOURCE_ID;
|
||||
#ifdef MAT_SHADOW
|
||||
shadow_viewport_layer_set(int(drw_view_id), int(viewport_index_buf[drw_view_id]));
|
||||
shadow_viewport_layer_set(int(drw_view_id), int(render_view_buf[drw_view_id].viewport_index));
|
||||
#endif
|
||||
|
||||
init_interface();
|
||||
|
@ -57,5 +57,10 @@ void main()
|
|||
clip_interp.clip_distance = dot(clip_plane.plane, vec4(interp.P, 1.0));
|
||||
#endif
|
||||
|
||||
#ifdef MAT_SHADOW
|
||||
shadow_clip.vector = shadow_clip_vector_get(drw_point_world_to_view(interp.P),
|
||||
render_view_buf[drw_view_id]);
|
||||
#endif
|
||||
|
||||
gl_Position = drw_point_world_to_homogenous(interp.P);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ void main()
|
|||
{
|
||||
DRW_VIEW_FROM_RESOURCE_ID;
|
||||
#ifdef MAT_SHADOW
|
||||
shadow_viewport_layer_set(int(drw_view_id), int(viewport_index_buf[drw_view_id]));
|
||||
shadow_viewport_layer_set(int(drw_view_id), int(render_view_buf[drw_view_id].viewport_index));
|
||||
#endif
|
||||
|
||||
init_interface();
|
||||
|
@ -56,4 +56,9 @@ void main()
|
|||
#ifdef MAT_CLIP_PLANE
|
||||
clip_interp.clip_distance = dot(clip_plane.plane, vec4(interp.P, 1.0));
|
||||
#endif
|
||||
|
||||
#ifdef MAT_SHADOW
|
||||
shadow_clip.vector = shadow_clip_vector_get(drw_point_world_to_view(interp.P),
|
||||
render_view_buf[drw_view_id]);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ void main()
|
|||
{
|
||||
DRW_VIEW_FROM_RESOURCE_ID;
|
||||
#ifdef MAT_SHADOW
|
||||
shadow_viewport_layer_set(int(drw_view_id), int(viewport_index_buf[drw_view_id]));
|
||||
shadow_viewport_layer_set(int(drw_view_id), int(render_view_buf[drw_view_id].viewport_index));
|
||||
#endif
|
||||
|
||||
init_interface();
|
||||
|
@ -39,5 +39,10 @@ void main()
|
|||
clip_interp.clip_distance = dot(clip_plane.plane, vec4(interp.P, 1.0));
|
||||
#endif
|
||||
|
||||
#ifdef MAT_SHADOW
|
||||
shadow_clip.vector = shadow_clip_vector_get(drw_point_world_to_view(interp.P),
|
||||
render_view_buf[drw_view_id]);
|
||||
#endif
|
||||
|
||||
gl_Position = drw_point_world_to_homogenous(interp.P);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ void main()
|
|||
{
|
||||
DRW_VIEW_FROM_RESOURCE_ID;
|
||||
#ifdef MAT_SHADOW
|
||||
shadow_viewport_layer_set(int(drw_view_id), int(viewport_index_buf[drw_view_id]));
|
||||
shadow_viewport_layer_set(int(drw_view_id), int(render_view_buf[drw_view_id].viewport_index));
|
||||
#endif
|
||||
|
||||
init_interface();
|
||||
|
@ -51,5 +51,10 @@ void main()
|
|||
clip_interp.clip_distance = dot(clip_plane.plane, vec4(interp.P, 1.0));
|
||||
#endif
|
||||
|
||||
#ifdef MAT_SHADOW
|
||||
shadow_clip.vector = shadow_clip_vector_get(drw_point_world_to_view(interp.P),
|
||||
render_view_buf[drw_view_id]);
|
||||
#endif
|
||||
|
||||
gl_Position = drw_point_world_to_homogenous(interp.P);
|
||||
}
|
||||
|
|
|
@ -103,7 +103,21 @@ void main()
|
|||
view_index = atomicAdd(statistics_buf.view_needed_count, 1);
|
||||
if (view_index < SHADOW_VIEW_MAX) {
|
||||
/* Setup the view. */
|
||||
viewport_index_buf[view_index] = viewport_index;
|
||||
|
||||
render_view_buf[view_index].viewport_index = viewport_index;
|
||||
/* Clipping setup. */
|
||||
if (tilemap_data.is_area_side) {
|
||||
/* Negative for tagging this case. See shadow_clip_vector_get for explanation. */
|
||||
render_view_buf[view_index].clip_distance_inv = -M_SQRT1_3 / tilemap_data.area_shift;
|
||||
}
|
||||
else if (is_point_light(tilemap_data.light_type)) {
|
||||
/* Clip as a sphere around the clip_near cube. */
|
||||
render_view_buf[view_index].clip_distance_inv = M_SQRT1_3 / tilemap_data.clip_near;
|
||||
}
|
||||
else {
|
||||
/* Disable local clipping. */
|
||||
render_view_buf[view_index].clip_distance_inv = 0.0;
|
||||
}
|
||||
|
||||
view_infos_buf[view_index].viewmat = tilemap_data.viewmat;
|
||||
view_infos_buf[view_index].viewinv = inverse(tilemap_data.viewmat);
|
||||
|
|
|
@ -161,6 +161,26 @@ void shadow_viewport_layer_set(int view_id, int lod)
|
|||
# endif
|
||||
gpu_ViewportIndex = lod;
|
||||
}
|
||||
|
||||
/* In order to support physical clipping, we pass a vector to the fragment shader that then clips
|
||||
* each fragment using a unit sphere test. This allows to support both point light and area light
|
||||
* clipping at the same time. */
|
||||
vec3 shadow_clip_vector_get(vec3 view_position, ShadowRenderView shadow_view)
|
||||
{
|
||||
float clip_distance_inv = shadow_view.clip_distance_inv;
|
||||
if (clip_distance_inv == 0.0) {
|
||||
/* No clipping. */
|
||||
return vec3(2.0);
|
||||
}
|
||||
|
||||
if (clip_distance_inv < 0.0) {
|
||||
/* Area light side projections. Clip using the up axis (which maps to light -Z). */
|
||||
/* Note: clip_distance_inv should already be scaled by M_SQRT3. */
|
||||
return vec3(view_position.y * clip_distance_inv);
|
||||
}
|
||||
/* Sphere light case. */
|
||||
return view_position * clip_distance_inv;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GPU_FRAGMENT_SHADER) && defined(MAT_SHADOW)
|
||||
|
|
|
@ -26,6 +26,12 @@ void main()
|
|||
{
|
||||
float f_depth = gl_FragCoord.z + fwidth(gl_FragCoord.z);
|
||||
|
||||
/* Clip to light shape. */
|
||||
if (length_squared(shadow_clip.vector) < 1.0) {
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef MAT_TRANSPARENT
|
||||
init_globals();
|
||||
|
||||
|
|
|
@ -231,14 +231,18 @@ GPU_SHADER_CREATE_INFO(eevee_surf_world)
|
|||
GPU_SHADER_INTERFACE_INFO(eevee_surf_shadow_atomic_iface, "shadow_iface")
|
||||
.flat(Type::INT, "shadow_view_id");
|
||||
|
||||
GPU_SHADER_INTERFACE_INFO(eevee_surf_shadow_clipping_iface, "shadow_clip")
|
||||
.smooth(Type::VEC3, "vector");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_surf_shadow)
|
||||
.define("DRW_VIEW_LEN", STRINGIFY(SHADOW_VIEW_MAX))
|
||||
.define("MAT_SHADOW")
|
||||
.builtins(BuiltinBits::VIEWPORT_INDEX)
|
||||
.storage_buf(SHADOW_VIEWPORT_INDEX_BUF_SLOT,
|
||||
.vertex_out(eevee_surf_shadow_clipping_iface)
|
||||
.storage_buf(SHADOW_RENDER_VIEW_BUF_SLOT,
|
||||
Qualifier::READ,
|
||||
"uint",
|
||||
"viewport_index_buf[SHADOW_VIEW_MAX]")
|
||||
"ShadowRenderView",
|
||||
"render_view_buf[SHADOW_VIEW_MAX]")
|
||||
.fragment_source("eevee_surf_shadow_frag.glsl")
|
||||
.additional_info("eevee_global_ubo", "eevee_utility_texture", "eevee_sampling_data");
|
||||
|
||||
|
|
|
@ -189,7 +189,7 @@ GPU_SHADER_CREATE_INFO(eevee_shadow_tilemap_finalize)
|
|||
.storage_buf(7, Qualifier::WRITE, SHADOW_PAGE_PACKED, "dst_coord_buf[SHADOW_RENDER_MAP_SIZE]")
|
||||
.storage_buf(8, Qualifier::WRITE, SHADOW_PAGE_PACKED, "src_coord_buf[SHADOW_RENDER_MAP_SIZE]")
|
||||
.storage_buf(9, Qualifier::WRITE, SHADOW_PAGE_PACKED, "render_map_buf[SHADOW_RENDER_MAP_SIZE]")
|
||||
.storage_buf(10, Qualifier::WRITE, "uint", "viewport_index_buf[SHADOW_VIEW_MAX]")
|
||||
.storage_buf(10, Qualifier::WRITE, "ShadowRenderView", "render_view_buf[SHADOW_VIEW_MAX]")
|
||||
.storage_buf(11, Qualifier::READ, "ShadowTileMapClip", "tilemaps_clip_buf[]")
|
||||
/* 12 is the minimum number of storage buf we require. Do not go above this limit. */
|
||||
.image(0, GPU_R32UI, Qualifier::WRITE, ImageType::UINT_2D, "tilemaps_img")
|
||||
|
|
|
@ -233,7 +233,8 @@ static void test_eevee_shadow_tag_update()
|
|||
|
||||
{
|
||||
ShadowTileMap tilemap(0 * SHADOW_TILEDATA_PER_TILEMAP);
|
||||
tilemap.sync_cubeface(float4x4::identity(), 0.01f, 1.0f, 0.01f, 0.0f, Z_NEG, 0.0f);
|
||||
tilemap.sync_cubeface(
|
||||
LIGHT_OMNI_SPHERE, float4x4::identity(), 0.01f, 1.0f, 0.01f, 0.0f, Z_NEG, 0.0f);
|
||||
tilemaps_data.append(tilemap);
|
||||
}
|
||||
{
|
||||
|
@ -1541,7 +1542,8 @@ static void test_eevee_shadow_page_mask_ex(int max_view_per_tilemap)
|
|||
|
||||
{
|
||||
ShadowTileMap tilemap(0);
|
||||
tilemap.sync_cubeface(float4x4::identity(), 0.01f, 1.0f, 0.01f, 0.0f, Z_NEG, 0.0f);
|
||||
tilemap.sync_cubeface(
|
||||
LIGHT_OMNI_SPHERE, float4x4::identity(), 0.01f, 1.0f, 0.01f, 0.0f, Z_NEG, 0.0f);
|
||||
tilemaps_data.append(tilemap);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue