Skip to content

Conversation

@ErikReider
Copy link
Member

@ErikReider ErikReider commented Jul 24, 2025

Allows for a dynamic shadow that isn't a fixed shape, like our shadow_node. This allows for shadows that "exclude" transparent regions like weirdly shaped surfaces and text buffers.

So according to the Mozilla docs, the drop-shadow works by applying a blur to the base textures alpha mask. So this should mimic the implementation that's used by web browsers. So a 10px radii in the browser should result in the same looking blur here.

image

Swaync with the smart shadows enabled:
image

TODO:

  • Change name to "drop-shadow"? (from smart shadows)
  • Use kawase blur instead? (Use a two-pass Gaussian blur, like the web browsers use)
  • Add this to the existing shadow-node and allow it to link to a scene_buffer instead?
  • Fix damage not being compensated for. Needs the same treatment as regular blur, so maybe do both in the same pass?
  • Fix weird weakness of color with a "low" alpha like 0.5
  • Add all parameters
    • x, y (also compensate the node visible region with these parameters)
    • Fix node visible region by creating two regions (one for blur and one for shadow) and run the union pixman operation
    • Color (pre-multiplied?)
  • Add post-processing or use the regular pass_add_texture function instead of a dedicated shader (or just blit for gles3?)
  • Add gles2 support
  • Make sure scaling and transforms work as expected
  • Fix all commented TODOs

@ErikReider ErikReider self-assigned this Jul 24, 2025
@ErikReider ErikReider added the enhancement New feature or request label Jul 24, 2025
@ErikReider ErikReider force-pushed the smart-shadows branch 2 times, most recently from 4e6325e to 3bf8724 Compare July 29, 2025 10:46
@ErikReider ErikReider changed the title Add smart shadows (CSS drop-shadows) Add drop shadows (CSS drop-shadows) Jul 30, 2025
@ErikReider ErikReider marked this pull request as ready for review July 30, 2025 17:56
@ErikReider ErikReider requested a review from WillPower3309 July 30, 2025 17:56
@WillPower3309
Copy link
Member

Still need to look at wlr_scene.c

@ErikReider ErikReider marked this pull request as draft August 15, 2025 21:41
@ErikReider
Copy link
Member Author

Converting to draft as there still are a few damage issues :/

@ErikReider ErikReider marked this pull request as ready for review September 27, 2025 16:49
@ErikReider
Copy link
Member Author

I've been using this for a few months now on multiple machines with the SwayFX PR, and no crashes. Marking as ready :)

#include <stdbool.h>
#include <wlr/util/addon.h>

#define drop_shadow_calc_size(blur_sigma) (ceil(1.5f * blur_sigma) * 2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: does an equal blur radius value result in an equal spread in drop shadow and box shadow?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but the overall color alpha will vary depending on the textures opacity (should we fix this?)

image image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, ideally they'd look the same but I haven't dived deep enough to know if this is a trivial problem to solve or not haha

Copy link
Member

@WillPower3309 WillPower3309 Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately the single pixel transparent area between the shadow and texture would need texture shader side changes (so we can keep that out of scope)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, ideally they'd look the same

Yeah, I noticed that the drop shadow spread is a bit further than the box one, so I'll be working on fixing that after the university finals season has passed

Comment on lines +160 to +163
enum wlr_scene_shadow_type {
WLR_SCENE_SHADOW_TYPE_DROP,
WLR_SCENE_SHADOW_TYPE_BOX,
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need these? We should be able to tell if buffer_link is NULL or not

Comment on lines +590 to +591
* shadow-type. A drop-shadow returns a larger integer compared to the
* box-shadow, so this can be used to dynamically adjust the size and position
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why would this be?

* NOTE: Please use the `wlr_scene_shadow_get_offset` function to get a dynamic
* offset depending on the type.
*/
void wlr_scene_shadow_set_type(struct wlr_scene_shadow *shadow, enum wlr_scene_shadow_type type);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can remove this call for now, if we're aligned on my earlier comment

@@ -0,0 +1,27 @@
#ifndef TYPES_LINKED_NODES_H
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this file should be linked_node.h

Comment on lines +11 to +13
uniform float blur_sigma;
uniform vec4 color;
uniform bool is_horizontal;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

size, blur_sigma and is_horizontal are unused

Comment on lines +8 to +11
uniform vec2 size;
uniform float blur_sigma;
uniform vec4 color;
uniform bool is_horizontal;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

size, blur_sigma, is_horizontal unused

Comment on lines +1057 to +1064
int wlr_scene_shadow_get_offset(struct wlr_scene_shadow *shadow) {
switch (shadow->type) {
case WLR_SCENE_SHADOW_TYPE_DROP:
return drop_shadow_calc_size(shadow->blur_sigma);
default:
return shadow->blur_sigma;
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have you tested that the shadows are functionally identical between box and drop? We'd want the same appearance minus the transparent areas between types. Also, why do you refer to the sigma as offset for the drop shadow?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Realize I already left this comment earlier in blur_data.h

struct linked_node *shadow_link = linked_nodes_get_sibling(&scene_buffer->drop_shadow_link);
if (shadow_link != NULL) {
struct wlr_scene_shadow *scene_shadow = wl_container_of(shadow_link, scene_shadow, buffer_link);
if (scene_shadow && SCENE_SHADOW_IS_DROP(scene_shadow)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need this check? We already have an assertion on the link. Maybe we should add another assertion here instead


const int shadow_size = drop_shadow_calc_size(scene_shadow->blur_sigma) * data->scale;

// Optimization: Fallback to a regular box-shadow if the texture is fully opaque
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

beautiful

@the-eater the-eater mentioned this pull request Oct 20, 2025
3 tasks
@WillPower3309
Copy link
Member

Late here, but do you think it's worth splitting the shadow node into separate box shadow and drop shadow nodes? Just thinking that there's not really any use case where a comp would want to swap between them on the same node, and it could help split up the impl. Open to your thoughts as well!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants