Jump to content


Photo

3D Point Light Dynamic Shadows


  • Please log in to reply
37 replies to this topic

#1 Davve

Davve

    GMC Member

  • GMC Member
  • 4091 posts
  • Version:GM:Studio

Posted 21 January 2014 - 08:35 PM

Point light dynamic shadows

91580726.png

 
Download demo .exe and source

Features:

  • Add colored point lights (shines in all directions unlike single directional lights)
  • Objects will cast realistic shadows, the darkness of shadows can be changed
  • Shadows are updated in real time
  • The code supports any number of lights, without taking up more RAM

Issues:
 
Speed. A majority of the code is done in the fragment shaders and thus the FPS drops drastically when jumping from 3 to 4 lights (or earlier depending on your computer). The number of triangles on-screen also affects this, as the scene has to be redrawn 7 times per light + 1.

 

Artifacts/"shadow acne". All the papers I've found about this suggests using a fixed "bias" when comparing floating point values to avoid artifacts, but there doesn't seem to be a perfect balance. A higher bias (currently at 0.02) removes the acne, but objects will start to "hover".
As much as I'd love to increase the smoothness of the shadows, it too greatly contributes to this problem (amount of samples & sample distance).
 
Left: The table appears to be floating (it's at Z=0), and artifacts can be seen on the ceiling.
Right: Weird patters on the wall when a light is close to it.
24091856.png


Edited by Davve, 11 December 2015 - 09:56 PM.

  • 18

#2 slojanko

slojanko

    HARD GAMER

  • GMC Member
  • 588 posts
  • Version:GM:Studio

Posted 21 January 2014 - 08:56 PM

So, I'm a bit confused right now, This looks nice and all, but what happened to the previous 3D shadows topic?


  • 0

Games in progress:

The unexpected: [--------------------]

My examples on YYG sandbox

My games on GameJolt

 


#3 Davve

Davve

    GMC Member

  • GMC Member
  • 4091 posts
  • Version:GM:Studio

Posted 21 January 2014 - 09:01 PM

So, I'm a bit confused right now, This looks nice and all, but what happened to the previous 3D shadows topic?

Not sure, some other guy also reported about disappearing topics.


  • 0

#4 MishMash

MishMash

    GMC Member

  • GMC Member
  • 1124 posts
  • Version:GM:Studio

Posted 21 January 2014 - 09:32 PM

This is looking really good! Speed isn't bad at all! however there isn't all that much in the scene. The quality of the shadows is also really nice, and yeah I do notice that "peter panning" effect (hovering), but this is looking nice! The main thing that hammered my shader was just draw calls, and even though I only drew 2 projections, having a scene with 10k polys got relatively slow quite fast.

Also in your demo, the text alone halves my Fps. When i hold the mouse button, I'm getting 700 fps with 4 lights, without it held, getting around 380 fps. (real).

One thing i really like is how the smooth shading turned out :)!

Good Job! 

On another note, When I did my shader, I kind of just whacked stuff together, as the tutorial I was following wasn't working, Somehow I ended up getting it to work without even using a bias, I also never experienced any shadow acne or hovering, not sure why though. Also, wtf happened to my topic xD?


Edited by MishMash, 21 January 2014 - 09:35 PM.

  • 4

VitalitySig18thMar.png


#5 slojanko

slojanko

    HARD GAMER

  • GMC Member
  • 588 posts
  • Version:GM:Studio

Posted 21 January 2014 - 09:34 PM

I would really like to see at least 30 fps on my pc with this project, but right now I'm getting up to 5. 


  • 0

Games in progress:

The unexpected: [--------------------]

My examples on YYG sandbox

My games on GameJolt

 


#6 Braffolk

Braffolk

    Lumenus Team

  • GMC Member
  • 1010 posts
  • Version:GM:Studio

Posted 21 January 2014 - 11:07 PM

Awesome! Now what about 2D? :D


  • 0

xOVkpik.png

Custom sprite framework(GML): http://gmc.yoyogames...howtopic=669935

