2D Dynamic Shadows

Ah good idea with the timer! I will try that.

You know the Lucky Luke comic character? Maybe it’s more known in Europe (where are you from?). Lucky Luke is a Western hero that can shoot faster than is own shadow :slight_smile:

Ah, I get it. I didn’t, but there was a demo for a game called that on the Archimedes a long time ago.

Ok, just checked to update the shadows 120 times a second. This would be a timer.perfomWithDelay with a delay set to 8.333, right?

(8.333 * 120 = 1000, roundabout).  But the shadows are still lagging when using transitions :( 

It’s really a shame that transition.* doesn’t offer a per-event listener.

How about a special “should this be an instant-update light” option that sets the metatable (special setting because setting the metatable results in a slower table)?

Pseudo-code (within shadows library):
[lua]
if thisLightShouldBeInstantUpdate then
local mt = getmetatable(thisLight)
local prevNewIndex = mt.__newindex
mt.__newindex = function(self, k, v)
prevNewIndex(self, k, v) – Use the original newindex function
if k == “x” or k == “y” then
self.update() – Whatever the “update this light” function is named
end
end
end
[/lua]

The above code should listen for setting of the light’s x or y value, then update the light when that happens. That way, the light will update each time it’s moved, not just on an enterFrame basis.

[lua]
light.x, light.y = 500, 500 – Bing! The light updates!
[/lua]

Of course, you probably still want the enterFrame listener to catch other objects moving.

You could expand this idea if the problem is occurring when any object moves, not just the light, and do a __newindex to update the whole scene’s light; I don’t know when this problem is happening, exactly.

Lua metatables are you friend!

  • Caleb

Thank you for your idea, Caleb. I will definitely take a look at the metatables approach. But first I have to read about Lua metatables. I does not know anything about it.

This is really great! I just tried it though and I am only averaging 13 FPS and my computer is really good. Did something change in Corona or your code? In addition, will Corona be supporting its own dynamic lighting system in the future if anyone knows?

Just compiled my code and tested in simulator and on device. But on both situations I get constantly around 60 fps (I tested level6 with the Real Attenuation feature). Have you tested on a device, too? Have you pulled from BitBucket or did you try the zip file from first post?

Anybody else with these low frame rates?

AFAIK there is no plan on Coronalabs side to implement a lighting system. 

I cloned it using Soruce Tree like you had talked about in the first post. It works perfect on my Galaxy S4 running between 40 and 50 frames a second. Just runs at 14 and drops below on my Corona client. Which is really weird.

Hi everybody,

In the Corona Geek Show #122 Charles gave me the opportunity to present the 2D shadow system. Now I updated the source code at the BitBucket repo to v1.1 which contains the latest features you can see in that Corona Geek issue.

New features are

  • Added circle shape support
  • Added support for multiple shapes per shadow caster
  • dded support for CodeAndWeb’s PhysicsEditor to create complex shapes
  • Added support for a shadow length factor. Now shadows can be longer or shorter per light source setting. (Simulates the height of the light source)
  • Shadows intensity can be changed independently from light source intensity. Per default it is the same, but if you want to make the shadows brighter without changing the appearance of the light.
  • Support for concave shapes (using multiple convex shapes)
  • Support for counter clockwise vertex shapes
  • Fixed a lense flare texture (borders were visible)
  • Some polishing to background and shadow caster objects (especially for the Corona Geek Show #122 :slight_smile:

To keep the compatibility to Coronas Starter Edition I implemented a image buffer technique. This means: drawing all shadow stuff on a white background, then capturing this greyscale image as a display object, hide all shadow polygon objects and finally drawing the captured image on to the screen. This might be a bit slower and I could imagine this way I use more texture memory. But at this I time I think it’s the only way to support multi shape objects with Corona Starter Edition.

 

Please let me know how the performance is going.
@roaminggamer Ed, maybe you could use your test scene you showed at Corona Geek (now it is officially a benchmark scene for the shadow system :lol: ) and let me know how it performs.

 

Oh, and Ed Maurina also found a way to use transition.to() and avoid the Lucky Luke (lagging shadows) problem: do not let the transition change the x and y position of the shadow caster object directly. Instead use some interim variables to do the transition to (yes you can do transitions on variables, it must not be a display object). And then update the shadow caster’s x/y position values to these interim variables in an enterFrame event for example. Good Idea! Thank you Ed.

Hm strange. Which Corona version and OS you use?

I never chimed in before the show, but this is very cool stuff!

Soft shadows seem to be a fun (but difficult!) problem, so I had to know. :) Somebody always seems to have a new-and-improved demo, in the latest graphics text, or being presented at a conference.

Version 2570 on Windows 7 x64. I’m going to use it anyway in my game, but I may move this onto my Mac to see if it acts differently. Trying to add two light sources to my game for the levels.

@Rene,

It was great to have you on the hangout and I want to say, “This library is looking really great!”  I’m out of the office today (writing on my laptop right now), but when I get a chance, I’ll download the latest version from the repository, re-create the ‘benchmark’ test I made and give an example of avoiding ‘lucky luke’.

I’ll post all that here or e-mail it to you via Charles.

Cheers!

I downloaded the repo yesterday and it appears to be missing a “util” folder and the files within it (Vector2d, Log). Build fails without those files.

@roamiggamer Thank you Ed, I’m looking forward for your example/benchmark.

@tartarsauce Thank you for the info, I will check that immediately.

Ok, the utils folder is my personal collection of Corona/Lua helpers. Since this is a BitBucket repository on its own it has not been pushed to the repo (it just gets ignored). Now I found out that you can create special nested subrepositories (very cool!) for this special case. So I added the util repo as a subrepo to the shadow system project. Now it gets properly pushed to the BitBucket server.

BUT : if you use the download button on the BitBucket website, nested repos do not get resolved. It is still missing. You have two possibilities.

  1. Do a real clone of the shadow repo with console or with a GUI tool (I’m using SourceTree). When using clone the nested repo is resolved correct.
  2. Or if you want to donwload manually, you have to go to the utils repo. Download this as well and copy it’s content into a util folder inside the 2dshadows folder.

I recommend to use the first way. It is just two or three clicks and if theres in update, you can just pull it. If you have still problems please let me know. Especially if you never used repos like BitBucket/GitHub this might be confusing at first.

So it works fine on the Mac, not entirely sure why. It could just be my laptop which is weird since it is new. But anyway, I have a question about one of your functions. When my character dies I attempt to call the light:Remove() function but it comes up with this error below. I have existing transition.cancel and timer.cancel function but they all use tags to cancel only specific timers. I’ve also tried without canceling the timers at all just in case your code cancels all active timers, but no dice. The error always occurs at 2DVector line 140. Do you know why?

I am calling the light class to just add a light. I’m not calling it through the shadow class like how you have it in your examples. Should I be calling it from the shadow class instead?

light1 = light:new( 2, {0,1,0}, 1, 4 ) light1.x = -10 light1.y = -10 light1:SetDraggable(false) sceneGroup:insert(light1)

Thanks for reading!

For convenience (and the ones that do not want to hassle with version control) I added an alternative download link in the first post.

First let me say that this light/shadow module has not been tested in a real game environment and I do expect errors if you try to implement it in a game. But I really want it to work within a game so I’m eager to solve any problems that may occur.

It seems that Corona tries to access a vector that has been removed. Also the last Method before the Vector2D:Sub Method is the UpdateLenseFlare Method. Have you tried it without any lense flares just for testing purposes?

Let me do some tests with adding/removing light at runtime to reproduce the error.

If you’re not useing the Shadow:AddLight() Method I really do not understand how this working? Or do you insert the light object manually to the Shadow.lights table? I think this does only make sense, if you don’t want to have shadows, but only lights and lense flares. I have to test this but the Shadow object is kind of a manager of the whole system.