Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix shadows for billboarded Sprite3D's #72638

Merged
merged 1 commit into from
Feb 13, 2024

Conversation

ecmjohnson
Copy link
Contributor

@ecmjohnson ecmjohnson commented Feb 2, 2023

This resolves #69026 and resolves #41420 in the master branch based on my reading of @clayjohn's suggested approach: the "main" camera transform is piped into the shader and the billboard always faces that transform, even when rendering shadow passes. I tested with both forward and mobile rendering backends.

fixed_billboard_sprite_shadows_small

The main_cam_inv_view_matrix needed is added to struct SceneData since it seemed like "scene data" and there might be a future case for using it elsewhere in the shader. If it would make more sense for a conditional uniform to be used (like for other material features), I can change that.

@ecmjohnson ecmjohnson requested a review from a team as a code owner February 2, 2023 23:54
@Calinou Calinou added this to the 4.0 milestone Feb 3, 2023
@ecmjohnson ecmjohnson force-pushed the billboard_sprite_shadows branch from ded7a81 to 1790355 Compare February 3, 2023 01:01
@ecmjohnson
Copy link
Contributor Author

Sorry, my mistake; I see the page on code style now and I'll set up my format checker

@clayjohn clayjohn modified the milestones: 4.0, 4.1 Feb 6, 2023
Copy link
Member

@clayjohn clayjohn left a comment

Choose a reason for hiding this comment

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

This looks great!

I am unsure about the naming of the new builtin so I would like to discuss this with other rendering contributors as soon as we are back to merging new features/ enhancements. Accordingly I am bumping this to the 4.1 milestone

@ecmjohnson ecmjohnson force-pushed the billboard_sprite_shadows branch from 1790355 to 87d4172 Compare March 7, 2023 20:36
@ecmjohnson ecmjohnson force-pushed the billboard_sprite_shadows branch from 87d4172 to 3d99715 Compare April 12, 2023 23:45
@clayjohn clayjohn modified the milestones: 4.1, 4.2 Jun 8, 2023
@clayjohn clayjohn added enhancement and removed bug labels Jun 8, 2023
@ecmjohnson ecmjohnson changed the title Improve shadows for billboarded Sprite3D's Fix shadows for billboarded Sprite3D's Jun 12, 2023
@ecmjohnson ecmjohnson force-pushed the billboard_sprite_shadows branch from 3d99715 to 91eb0ca Compare June 12, 2023 23:01
@ecmjohnson
Copy link
Contributor Author

ecmjohnson commented Jun 12, 2023

@clayjohn I think this is more of a bug than an enhancement since the shadows will be incorrect for billboarded Sprite3D's without this change. Currently the only way to accomplish billboarded Sprite3D's with shadows is by employing a workaround

@Zain-A-Abbas

This comment was marked as off-topic.

@AThousandShips
Copy link
Member

@ZainWD Please don't bump PRs without contributing significant new information. Use the 👍 reaction button on the first post instead.

@clayjohn clayjohn added bug and removed enhancement labels Jul 28, 2023
@BastiaanOlij
Copy link
Contributor

I don't think this is a good solution. If you're making a 2 player game with side by side screen (yeah people still make those), or if you have additional viewports for other reasons, you'll have two different camera that both show the billboard in a different way, but only for one shadows will be correct.

Billboard is a technique that doesn't work well with shadows. If you're using it for LOD purposes, a billboard is only used when the object is far enough away that a shadow doesn't matter.

If you're using it for something like a name above a player or a healthbar, than it just can't cast a shadow. In this case the object should not be billboarded in the shader but you should orient it in code.

@ecmjohnson ecmjohnson force-pushed the billboard_sprite_shadows branch from 91eb0ca to d08bebe Compare July 28, 2023 11:37
@ecmjohnson
Copy link
Contributor Author

@BastiaanOlij You're totally correct that this wouldn't make sense in any scenario with multiple cameras in the scene. I'd add to your example stereo rendering, where the shadows would be generated based on billboarding to the e.g. left camera and be slightly incorrect for the other eye. I also agree with you that most uses of billboards should not use shadows and will not benefit from this change, but this use case can simple disable shadows.

However, I disagree that this makes this solution not worth having. As is, a beginner trying to create a single camera sprite game with 3D lighting (a la Octopath Traveler or Cult of the Lamb) will have to rotate the sprites in software themselves. I think this use case should work as intuitively out-of-the-box to avoid hurting a beginner who simply wants their Sprite3Ds to cast shadows. More advanced users making a two-player or stereo game should have the wherewithal to identify the problem when their shadows are weird from one perspective.

