Invisible shadow casters

The missing feature

It is currently not possible to make an invisible part cast a shadow.

The use case

I have a small room the player can enter. It would be cramped to enter this space in third person if the camera was forced to stay in the room so the camera is outside the room looking in with any walls that would block the camera’s view into the room made invisible, similar to a game like The Sims.

My problem is that I do not want this room lit as if it’s outdoors. I want bright sunlight to stream in through the windows and light up the floor but for the rest of the room to be lit as if it’s indoors and I want this to work whether the wall the window is on is visible or not.

Example images:


image

The proper way to do what I want would be to make invisible shadow casters that will ensure the room is in shadow from the sun except for the sunlight let in through the window, but Roblox does not have this feature (unlike many other engines like Unreal, Unity, and Godot).

Another use case is first-person shadows. Let’s say you want the player’s avatar to be invisible while the player is in first person but you still want them to cast a shadow. Good luck with that.

Workarounds

Give a part the Forcefield material, and then set it’s transparency to either math.inf or -math.inf.

On PC this will cause the part to not be rendered but cast a shadow. This is what I’m doing right now. This isn’t a good enough workaround though because it doesn’t work on every platform. On Android these invisible shadow casters don’t cast shadows, and worse on IOS these invisible shadow casters are actually still visible and cause a lot of z fighting.

This workaround also causes SurfaceGUIs with LightInfluence = 1 that are in a shadow cast with this method to still be lit as if in direct sunlight, even on PC where this workaround seems to work.

Place a part somewhere up in the sky where it’ll still cast a shadow where you want but not be visible without looking up ( using lighting:GetSunDirection() )

This method only works if you restrict the camera’s movement so player’s can’t look up and see random stuff floating in the air, and only works with sunlight. This should work for my use case but won’t for others.

shadow caster is the hallow white box with the window on it. The rooms are where the shadows are cast.
image

Implementation

I think Basepart.CastShadow should be deprecated and replaced with an ENUM property with the following possible values:

  • “None” – cast no shadows. Same as CastShadow = false.
  • “Alpha clip” or “On” – default and current behavior. cast shadows based on the transparency of the object and it’s surfaceappearance
  • “Always” – cast shadows regardless of the object’s transparency
  • “Always alpha clip” – Always cast shadows regardless of basepart.Transparency, but the alpha channel of the applied surfaceappearance will still cause parts of the model to not cast shadows. Useful for more complex shadows like of a ghost floating around.
12 Likes

The problem i see with replacing CastShadow is that game that rely on it would break if it has to use it.
I’d love to see improvements for shadow system in regardless, there’s one way to get shadows to work on transparent parts, but it’s hacky so god knows if it’ll stay unpatched or they’ll just fix a “feature”

When Roblox deprecates values they don’t usually remove them, just advise against using them in new work and hide them in the properties window.

How Roblox would typically implement this would be something like to make it so if Basepart.CastShadow gets set to True it would also update the ENUM to equal Alpha clip and if it gets set to False it would set the ENUM to None and if the ENUM gets modified instead and is set to anything but None then the deprecated boolean would get set to True.

2 Likes

This is so needed, in my game the player is in first person and the body is visible, but the head is invisible to not clip with the camera and it looks weird when a headless body is casting a shadow in a light

2 Likes

I have a feeling that your proposed implementation would significantly inflate file sizes for places with a large number of PVInstances, potentially rendering a sizable number of projects actively in development by developers across the platform unopenable/unable to be saved/unable to be uploaded as a result of hitting the maximum upload size for Studio (~100-125MB as a .rbxl file).

I support the idea of a shadow catcher material - but feel that a different solution, such as either:

  • An additional instance added as a child to alter rendering behavior, such as currently exists with Highlights.
    • Could potentially allow easy expansion for additional behaviors in future.
  • An additional boolean property (default false) that enables rendering shadows regardless of part opacity.
    • This, considering how parts are stored in .rbxmx/.rbxlx files, likely would have a far lower impact on file size than the initial proposed solution, as properties aren’t written to files explicitly if they remain as the default.

would likely be less problematic.

I don’t see how having a CastShadows boolean and some sort of AlwaysCastShadows boolean would save much space compared to a ENUM (which should just be stored as an int to my understanding, correct me if I’m wrong.)

I think Roblox is well capable of only storing one of the two values to disk since they’re redundant to each other. And they would only need to save it if it’s changed from the default so most baseparts likely wouldn’t have to save it at all.

1 Like

Good feature request. I don’t understand why some people won’t agree that deprecating BasePart.CastShadow is good idea? I think why. Because they think Roblox will delete .CastShadow by deprecating it. Simple answer : Not. If they are deleting something, they’re saying usually “sunsetting […]”

1 Like

Please read the entire post before responding.

I have readen everything. :roll_eyes:

Well, that work around was already detailed in the original post.

Honestly - I have readen everything, but somehow that statement not caught my attention. Sorry for that. :pensive: