-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
Point/Spot light docs #6813
Point/Spot light docs #6813
Conversation
pub range: f32, | ||
/// The size (radius) of the point light itself. | ||
/// | ||
/// A radius of 0.0 (the default) is a point with no measureable size, while a radius of 1.0 is a unit sphere, etc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if it's the case in Bevy, but usually the size of the light source affects the sharpness of the shadows. The bigger the light source (keeping the light source at the same distance from the object), the softer the shadows get as they are further from the object. I mention the distance, because the sun is a huge sphere, but since it's so far that it works as a directional light giving mostly sharp shadows (?).
Might be interesting to mention?
Rendered in Blender:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are no soft shadows yet. This would be addressed by something like #3631 . When I was hacking on soft shadows using the PCSS method, I was using the light's radius for this kind of effect.
pub intensity: f32, | ||
/// How far light extends from the surface (TODO: or center?) of the point light. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// How far light extends from the surface (TODO: or center?) of the point light. | |
/// How far light extends from the center of the point light. |
pub intensity: f32, | ||
/// How far light extends from the surface (TODO: or center?) of the spot light. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// How far light extends from the surface (TODO: or center?) of the spot light. | |
/// How far light extends from the center of the spot light. |
pub range: f32, | ||
/// The size (radius) of the spot light itself. | ||
/// | ||
/// A radius of 0.0 (the default) is a point with no measureable size, while a radius of 1.0 is a unit sphere, etc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Radius 1.0 would give the cone cut from a unit sphere according to the outer angle.
The lighting mostly follows what Google's Filament renderer defines, but with a few tweaks from other places. Point and spot lights have their light falling off over distance in a physical way (proportional to 1 / distance^2). Point lights with 0 radius can technically not exist physically, so some approximations need to be applied there, also if I recall correctly for when something is inside the radius of the light. I think we followed some Brian Karis / Unreal Engine ideas for that part. It's documented in the shader code. And then we apply some additional attenuation to the light so that it smoothly fades out to 0 at its range limit rather than abruptly stopping.
As noted above, the falloff is physically-modelled and is proportional to 1 / distance^2. Distances are measured from the centre. And additional non-physical attenuation is applied close to the range in order to smoothly fade out rather than abruptly cutting off.
Correct.
The range is a property of the light, so it depends how far the point on the surface of the object is from the centre of the light.
The light range calculations use 1 / range^2 so whether range is positive or negative it will behave based on its absolute value I think. It may be that the culling of objects or clustering gets messed up with negative range. Range should not be negative and I'm not sure if we check or limit that anywhere. A quick search suggests that we don't. But range should be > 0.0. A range of 0.0 may cause some divide by 0s...
As mentioned, the radius could be used for soft shadows in the future but that is not yet supported. Radius is used for lighting however and is a feature: https://bevyengine.org/news/bevy-0-6/#spherical-area-lights
This is incorrect. >= 0.0 is the constraint I think.
I think negative radius is invalid.
Too large values will detach the shadow from where the object contacts the surface on which it is resting and make it look like the object is floating. shadow_depth_bias and shadow_normal_bias are to avoid 'shadow acne' or 'self-shadowing'. They are workarounds for a problem with shadow map resolution and depth precision with the way that shadow mapping using depth buffers works. From experience, avoiding self-shadowing with shadow mapping techniques is a major pain. The The self-shadowing problem is that the shadow map textures are depth textures of geometry in the scene from the perspective of the light. So they contain the closest point to the light for each pixel in the texture. When rendering from a camera's perspective, in order to understand if the point on the surface of some geometry in the scene that is visible to the camera is in shadow or not, that point is transformed into the light's perspective, and then its depth or distance from the light is compared with the depth in the shadow map texture to see if there is something closer to the light. If so, the point is in shadow, if not then it is the closest point along that light ray from the light to the surface and it is lit. Because of limited shadow map texture resolution and limited depth precision, there can be small differences in the two depths when the point on the surface that is visible to the camera is actually meant to be the closest point to the light and it should be lit, but where the small differences make the comparison of the two depths indicate that there is something slightly closer to the light and so that point should not be lit. The depth bias moves the point in the scene that is visible to the camera, slightly closer to the light to try to compensate for these precision problems. The normal bias moves the point slightly away from the surface along the surface's normal, for the same reason. The depth and normal biases are one of the standard approaches to dealing with these problems. Godot's documentation has a good writeup with images and I thought that we would do something similar at some point. https://docs.godotengine.org/en/stable/tutorials/3d/lights_and_shadows.html#shadow-mapping Their 'bias' is the depth bias, and their 'normal bias' is the same as our normal bias.
Right, this is self-shadowing. Too small values will exhibit self-shadowing. The defaults are meant to tradeoff avoiding self-shadowing while being as small as possible to avoid detaching the shadows from the contact points. While it could be negative, in practical terms that will just cause self-shadowing and so is never going to be what a user wants.
Again it should not be negative for practical purposes as that would cause self-shadowing which is undesirable. It should be as small as possible, >= 0.0, and enough to along with the depth bias avoid self-shadowing.
Good point, the lighting is definitely based on SI units of measure and so world units should be in metres for correct lighting.
Yes. DirectionalLight is meant to model a light that is very far away and so has practically parallel light rays in the direction of the light. Google's Filament renderer has a lot of documentation on the choices: https://google.github.io/filament/Filament.html#lighting |
Closing this PR so that we don't have to go through me to work on this, another PR will get opened instead :) |
Documents some fields of PointLight and SpotLight.
I'm unsure whether range is measured from the surface of the point/spot light, or always from the center regardless of its radius.
I'm also unsure what units range and radius are in (meters?), and how to document the rest of the fields.