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

Add a light type of entity for lighting effects #267

Open
eonarheim opened this issue Apr 22, 2014 · 12 comments
Open

Add a light type of entity for lighting effects #267

eonarheim opened this issue Apr 22, 2014 · 12 comments
Labels
feature Label applied to new feature requests

Comments

@eonarheim
Copy link
Member

eonarheim commented Apr 22, 2014

Context

It would be useful to have the ability to utilize dynamic lighting effects.

Proposal

Something like this

// x, y, radius, luminosity
var light = new ex.Light(100, 100, 10, 1);
game.currentScene.addLight(light);
@eonarheim eonarheim added this to the 0.4 Release milestone Apr 22, 2014
@jedeen jedeen modified the milestones: 0.4 Release, 0.5 Release Sep 30, 2014
@jedeen jedeen added the feature Label applied to new feature requests label Apr 30, 2015
@jedeen jedeen modified the milestones: 0.6 Release, 0.7 Release May 10, 2015
@jedeen jedeen modified the milestones: 0.7 Release, vNext May 26, 2015
@jedeen
Copy link
Member

jedeen commented Sep 12, 2017

This might be worth looking at: https://github.com/gre/illuminated.js

@github-actions
Copy link

github-actions bot commented Jul 4, 2021

This issue hasn't had any recent activity lately and is being marked as stale automatically.

@github-actions github-actions bot added the stale This issue or PR has not had any activity recently label Jul 4, 2021
@luttje
Copy link

luttje commented Jan 31, 2022

I hope you don't mind me bumping this old issue, but I'm looking for something like this. In the meantime while we wait I've got something that may help others looking to light their scenes.

I've conjured up a very cheap way to fake lighting:
image

