• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Legacy GM Any tips/coding structures on getting lighting going?

X

XirmiX

Guest
I've benn hitting myself over the head with all of this lighting system mash. I checked out a few engines, looked at tutorials explaining how lighting and shadows work and how to implement them in the game, but nothing that could really help me get things working. What I have right now is complete garbage of no shadows and a broken light, which is drawn once by a light casting object (on a surface), but when moved/rotated or whatnot, the object doesn't move the light around. At the time, I didn't even know what kind of lighting system I really wanted for the game and for all I know, what I think would be a really good lighting system for my game now might not be what I want the game to stick to and that looks great. I've made 2 threads about this before, but the best I got was some suggestions using light engines. I don't know why, but I feel reluctant to use them, probably because I don't know their functionalities, it would take long to understand them and it's all in the end very restrictive.

So, what now? I really need to get the lighting system implemented in order to move on in the game's development as light and dark will be core features of the game. The following is a way of how I currently think I would like the lighting system to work and a mention of something important in terms of how lighting will interact with the player:

* I need a way to have light rays as well as light specs to work on objects to create shadows.
* I need shadows to cast from light sources as necessary, with the shadows becoming quite blurry the farther away they are from a light source
* This needs to work with multiple light sources

* Light and dark casted on surfaces will have an effect on player, so the methods used in order to cast light and shadows need for the program to get input from when the player is touching light or not or touching darkness or not. Similarly to this (the above 3 points I cannot get going even though I understand the fundamental logic they go by in my head. This point I can probably do on my own after light and shadows are put in place and working as necessary, I'm simply pointing out that I need this point to be achievable with the light and shadows that are casted):

I have a large portion of the movement working in the game as necessary and I could do it without much struggle. This however, I cannot find a solution on my own :(
 
F

Facet

Guest
Find "simple lighting" or "fake light" over this forum, here a lot of threads. Also on marketplace few free, simple and good assets. In GM many lighting solutions, some more advanced, but simple lighting will be enough and very good for your needs. I can't see shadow system on this video, if you need it, this will be more challenge. For effect like this surface or/and blend mode based lighting will be enough.

Here is article how to https://zackbellgames.com/2015/01/19/simple-lighting-surfaces/ with some tweaks you can use it in project like on video.

This thread can be good start https://forum.yoyogames.com/index.php?threads/fake-light.213/
 
X

XirmiX

Guest
Here is article how to https://zackbellgames.com/2015/01/19/simple-lighting-surfaces/ with some tweaks you can use it in project like on video.
Wow, that basic lighting system really helped! And it really made me understand lighting and surfaces a bit better, thank you! Although now I would really want to get into adding shadows, after which it's light and shadow blurring and finally light and shadow affecting player character. So, if you or anyone else can help me get to understand this in some way, that would be much appreciated. It's unbelievable how I made some decent progress in just about an hours time for my game with this :eek:

EDIT: The former fake light tutorial seems to be interesting as well, however for blur effect it creates dozens of dim light objects in order to simulate blur... this can be a problem in terms of rendering, especially in my game where lights will be plentiful, with the possibility of online multiplayer, so I'll need a better method than simply spawning a bunch of dim lights to create the illusion of a light emitting object having blurry light on the edges.
 
Last edited by a moderator:
F

Facet

Guest
With blurred or soft edges light you have to use mask with gradient. For torch - torch like shaped. Shadows is other matter. If I can suggest, stay on game without shadows. Game from your sample video not using it as I see and looks good. Creating good shadow engine need more code and skill than creating whole game sometimes. You can use ready solution, but here always some problems and it still need a lot of knowledge.

Here another fake light sample https://forum.yoyogames.com/index.php?threads/fake-light.213/ I should post it first, just can't found before.

Advanced light engine I use is here https://marketplace.yoyogames.com/assets/225/glare-engine-2d-illumination however probably I will not use it in my game. Game looks better, but performance issues in open world, more instances game type. And I will stay rather on simple/fake lighting with some special effects.
 
X

XirmiX

Guest
@Facet once again, thank you, although I'm not too keen on light engines and such at least at the moment. I actually started grasping basic shadows and whatnot thanks to these two tutorials:

I'm nearly at the point where the shadows are working, just a glitch where the collision boxes are not detected, strangely. And I will need shadows for my game, the game trailer presented didn't really use shadows, but for my game they're kind of important.

As for blur/soft edges/fade, perhaps a shadow could work... although this isn't being applied to all of the screen... Hmm, it seems like the blur for lights and shadows might be tricky. I thought of a logic that could go something like this, say for a spheric light:

if (or possibly while) light radius is more than 50%, decrease alpha for the next pixel layer.

This kind of logic should keep away all of the dozen light circles created for one object, while still applying blur. The question is now, how do I apply it in code?

Oh, and finally, I believe I mentioned this in a comment on the first video on shadows I linked: how would I go about having light erase itself when hitting a collision box? So, instead of, say, a circle of light going through and erasing parts of the darkness surface I've created across the whole level when touching collision boxes, the light itself gets cut where necessary, in a sense. If this explanation doesn't make sense, let me know and I could perhaps draw out some sketch examples of how I want it and don't want it to be, so you get a clearer picture of that.
 
X

XirmiX

Guest
A little question in terms of surfaces: how do put a surface lower down to a layer than some other objects are at? Because creating a new surface and drawing it on application surface will render the surface above everything else and when working with shadows, I need the shadows to be behind everything instead of in-front.
 

c023-DeV

Member
A little question in terms of surfaces: how do put a surface lower down to a layer than some other objects are at? Because creating a new surface and drawing it on application surface will render the surface above everything else and when working with shadows, I need the shadows to be behind everything instead of in-front.
Think of the surface as a virtual sprite. It can be drawn at the depth of the object that is drawing it. If you just want to draw a surface containing the shadows then place your surface draw code in an object that has the required depth. (First the code to draw on the surface and then you draw the surface like you would draw a sprite but with: draw_surface(id,x,y); (or draw_surface_ext(...) if you want to draw it less opaque).
 
X

XirmiX

Guest
Think of the surface as a virtual sprite. It can be drawn at the depth of the object that is drawing it. If you just want to draw a surface containing the shadows then place your surface draw code in an object that has the required depth. (First the code to draw on the surface and then you draw the surface like you would draw a sprite but with: draw_surface(id,x,y); (or draw_surface_ext(...) if you want to draw it less opaque).
Well, emm... the code is set up so that:
There is a shadow object that contains the code. The shadow object is parented to a wall object, so the wall object object essentially runs the code. Within this code, shadows are created. The surface itself is created in another object (I'll refer to it as shadow surface object), but putting this shadow surface object down some layers (e.g. down to 10 depth) doesn't render the shadows behind the wall objects (which have the depth of 0, the default value).

It might be easier for me to do this once I have got the shadow object to render shadows through being coded correctly and parented to light source objects and not the wall objects (which I'm too having trouble with, actually, so I'll present this as the next thing to deal with after this), but this still seems weird that it doesn't work as needed when I've checked all the things involved in surface creation and the shadows drawn on it.

In case none of that made much sense, here's a summary: the object that creates the surface has the depth of 10, but the object that draws shadows onto this surface has the depth of 0 and it is also the object on which the shadows are drawn on top of, whilst I want the shadows to be drawn behind it instead (this object being the wall object).

--------------------------------------------------------------------------------------------------------------------------

Currently, the code doesn't create any shadows and makes the walls invisible for some reason. The following is the current code with which I am trying to make what was shown in the videos listed in this topic, but with light objects holding onto all of the checking and drawing codes instead of the wall objects:

obj_shadowSystem_new Create event:
/// shadow variables
shON = true; // this variable enables and disables the shadow system.
lightRad = 300;
pl = obj_collisionbox;

thisX = x;
thisY = y;
thisXOld = 0;
thisYOld = 0;

plX = pl.x;
plY = pl.y;
plXOld = 0;
plYOld = 0;

// First border Line

direct1Mod = 0;
direct2Mod = 0;

trace1 = true;
trace2 = true;
trace3 = true;
trace4 = true;

extender = 600; // extra shadow space for close lighting

point3X = 0;
point3Y = 0;
point4X = 0;
point4Y = 0;

point1X = 0;
point1Y = 0;
point2X = 0;
point2Y = 0;


mover1 = 0;
mover2 = 0;

obj_shadowSystem_new Step event:
/// draw_shadows
plX = pl.x;
plY = pl.y;
thisX = x;
thisY = y;


if (shON = true) {
if (point_distance(x,y,plX,plY) < lightRad) {inLight = true;}
else {inLight = false;}

if (inLight == true) {
if (trace1 == true ) {
direct1 = point_direction(x,y,plX,plY) + direct1Mod;
point1X = x + lengthdir_x(lightRad + extender,direct1);
point1Y = y + lengthdir_y(lightRad + extender,direct1);
direct1Mod+=0.1 ;
if (!collision_line(point1X,point1Y,plX,plY,pl,true,false)) {trace1 = false;}
}
if (trace1 == false && trace3 == true) {
point3X = x + lengthdir_x(mover1,direct1-0.1);
point3Y = y + lengthdir_y(mover1,direct1-0.1);
mover1 += 0.1;
if (collision_circle(point3X,point3Y,1.1,pl,true,false)) {trace3 = false;}
}

if (trace2 == true ) {
direct2 = point_direction(x,y,plX,plY) + direct2Mod;
point2X = x + lengthdir_x(lightRad + extender,direct2);
point2Y = y + lengthdir_y(lightRad + extender,direct2);
direct2Mod-=0.1;
if (!collision_line(point2X,point2Y,plX,plY,pl,true,false)) {trace2 = false;}
}
if (trace2 == false && trace4 == true) {
point4X = x + lengthdir_x(mover2,direct2+0.1);
point4Y = y + lengthdir_y(mover2,direct2+0.1);
mover2 += 0.1;
if (collision_circle(point4X,point4Y,1.1,pl,true,false)) {trace4 = false;}
}
}

if (plXOld != x || plYOld != y) {
trace1 = true;
trace2 = true;
trace3 = true;
trace4 = true;
mover1 = 0;
mover2 = 0;
direct1Mod = 0;
direct2Mod = 0;
plXOld = x;
plYOld = y;
}
}

obj_shadowSystem_new Draw event:
if (point_distance(plX,plY,x,y) < lightRad) {

draw_line(plX,plY,point1X,point1Y);
draw_line(plX,plY,point2X,point2Y);
draw_line(point1X,point1Y,point2X,point2Y);

draw_circle(point1X,point1Y,5,0);
draw_circle(point2X,point2Y,5,0);

draw_circle(point3X,point3Y,5,0);
draw_circle(point4X,point4Y,5,0);

surface_set_target(global.shadows);

draw_triangle_colour(point1X,point1Y,point2X,point2Y,point3X,point3Y,c_black,c_black,c_black,0);
draw_triangle_colour(point2X,point2Y,point3X,point3Y,point4X,point4Y,c_black,c_black,c_black,0);

surface_reset_target();
}



draw_self();

draw_circle(x,y,lightRad,1);
 
Last edited by a moderator:
Top