My main project ^o^ 2Volution GMC | GameJolt


#7 darthjaiz

darthjaiz

    GMC Member

  • GMC Member
  • 45 posts
  • Version:GM:Studio

Posted 22 January 2014 - 01:34 AM

 

 

 Also, wtf happened to my topic xD?

 

Yep WTF happened there.

I may be the last that posted on that topic, it might be me, but I doubt because I posted my comment and saw it on the page after refreshing.


  • 0

2qw3ecy.jpg Circus King! Try It on Google Play


#8 xygthop3

xygthop3

    You may know me from such forums as "Shaders"

  • GMC Member
  • 3367 posts
  • Version:GM:Studio

Posted 22 January 2014 - 01:55 AM

C'mon guys lets not get this topic off track so fast,Davve has done a great job with this shader so lest keep the comments on topic.

 

It might be worth your time investigating dual paraboloid shadow mapping techniques to use in this shader as it only requires 2 camera projections for each shadow map rather than the 6 you're using now, this will allow for a speed increase.

 

Other than that the shader is looking really nice and works how it should, but with any forward rendering technique it will be slow the more lights you use.

 

A way for users to over come this, I'll make reference to a recent indie game called "The Stanley Parable". If you pay close attention the the level design you'll notice that the rooms containing shadows only allow for a single light in the room as the shadow caster, there might be multiple light sources in the room but always one caster. This gives a more then reasonable effect to the player and only noticeable if you're looking for it.

 

I think I'll be spending a lot of time going over this shader :D Nice work!


Edited by xygthop3, 22 January 2014 - 01:56 AM.

  • 2

#9 MishMash

MishMash

    GMC Member

  • GMC Member
  • 1124 posts
  • Version:GM:Studio

Posted 22 January 2014 - 11:13 AM

Yeah, being realistic, Most scenarios, even In Real life only have one clear source of shadow casting light, because when you have multiple lights in a room, the effects of the shadows often get cancelled out by other lights. An idea could be having the option to define a light as casting or not, and  then other lights cut that other lights shadow, rather than cast their own.

It could also be cool to have a system in which the closest light to the player becomes the shadow caster, This would need to be done well however, to ensure that moving between rooms, there is a decent transition between which light is casting shadows.

 