@Calinou
Copy link
Member

Calinou commented Jul 28, 2023

I think this change makes sense, but the class reference must be modified to mention that this approach won't work in multi-viewport or XR scenarios. In this case, the only workaround I know is to render multiple Sprite3Ds with different layers (and changing each viewport's visible layers accordingly).

@ecmjohnson
Copy link
Contributor Author

@Calinou That would be a separate PR in the docs repo eh? I'll look into updating the Sprite3D documentation to clarify this behaviour

@BastiaanOlij
Copy link
Contributor

In VR we always use quads that are properly positioned and aren't view aligned so there is stability in orientation regardless of the player turning their heads.

@Calinou
Copy link
Member

Calinou commented Jul 28, 2023

@Calinou That would be a separate PR in the docs repo eh? I'll look into updating the Sprite3D documentation to clarify this behaviour

Class reference changes should be done in doc/Classes/Sprite3D.xml in this PR, not in godot-docs.

That said, a separate PR for the 3D lights and shadows page on godot-docs is welcome.

@ecmjohnson ecmjohnson force-pushed the billboard_sprite_shadows branch 2 times, most recently from 75fd218 to 709b4cb Compare September 4, 2023 15:16
@ecmjohnson ecmjohnson requested a review from a team as a code owner September 4, 2023 15:16
@ecmjohnson
Copy link
Contributor Author

Sorry for the delay in such a simple change: it's currently summer in Canada. I changed docs/classes/BaseMaterial3D.xml to include an additional note reading:

			[b]Note:[/b] When billboarding is enabled and the material also casts shadows, billboards will face [b]the[/b] camera in the scene when rendering shadows. In scenes with multiple cameras, the intended shadow cannot be determined and this will result in undefined behaviour. See [url=https://github.com/godotengine/godot/pull/72638]GitHub Pull Request #72638[/url] for details.

I linked this PR since that could help a developer if they wanted to determine for which camera the shadow would be rendered (e.g. always wanting the shadow to be from a specific camera even with multiple cameras in the scene), but in most cases I would expect the billboards enabled and shadows enabled combination of settings to be a mistake when multiple cameras are used (e.g. couch co-op).

@ecmjohnson ecmjohnson force-pushed the billboard_sprite_shadows branch from 709b4cb to 86d64e9 Compare September 5, 2023 01:22
@ecmjohnson
Copy link
Contributor Author

I also added the same note under docs/classes/SpriteBase3D.xml since that seems to be the one that shows in the editor when modifying the Sprite3D instance

@clayjohn clayjohn modified the milestones: 4.2, 4.3 Oct 25, 2023
@ecmjohnson
Copy link
Contributor Author

It might be worth refactoring RenderForwardClustered::_render_shadow_pass() and RenderForwardClustered::_render_shadow_append() to take a struct parameter since the number of individual parameters is getting pretty nasty and this is a common point of extensibility for new features or bug fixes. I know this PR makes it one worse 😳 but I've noticed because I've had to manually rebase a couple times now

@ecmjohnson ecmjohnson force-pushed the billboard_sprite_shadows branch 2 times, most recently from e99c837 to 3e7e295 Compare December 10, 2023 19:50
@ecmjohnson
Copy link
Contributor Author

I also missed making this fix to the compatibility rendering backend so I've added those now and verified the 3D billboarded sprites shadows on all rendering backends

Copy link
Member

@clayjohn clayjohn left a comment

Choose a reason for hiding this comment

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

Sorry for taking such a long time to review this. It took awhile to discuss with other contributors and then I kept poking at it and dropping it again.

Overall, I think the implementation looks great. I don't think there is a better way to implement this and I think you have done everything correctly.

doc/classes/BaseMaterial3D.xml Outdated Show resolved Hide resolved
doc/classes/SpriteBase3D.xml Outdated Show resolved Hide resolved
@akien-mga
Copy link
Member

akien-mga commented Feb 12, 2024

While fixing the couple spelling issues in the docs, I would suggest rebasing on latest master to make sure it still builds fine after the last few weeks of active development on the rendering architecture.

Edit: Done myself.

@akien-mga akien-mga force-pushed the billboard_sprite_shadows branch from 3e7e295 to eab9569 Compare February 13, 2024 09:36
@akien-mga akien-mga merged commit ccd1fa2 into godotengine:master Feb 13, 2024
15 checks passed
@akien-mga
Copy link
Member

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
7 participants