godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.12k stars 69 forks source link

Allow specifying a non-zero start radius for SpotLight3D (resulting in cylindrical lights) #2520

Open Calinou opened 3 years ago

Calinou commented 3 years ago

Related to https://github.com/godotengine/godot-proposals/issues/1275.

Describe the project you are working on

The Godot editor :slightly_smiling_face:

Describe the problem or limitation you are having in your project

SpotLights currently must have a conic shape, which makes them too limited to imitate DirectionalLight3Ds that are constrained to a specific area of a level.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Cylindrical lights (spot lights whose "start radius" is equal to the "end radius") can be used as a localized DirectionalLight3D.

Since SpotLight3D shadows are much cheaper to render than DirectionalLight3D shadows, this can improve performance in indoor levels and closed areas while avoiding potential issues with GI light leaks.

Being able to specify a start radius also makes it possible to fake area lights in a more convincing manner.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Add a start_radius property (defaulting to 0) that specifies how wide the "circle" at the start of the SpotLight should be. If start_radius is equal to the end radius (which is determined by the light's spot angle and range), then the spot light effectively becomes cylindrical and acts like a localized DirectionalLight3D.

If this enhancement will not be used often, can it be worked around with a few lines of script?

No. While OmniLight3Ds and even SpotLight3Ds can be used to achieve this kind of "localized" DirectionalLight3D effect, light and shadow rendering will look incorrect unless the light is placed really far away. This greatly lowers the effective shadow resolution. OmniLight3Ds also have to render cubemap (or dual parabolid) shadow maps, which are more expensive than SpotLight3D shadows since they only have to render one face.

Is there a reason why this should be core and not an add-on in the asset library?

See above.

Keywords for easier searching: cylinder

alexfreyre commented 3 years ago

Can get this type of light a square shape and a square specular lobe?

Calinou commented 3 years ago

Can get this type of light a square shape and a square specular lobe?

That's probably quite different to implement, so I doubt it.

golddotasksquestions commented 3 years ago

Yes please! This proposal is exactly what I would have needed when I was making the blob shadow for the main character in this demo. I can think of a million other cases where it would be useful.

Calinou commented 3 years ago

Yes please! This proposal is exactly what I would have needed when I was making the blob shadow for the main character in this demo. I can think of a million other cases where it would be useful.

For blob shadows, you should use Decal nodes (new in master) instead of negative lights. This gives you more control over the shadow's size and normal fade, while putting less strain on the renderer. Decal nodes can be moved every frame just fine, since they don't rely on mesh generation to be rendered.

Cylindrical lights are most suited when you have a directional light coming through a window – for instance, an attic exposed to sunlight/moonlight in an otherwise fully indoor scene.

golddotasksquestions commented 3 years ago

For blob shadows, you should use Decal nodes (new in master) instead of negative lights. This gives you more control over the shadow's size and normal fade, while putting less strain on the renderer. Decal nodes can be moved every frame just fine, since they don't rely on mesh generation to be rendered.

Yes, decals would have been my first choice and I'm really looking forward to the 4.0 decals. The decal solutions available for Godot 3 did not work for me in this demo, regardless of what I tried. This was really just one example where an alternative like this would be awesome. But I can think of many more situations where non-zero start angle for lights would be great. Moving the lights way out of bounds and then having to struggle with tons of cull masks and light layers which all have to be turned on and off in certain conditions is really not fun.

jitspoe commented 6 months ago

Oops, didn't notice this when I proposed https://github.com/godotengine/godot-proposals/issues/9157 so I'll just copy/paste it for reference:

Describe the project you are working on

Quake-like retro fps.

Describe the problem or limitation you are having in your project

Some spotlights are kind of large and I want the cone to start wider than a single point. For example, here's a top-down view of a light partially submerged in water: image Note that the cone starts in front of the light, but looks a little weird not matching up with the texture. It should be wider at the start.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

A simple parameter on the SpotLight3D to set the offset so that the light could start sooner, but with a near clipping plane so the world geometry does not cast shadows from INSIDE the light fixture, so it would look like this: image

(Note: I was able to move the lights back in this case, but sometimes model geometry will cast shadows, preventing that solution).

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

image Here there would just be a new parameter like "Start Offset", in meters.


I think this might be slightly different, though, or maybe it's just a terminology thing? Like regardless of the angle, the start is still going to be a single point. Wouldn't a cylindrical light be an angle of 0 with a starting radius?

On the topic of spot lights used like directional lights, I have a case where I'm using a very large spot light that's almost a directional light, and it would be nice if I could specify a separate texture for it instead of using the atlas so it's not so chunky. Any proposals to have special non-atlased lights?

Calinou commented 6 months ago

Wouldn't a cylindrical light be an angle of 0 with a starting radius?

That's a spotlight, which is how it works currently :slightly_smiling_face:

A cylindrical light is a light whose start and end angle are identical.

and it would be nice if I could specify a separate texture for it instead of using the atlas so it's not so chunky. Any proposals to have special non-atlased lights?

The way the shadow atlas works doesn't make this possible. However, there could be a way to force specific lights to use a given shadow quadrant, which can be used to increase the shadow detail of certain lights: https://github.com/godotengine/godot-proposals/issues/840

jitspoe commented 6 months ago

I think there's some disconnect here... spotlights have the same angle all the way through:

image

A cylinder would have an angle of 0 degrees + a radius. image

Calinou commented 6 months ago

I think there's some disconnect here... spotlights have the same angle all the way through:

By "angle", I meant the radius of the circle rather than the angle of the light being emitted. I've adjusted the proposal's title and description to make this more clear.

ben-rolfe commented 1 month ago

I just want to add that this would be especially useful for moving lights (e.g. flashlights and car headlights). I'm currently working on a car game and it looks really silly when you drive up to a wall and the headlights become pinpoints - My only available workaround seems to be to embed the lights in the body of the car, and that causes its own problems.