Question, Do you have a secondary shading system for the lighting (even if shadows weren't being cast), or is the smooth shading on the objects just a result of the shadows?


  • 0

VitalitySig18thMar.png


#10 Davve

Davve

    GMC Member

  • GMC Member
  • 4091 posts
  • Version:GM:Studio

Posted 22 January 2014 - 01:45 PM

It might be worth your time investigating dual paraboloid shadow mapping techniques to use in this shader as it only requires 2 camera projections for each shadow map rather than the 6 you're using now, this will allow for a speed increase.

Sounds interesting, as the amount of redraws is the biggest cause of the lag.
 

A way for users to over come this, I'll make reference to a recent indie game called "The Stanley Parable". If you pay close attention the the level design you'll notice that the rooms containing shadows only allow for a single light in the room as the shadow caster, there might be multiple light sources in the room but always one caster. This gives a more then reasonable effect to the player and only noticeable if you're looking for it.

The problem with shaders at this point is that you can only do a fixed number of iterations (at least from what I've tried), so you'll still have to redraw the scene for every light, even though they don't cast shadows, rather than just sending all of them to a shader as uniform and doing a for loop.So the redraw rate will be 7*C+N+1 where C=amount of lights that cast shadows, N=amount of "fake" lights that only lit up the scene. I'll experiment a bit with this though.
 

Question, Do you have a secondary shading system for the lighting (even if shadows weren't being cast), or is the smooth shading on the objects just a result of the shadows?

There's two shaders: shdr_shadows3D_shadowmap just stores the depth, and the other one does everything else, including figuring out what shadowmap a pixel belongs to for the current light and calculate the shadow with PCF.
  • 0

#11 Misu

Misu

    Awesometasticness!

  • GMC Member
  • 691 posts
  • Version:GM:Studio

Posted 08 June 2014 - 02:06 PM

So I was trying to add the shadow example to my game (Ive used it in another game and worked very fine) but now,
there is this wierd bug I encountered (also seen on my other game file when I open it). The bug seems to be casting a shadow out from
no where. Take a look at the image below.

b485c04dd682f93f49d1f753a22572af.png

I dunno why it does this but I tried to extract most of my contents and resources from the file to find the source of the bug (this is
my special way of locating a problem and it usually helps me a lot), and this is what I found out:

a6c8283c111da47387a8c10877991941.png

It seems the light is casting its own shadow...? I have no model set up for this and I have it done exactly like in the example file and 
yet this is casting its own shadow.

So I was wondering if there is a solution to this but I can't seem to bust my head on this one. Can someone help me?


Edited by Misu, 08 June 2014 - 02:20 PM.

  • 0

#12 Davve

Davve

    GMC Member

  • GMC Member
  • 4091 posts
  • Version:GM:Studio

Posted 08 June 2014 - 07:51 PM

So I was wondering if there is a solution to this but I can't seem to bust my head on this one. Can someone help me?

It looks like one of the depthmaps failed to render, does it work in my demo? Try reducing the depth/shadowmap size.


  • 0

#13 Misu

Misu

    Awesometasticness!

  • GMC Member
  • 691 posts
  • Version:GM:Studio

Posted 08 June 2014 - 10:31 PM

I tried already tried changing the shadow map value and the problem still persist. Also it appears on your example as well:

082d8f6d95ea361ff5ccb82f8c1715be.png


Edited by Misu, 08 June 2014 - 10:32 PM.

  • 0

#14 Davve

Davve

    GMC Member

  • GMC Member
  • 4091 posts
  • Version:GM:Studio

Posted 09 June 2014 - 09:05 AM

I tried already tried changing the shadow map value and the problem still persist. Also it appears on your example as well:

 

It's probably something with your graphics card, try updating your drivers.


  • 0

#15 Insolitus

Insolitus

    GMC Member

  • New Member
  • 6 posts
  • Version:GM:Studio

Posted 02 July 2014 - 02:59 PM

This is great and I was able to get it working in my game really quick. However it would be nice if you could make it work with 2D textures that have clear backgrounds as the game I'm working on mainly uses sprites...

 

testscreen.png


  • 0

#16 slojanko

slojanko

    HARD GAMER

  • GMC Member
  • 588 posts
  • Version:GM:Studio

Posted 09 July 2014 - 09:43 PM

I'm getting an error when updating GM:S

"Unbalanced surface stack. You MUST use surface_reset_target() for each set."


  • 0

Games in progress:

The unexpected: [--------------------]

My examples on YYG sandbox

My games on GameJolt

 


#17 Davve

Davve

    GMC Member

  • GMC Member
  • 4091 posts
  • Version:GM:Studio

Posted 09 July 2014 - 09:49 PM

I'm getting an error when updating GM:S

"Unbalanced surface stack. You MUST use surface_reset_target() for each set."

What GM version? The .gmz in the download should work in v1.3.1354.


  • 0

#18 slojanko

slojanko

    HARD GAMER

  • GMC Member
  • 588 posts
  • Version:GM:Studio

Posted 09 July 2014 - 10:01 PM

I'm using 1.3.1347. Downloaded it again and still error.


  • 0

Games in progress:

The unexpected: [--------------------]

My examples on YYG sandbox

My games on GameJolt

 


#19 Davve

Davve

    GMC Member

  • GMC Member
  • 4091 posts
  • Version:GM:Studio

Posted 09 July 2014 - 10:08 PM

I'm using 1.3.1347. Downloaded it again and still error.

I assume you get the error in the shadows3D_draw script? Make sure it has a surface_reset_target() after every surface_set_target(), if not, you're using an old version of this.


  • 0

#20 rshoel

rshoel

    GMC Member

  • GMC Member
  • 108 posts
  • Version:GM:Studio

Posted 19 November 2014 - 10:36 AM

I tried it through the source and with the .exe, it worked find wile I tried it with the .exe but when I tried to test it in gm:s all shadows and light got drawn on the screen.


  • 0

#21 DJ Coco

DJ Coco

    GMC Member

  • GMC Member
  • 131 posts
  • Version:GM:Studio

Posted 02 January 2015 - 11:27 PM

Sorry for the bump, but I can't get it set up - once I start 3D I call two scripts, one that initiates everything and once that places the light. In the draw event of the same object I call the drawing script and pass a script that calls all user-defined events containing the draw codes. All, I'm getting, however, is this:

Spoiler

I don't think that's how it's supposed to look like. What am I missing here? I keep checking your demo to see where I've gone wrong, but I can't find the issue.


Edited by DJ Coco, 02 January 2015 - 11:28 PM.

  • 0

RyZz54p.png


#22 chreechokash007

chreechokash007

    GMC Member

  • GMC Member
  • 230 posts
  • Version:GM:Studio

Posted 15 February 2015 - 05:54 AM

Looks like the shape of the light is like a trianglefan. How can i change it?  I tried implementing it in my fps 3d project and the light only shows either ceiling or floor as per the adjustment. If i move the light source upward it shows the ceiling and the floor vanishes and when i shift it downward then vice versa. How can i make the light to show both floor and ceiling? Do i need to make two light sources for that? Please help me.


  • 0

#23 Davve

Davve

    GMC Member

  • GMC Member
  • 4091 posts
  • Version:GM:Studio

Posted 15 February 2015 - 11:15 AM

Looks like the shape of the light is like a trianglefan. How can i change it?  I tried implementing it in my fps 3d project and the light only shows either ceiling or floor as per the adjustment. If i move the light source upward it shows the ceiling and the floor vanishes and when i shift it downward then vice versa. How can i make the light to show both floor and ceiling? Do i need to make two light sources for that? Please help me.

The light should shine in all directions, if it doesn't then it's either a hardware issue or you've implemented it incorrectly.


  • 0

#24 coNNecTT01

coNNecTT01

    GMC Member

  • GMC Member
  • 297 posts
  • Version:GM:Studio

Posted 15 May 2015 - 07:57 PM

This shadow engine is perfect. I don't know if it's been abandoned, but I have 3 simple questions if anyone could answer them:

1. Where do I draw stuff without the shadows? I've tried putting my draw code everywhere and even though it doesn't make sense, it doesn't draw it. I'm not sure why I can't render other 3D stuff over the drawn surface. (I have always been making only 2D games, so I might be missing something here)

 

2. Is it possible to make transparent parts of a texture not cast shadows? ("d3d_draw_floor()" to be exact)

 

3. Why do I have a black screen after game start until I do room_restart()?

 

Thanks in advance!

 

EDIT: Nevermind.


Edited by coNNecTT01, 16 May 2015 - 04:28 PM.

  • 0

#25 raisins

raisins

    GMC Member

  • GMC Member
  • 349 posts
  • Version:GM:Studio

Posted 23 May 2015 - 11:27 PM

Hi davve, I found a problem with the shader. There's this almost vignette dark shade of gray surrounding every point of light in the map and I suspect it's a product of the shdr_shadows3D_shadowmap shader. I made an illustration below, what can I do to achieve the ideal picture below?

 

Also, the dark shade is a problem because it makes the environment look darker.

 

2ZzS117.png

 

This problem also exist in your original example:

5FVrTxo.png

 

Thanks.


Edited by raisins, 23 May 2015 - 11:41 PM.

  • 0

fxYmZ6o.png

 

Visit my blog for GM tutorials and more! Ask.fm me a question! :D

 

kWb6ZYf.png  Vd9fN4l.png


#26 Davve

Davve

    GMC Member

  • GMC Member
  • 4091 posts
  • Version:GM:Studio

Posted 24 May 2015 - 02:02 PM

Hi davve, I found a problem with the shader. There's this almost vignette dark shade of gray surrounding every point of light in the map and I suspect it's a product of the shdr_shadows3D_shadowmap shader. I made an illustration below, what can I do to achieve the ideal picture below?

 

Also, the dark shade is a problem because it makes the environment look darker.

 

This problem also exist in your original example:

 

 

Thanks.

It's mostly got to do with the attenuation factor of the light, pixels further away get dimmer according to the light range. The crappy filtering could also be to blame.

I've made some optimizations to the code since this was released, I might update the file in the first post.


Edited by Davve, 24 May 2015 - 02:09 PM.

  • 1

#27 programmmer5

programmmer5

    GMC Member

  • GMC Member
  • 395 posts
  • Version:GM:Studio

Posted 04 July 2015 - 06:06 PM

Hey, this is great!

but just a few questions.

 

is there a way to add the shadows to an object and its draw event, than to draw everything in the "draw_stuff" script?

so i want to apply the shadows to different objects without using the "draw_stuff" script.

 

also about static shadows, would it make things faster if you could make some shadows static (like shadows casted by walls and static objects)

and others like the players shadow dynamic?


  • 0

Kidnapped Treasure [Jam 13]

xulg.png

WIP: Space Chase (3D)GMC jam 9 

Space Chase 3D for Android < Click it!

 


#28 Davve

Davve

    GMC Member

  • GMC Member
  • 4091 posts
  • Version:GM:Studio

Posted 04 July 2015 - 06:13 PM

is there a way to add the shadows to an object and its draw event, than to draw everything in the "draw_stuff" script?
so i want to apply the shadows to different objects without using the "draw_stuff" script.


You can use a with loop in the draw_stuff script to call either a drawing script or fire a custom event for each object, like...
 

with (someObject)
   draw_me()

Where draw_me contains the code that would usually be in the draw event.
 

also about static shadows, would it make things faster if you could make some shadows static (like shadows casted by walls and static objects)
and others like the players shadow dynamic?


If the light doesn't move it is probably possible to render nearby static objects first to a separate depth buffer (on game start), and then use that buffer in some clever ways when the game runs and you're only checking with dynamic objects. Haven't tried it though.


  • 0

#29 programmmer5

programmmer5

    GMC Member

  • GMC Member
  • 395 posts
  • Version:GM:Studio

Posted 04 July 2015 - 07:58 PM

 

is there a way to add the shadows to an object and its draw event, than to draw everything in the "draw_stuff" script?
so i want to apply the shadows to different objects without using the "draw_stuff" script.


You can use a with loop in the draw_stuff script to call either a drawing script or fire a custom event for each object, like...
 

with (someObject)
   draw_me()

Where draw_me contains the code that would usually be in the draw event.

 

sorry, thats not what i ment, is there a way to eliminate that script entirely?

so i could place objects in a room normaly with the shader still being applied?

 

also one more thing, is there a way to change the opacity or strength of the shadows?

the faces of my models that are facing away from the light are completely black.


  • 0

Kidnapped Treasure [Jam 13]

xulg.png

WIP: Space Chase (3D)GMC jam 9 

Space Chase 3D for Android < Click it!

 


#30 Davve

Davve

    GMC Member

  • GMC Member
  • 4091 posts
  • Version:GM:Studio

Posted 04 July 2015 - 09:40 PM

sorry, thats not what i ment, is there a way to eliminate that script entirely?

so i could place objects in a room normaly with the shader still being applied?

 

also one more thing, is there a way to change the opacity or strength of the shadows?

the faces of my models that are facing away from the light are completely black.

 

Since the scene is redrawn multiple times per light, a script is required.
You can increase the ambient level to get lighter shadows.


  • 0

#31 Colnusca

Colnusca

    GMC Member

  • GMC Member
  • 462 posts
  • Version:GM:Studio

Posted 28 July 2015 - 04:09 AM

Is this still functional? I might use it but since I'm taking a DOOM approach to my game (monsters and players are 2D Graphics because Game Maker doesn't support 3D animated models, and I suck and making 3D models ;-;) I wonder if it will cast a shadow correctly. Probably not. The enemies and players are just flat planes that always face the camera, drawing the monster on the plane, and don't draw transparency. (this is my goal, i haven't even done it yet). Will it cast the shadow of the whole plane, or just the rendered part (the part where the sprite is opaque or not 0% opacity)?


  • 0

I'll help any way I can ^.^


#32 orange451

orange451

    GMC Member

  • GMC Member
  • 1411 posts
  • Version:GM8.1

Posted 28 July 2015 - 07:48 AM

Game Maker doesn't support 3D animated models

 

It sure does!


  • 0

bC14QqN.pngNrTFeil.png


#33 Davve

Davve

    GMC Member

  • GMC Member
  • 4091 posts
  • Version:GM:Studio

Posted 28 July 2015 - 09:19 AM

Will it cast the shadow of the whole plane, or just the rendered part (the part where the sprite is opaque or not 0% opacity)?

 

I doubt the current code works with transparent textures, but the depth shader can easily be adjusted to ignore pixels below an alpha threshold.


  • 0

#34 Colnusca

Colnusca

    GMC Member

  • GMC Member
  • 462 posts
  • Version:GM:Studio

Posted 28 July 2015 - 01:30 PM

 

Game Maker doesn't support 3D animated models

 

It sure does!

 

Yeah, if each frame is a totally different model, or you save models by primitives :P

 

 

Will it cast the shadow of the whole plane, or just the rendered part (the part where the sprite is opaque or not 0% opacity)?

 

I doubt the current code works with transparent textures, but the depth shader can easily be adjusted to ignore pixels below an alpha threshold.

 

Talking to me with shader terminology is useless, I barely understand them. I know the difference between the fragment and vertex and that's about it. I suck at OpenGL ES xD

 

EDIT: I just went through some great shader tutorials for 2D and a few for 3D, and now suck slightly less with them! I understand tons more now!


Edited by Colnusca, 28 July 2015 - 02:55 PM.

  • 0

I'll help any way I can ^.^


#35 orange451

orange451

    GMC Member

  • GMC Member
  • 1411 posts
  • Version:GM8.1

Posted 29 July 2015 - 03:22 AM

Yeah, if each frame is a totally different model, or you save models by primitive

 

 

 

This is untrue! You can load animated models with Game Maker :)

 