This is the general process:

  1. Overlay the game canvas with another canvas (#lightingCanvas), match the game canvas size and position
  2. Paint the whole #lightingCanvas translucently black (this mimics darkness)
  3. Ask all objects which type of 'light mask' they emit and where. Example mask:
    spot
  4. Using globalCompositeOperation = 'destination-out' cut out the lit part from the darkness on the #lightingCanvas

Objects can register their lighting in their constructor like this:

const lightSprite = Resources.light_Spot.toSprite();
LightingManager.instance.on(LightingEventTypes.RegisteringLights, (ev) => {
  // This event handler is called everytime lighting is updated

  // Let this big light be drawn:
  ev.lightingManager.registerLight(
    new GraphicLightEmitter({
      pos: this.pos,
      graphic: lightSprite,
      scale: vec(5, 5)
    })
  );
});

I quickly made a little demo based on the platformer demo and it's custom-loader.ts shows how to light the whole screen on loading.

Of course it isn't realistic lighting at all, but for some style of pixel art it may just be enough.

I hope this helps someone.

@eonarheim
Copy link
Member Author

@luttje Wow this is very cool!

@eonarheim eonarheim removed this from the vNext milestone May 27, 2022
@Autsider666
Copy link
Contributor

Giving this old issue another bump by giving a +1 to the globalCompositeOperation = 'destination-out' method.

I've experimented with this topic a lot the past few months and I managed to get light occluding objects to work in my latest experiment. (Video of end result)

The light mask is handled using createRadialGradient, but it should work with sprites as well.

The light occlusion is handled by a field-of-view polygon build on top of this example, calculated by raycasting to every visible edge point of every light blocking object twice, each with a very small (0.000001) positive and negative offset. A lot of this process is "cached" by storing the points in the new(ish) Path2D.

I've gathered a large, chaotic list of resources about this subject, so give me a shout if it's useful if I compile it into something more useful for general usage.

@eonarheim
Copy link
Member Author

@Autsider666 Lighting effects are definitely something I want in Excalibur.

Some low hanging fruit might be to add cookbook/tutorials to the docs on how to achieve effects like your video! (Which is awesome by the way).

Some ideas I've been kicking around involve ECS style things:

  • Point light component to emulate the radial gradient effect
  • Field of view light component
  • Shader light component? For custom shader effects, I'm thinking like doing particle lighting or flickering?

Not sure if we'd have a single lighting system or multiple for each effect

I've gathered a large, chaotic list of resources about this subject, so give me a shout if it's useful if I compile it into something more useful for general usage.

Definitely send that over! It would 1000% be useful

@github-actions github-actions bot removed the stale This issue or PR has not had any activity recently label Oct 21, 2024
@dgrbrady
Copy link

Bumping this because I'd LOVE to have a built-in lighting system. I'm creating something that allows users to customize a personal room with various items. One category of item I'd like to add is lighting.

If you're taking input for possible API features, it'd be awesome to have the ability to set the light color, brightness/intensity, direction and maybe even an interval/duration specified either as a number or a function to emulate different kinds of lights such as constantly on, flickering, blinking, fading in/out, etc.

@imvenx
Copy link

imvenx commented Nov 20, 2024

we need this

@eonarheim
Copy link
Member Author

@imvenx @dgrbrady Totally agree, I'll add this to our priority for the v0.31.0

@Autsider666 has some really cool stuff he's built in excalibur we can take some inspiration from

@dgrbrady
Copy link

@imvenx @dgrbrady Totally agree, I'll add this to our priority for the v0.31.0

@Autsider666 has some really cool stuff he's built in excalibur we can take some inspiration from

MY GOAT. Thank you so much man. Just curious, what does v0.31.0 translate into timeframe wise? Is this like a within 6 months kind of thing or a year plus? Not trying to sound pushy or ungrateful, just super excited about it! I don't know much about the math side of things that would go into implementing a feature like this, but I'd love to help with any low hanging fruit.

@eonarheim
Copy link
Member Author

@dgrbrady Good question, there isn't too much more left on my pre-v1 list. Ideally we'd be able to turn around v0.31.0 < 6 months but it's all subject to contributions and life ❤️

I've put lighting on the list of graphics things #1161

I think there are probably 2 biggish things to implement:

  • Point light radial gradient
  • Raycast field of view/occulsion

@Autsider666 is implementing both here, and I think these results are what we want out of the box in Excalibur! https://github.com/user-attachments/assets/87a07ca1-5343-46ef-9410-3284a3603213

There are a few open questions I haven't worked out yet:

  • What does the ex API look like? A sketch of an API might be a good place to start
  • Do we add a darkened layer that is carved out by a point light? or do we do something additive/multiplicative?
  • What geometry do we use for raycasting? Same as colliders? Or should we have separate geometry for lighting?
  • Do we want to support fancy things like normal mapping to do interesting lighting effects in shaders?

@imvenx
Copy link

imvenx commented Nov 21, 2024

Thank you for the quick update! I just commented "we need this" yesterday and didn't expect such a prompt response. 😊

Regarding your questions, here are my humble thoughts:

Normal Mapping and Advanced Lighting Effects:

While normal mapping and advanced shader effects would greatly enhance the visual quality, if it is complicating things too much, maybe starting with basic lighting features would satisfy most users. It's important, however, to design the API with future enhancements in mind.

API Design Sketch:

Here's a rough idea of what that could look like:

const light = new ex.PointLight({
  position: ex.vec(100, 200),
  radius: 150,
  color: ex.Color.Yellow,
  intensity: 0.8,
  // Optional properties for future extensions
  // castShadows: true,
});
game.currentScene.add(light);

Lighting Techniques—Darkened Layer vs. Blending Modes:

Regarding whether to use a darkened layer that's carved out by point lights or to employ additive/multiplicative blending, I think providing options would be beneficial. An additive blending mode might work well for multiple overlapping light sources, creating a more natural lighting effect. Alternatively, a subtractive approach (darkening the scene and adding light) can create a different ambiance. Allowing developers to choose the blending mode per light or globally could make the system more versatile.

Geometry for Raycasting:

Using colliders for raycasting could be a convenient default, but I think that we shouldn't make it the only option. There are cases where you might want an object to interact with light differently than it does with physics, for example a transparent window that blocks players but lets light pass through. Introducing a separate set of "light occluder" shapes or flags that can be assigned to objects would give developers precise control over lighting interactions. This could look something like:

const sprite = new ex.Sprite({
  image: myTexture,
  lightOccluder: ex.Shape.Box(50, 200),
  // normalMap: myNormalMapTexture,
});

Considerations for Performance:

Lighting calculations can be performance-intensive, especially with dynamic lights and shadows. It might be worth considering an option for developers to toggle lighting features on a per-scene or per-object basis, or use pre-baked lighting, or a custom update interval, balancing visual effects with performance needs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Label applied to new feature requests
Projects
None yet
Development

No branches or pull requests

6 participants