Paper 2d sprites, top-down camera--how to get shadows consistent with 3d space? 4-26

I’m newish to UE4 and trying to make a 2.5D sprite-based game somewhat in the style of Octopath Traveler–but from a more top-down perspective.

I’m struggling with getting the shadows and lighting on sprites to “work” in this perspective. It’s a bit complex, so I’ve included photos and descriptions–apologies for the length.

In Octopath, the camera view is from the side, maybe rotated 10 degrees or so above the ground plane itself. With this side-view perspective, sprites can be placed at their default rotation–perpendicular to the ground plane–and both sprites and their shadows look and behave as you would expect them to if they were 3D objects. A direction Light Source at a reasonable “sunlight” angle casts correct shadows from sprites. The shadows cast by the sprite look and behave in the same way you’d expect them to when compared to 3D objects in the same space. Example:

However, for a top-down perspective, the camera has to be at a higher angle (somewhere between 45 degrees and 90 degrees, that is, aimed directly at the ground plane). I find something like 55 degrees is appropriate and gives it that old school “Zelda” top-down look. However, if you leave the sprites at their default rotation with this camera angle, the sprite looks visually “sheared”–like looking down at a thin cardboard cutout from above, which is, of course, essentially what’s happening. Example:

The obvious solution to that problem is to rotate the sprites to match the camera rotation so that they are always facing straight forward in the viewport. This avoids the shearing effect of viewing a flat sprite from the wrong angle, but creates new challenges with the engine’s lighting system. After all, as far as the 3D engine is concerned, the sprite is a 2D, paper-thin cut-out that is now “leaning” toward the ground instead of perpendicular to it, and the shadows behave accordingly. Example:

One possible solution I arrived at for THAT was to disable shadows on the visible sprite and attach a hidden, shadow-casting duplicate sprite that stands at 90 degrees to the ground in front of the visible, rotated sprite. Example:

This actually works well as long as the light comes from behind, casting the shadows in front of the sprites. But if the light source is in front of the characters (which IMO looks better), then this hidden shadow-caster sprite casts the shadow on top of the visible sprite, ruining the illusion. Example:

Is there any way to make the hidden shadow-caster sprite NOT cast a shadow on the visible sprite? Or, to let the visible sprite accept shadows from everything except the shadow-caster sprite? It doesn’t seem like this is possible, but that would probably make this workaround viable.

Ideally, I want the camera angled downward, the visible sprites angled to face the camera with no shear/distortion, the light generally will be angled from the front, and the sprite actor should cast a shadow that is visually cohesive with the shadows of other 3D objects in the space. Example (mock-up):

I’m pretty much out of ideas as to how to achieve that look. Does anyone have any?

Has anyone else made a 2.5D/HD-2D sprite-based game using a top-down camera perspective and successfully made use of Unreal’s lighting and shadow system?

Or, is this just going to be effectively impossible or unworkable and I should rethink things?

Come to think of it, maybe this is why most games I see with the HD-2D style use the same low/side-view camera angle as Octopath…

TL;DR: How do you get consistent shadows that look correct for the 3D environment using 2D sprites from a top-down camera perspective?

There is one, let the shadowcaster hover flat just a few units above the ground ^.^ And stretch and rotate it to create your desired shadow.
Something like this here, he has two shadowcasters for left and right, i just would turn off the unneeded one:

An even better approach might be to use different Lightchannels for your Mainlight (channel 0) and for a separate shadowcaster light (channel 01), and let your normal sprite react only to the main light channel, and the shadowcaster only to the shadowcaster light channel 01.
Your environment then just have to react to both light channels to get affected by the shadow created by the light with channel 01.
of course, you then have to adjust your lightintensities of your scene, so that both of the lights combined do not get to bright. But that is doable with some finetuning :slight_smile:
The big difference is, that with this method your environment reacts properly to your desired shadows.

1 Like