Shaders have allowed Game Maker to be close to on-par with other game engines out there.


  • 1

bC14QqN.pngNrTFeil.png


#36 Colnusca

Colnusca

    GMC Member

  • GMC Member
  • 462 posts
  • Version:GM:Studio

Posted 29 July 2015 - 01:24 PM

 

Yeah, if each frame is a totally different model, or you save models by primitive

 

 

 

This is untrue! You can load animated models with Game Maker :)

 

Shaders have allowed Game Maker to be close to on-par with other game engines out there.

 

Thanks for that! I'll probably buy it tomorrow or later today and try it out, maybe make some models :D


  • 0

I'll help any way I can ^.^


#37 Colnusca

Colnusca

    GMC Member

  • GMC Member
  • 462 posts
  • Version:GM:Studio

Posted 30 July 2015 - 06:11 AM

This shader looks great, but the light seems to be casting a shadow of itself?

 

Also, how would one draw stuff without putting everything in a draw_scene script? I already have so much being drawn that I would have to move it all. I did already once, but the screen was fully black no matter what, so I moved it all back, and disabled the scripts.


Edited by Colnusca, 30 July 2015 - 06:51 AM.

  • 0

I'll help any way I can ^.^


#38 JimmyBegg

JimmyBegg

    GMC Member

  • GMC Member
  • 111 posts
  • Version:GM:Studio

Posted 08 March 2016 - 10:09 AM

Finally got specular and normal mapping working ^_^
 
Great shader Dave :thumbsup:
 
specnorm.PNG


Edited by JimmyBegg, 08 March 2016 - 10:10 AM.

  • 3

logoleapgmsig.pngparacs.png