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

Expose the lightmap shadow value to scripting using a raycast #2198

Open
cenullum opened this issue Jan 28, 2021 · 7 comments
Open

Expose the lightmap shadow value to scripting using a raycast #2198

cenullum opened this issue Jan 28, 2021 · 7 comments

Comments

@cenullum
Copy link

cenullum commented Jan 28, 2021

Describe the project you are working on

I want to work on Thief clone

Describe the problem or limitation you are having in your project

Main feature of Thief clone, detecting whether is player on shadow is not possible in Godot or I couldn't find the way

You can see what I try to achieve at 5:20 of the video https://www.youtube.com/watch?v=4Dnd4AWKT5Q

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

I know it will be unprofessional with this way to tell what I want, but I think it will be easier to understand. https://docs.unity3d.com/ScriptReference/RaycastHit-lightmapCoord.html . In Unity you can get lightmap value with raycast. It would be good to overcome the detecting is player on shadow.

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

var space_state = get_world_2d().direct_space_state
var result = space_state.intersect_ray(Vector2(0, 0), Vector2(50, 100))  
if result:
      var value= result.lightmap_value # this will be return value between 0.0 and 1.0 
      print("lightmap color",value) 
      if (value >0.5):
            print( "player on shadow and can't be detect by NPCs")

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

I wish I could workaround but description of bakedlightmap isn't don't yet, so I didn't find a way to do the feature with current state.
https://docs.godotengine.org/en/stable/classes/class_bakedlightmapdata.html#class-bakedlightmapdata

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

I think it should be part of the core because it is very useful for basic of stealth games.

@Calinou
Copy link
Member

Calinou commented Jan 28, 2021

There are many ways to achieve Thief-like light sensors without relying on rendering-specific stuff or baked lightmaps. For instance, you could perform a raycast from every light in range and use this to compute a "lightness" value at the player position. This can be done with both DirectionalLights and OmniLights.

For SpotLights, you'll also have to add a dot product check (Vector3.dot()) to make sure the player is actually in the spotlight's angle radius.

@Calinou Calinou changed the title Lightmap shadow value with using a raycast Expose the lightmap shadow value to scripting using a raycast Jan 28, 2021
@Zireael07
Copy link

Thief and Deus Ex used a "light/dark" value baked into the map structure, just FYI (the lighting was static) - my most recent project happens to be Deus Ex based although no light/dark support yet

@cenullum
Copy link
Author

It came to my mind to measure the value of all lights, at least the dynamic ones but I was thinking of bake the static ones so maybe this kind of feature would be helpful. Frankly, I don't know how good it is to loop for all lights every second, maybe I can just loop the near ones for performance or maybe this is not even necessary.

@Calinou
Copy link
Member

Calinou commented Jan 28, 2021

Frankly, I don't know how good it is to loop for all lights every second, maybe I can just loop the near ones for performance or maybe this is not even necessary.

Individual raycasts aren't that expensive. Just make sure to use a Timer node to not perform it too frequently, and exclude lights which aren't in the player's range (with the exception of DirectionalLight which always uses a fixed "angle" for its shadow).

@atirut-w
Copy link

you could perform a raycast from every light in range and use this to compute a "lightness" value at the player position. This can be done with both DirectionalLights and OmniLights.

This will probably be difficult to match the actual lighting, I think

@Zireael07
Copy link

I'm back to poking around that DX-1 like game, and the solution I will be going with (as the game will feature dynamic day/night system) will be based on raycasts. This shouldn't be difficult to match with actual lighting unless the lighting is doing something super weird.

Hint: https://stackoverflow.com/questions/46767188/detect-if-object3d-is-receiving-shadows-r86

@Zireael07
Copy link

Proof of concept of raycast use: Zireael07/Stealth-fps@106ac5f

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

No branches or pull requests

4 participants