Skip to main content

On Sale: GamesAssetsToolsTabletopComics
Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines
(3 edits)

Another thing that you may need to consider is setting static objects depth in their create event "before" event_inherited.  This is because static objects like shadow casters add their shadow depth when created to a the buffer used for casting shadows.  So, depending on your depth sorting method you would put in the create event:

depth = room_height - bbox_bottom;

event_inherited();  // After setting depth

Then for objects which change depth often you would put in their step event or where ever:

depth = room_height - bbox_bottom;

update_depth();  // Explained in the user manual

Light depth on the other hand is normalized so where the light is updated you would put:

light_id.y = new_y_value;

light_id.set_depth(room_height/new_y_value);

Or use a "with statement" or something to avoid all the extra id lookups, etc.

(2 edits)

I've set the origin of my sprites at the lowest isometric point so I don't have to use bbox_bottom I don't think.


I watched the video, I'm normalizing the depths now (in my player and solid objects):

Function calculate_depth():
depth = room_height - y + 100;

Controller Create Event
layer_depth("Instances", -1);
layer_depth("Light_Layer", 100);
layer_depth("Background", room_height + 100);

Solid Objects Step Event:
calculate_depth();

Player Create Event:
light = instance_create_layer(x, y,"Light_Layer", le_light_spot);


Player Step Event:
calculate_depth();
with(light) {
    x = other.x; y = other.y + 1;

    set_depth(y / room_height);
}

My player and the light objects unfortunately don't have the function "update_depth()"

--
I still don't understand what I'm doing wrong. I'm using set_depth() now but the light is still going under my player and above the background. The light is going under everything except the background.

I haven't touched shadows and nothing is inheriting from a shadow object yet, I'm just trying to get the light to go in the proper depth (same depth as my player but above my player).

Player depth is working fine still. I just don't understand. How do I set the light's depth? What am I doing wrong?

Did you read the manual or watch the videos?  You have to inherit from one of the light engine objects for your things like players, enemies, and other entities.  In most cases __le_game should be inherited from.  Unless of course it is a shadow caster.

(4 edits)

I did but it's a very complicated system honestly at first glance. I'm very sorry I'm trying to understand it. I don't know what objects need to inherit from what to get depth working properly, I understand depth is a recent addition you added?

I now have my player and my building objects inheriting from __le_game. I think things are starting to work a bit better.

I now have two small issues though:

- Light is emitting very strong whiteness against my players and objects that are inheriting from __le_game. I was just hoping it could brighten up the scene the way it would be drawn if there was no darkness. It's lighting up the background layer perfectly fine but the player/solid objects are turning white
--

- The light is not going behind my building now, it's always above it
--

But I'm guessing this is because I need to somehow get the le_light_spot object to inherit from __le_game as well so I can call update_depth? It's already inheriting from _le_light_cull which inherits from __light. So I tried making __light inherit from __le_game but now I get this error:
"
Variable le_light_spot.normal(101661, -2147483648) not set before reading it.

 at gml_Object___le_game_Other_25 (line 3) - draw_sprite_ext(normal_map, image_index, x, y, image_xscale, image_yscale, image_angle, normal, LE_NORMAL_ANGLE);
"

(1 edit)

Lights do not need to have inheritance setup.  I said to setup inheritance for your game objects.  Again, the user manual shows which functions a light has for setting depth.

Your objects are bright because they do not have normal maps and so they use the sprite as a default normal map that is completely flat.  So, they are like a mirror surface.  You can turn up the roughness and turn down the metallic on the object in the variable definitions tab which will help with some of that.  

Another thing is just setting the light different.  A larger radius but with lower intensity or falloff.  

Eclipse is made for PBR lighting which means you will want material and normal maps to go with your sprites.  The PBR packer that comes with it and which also has a video tutorial on it explains how you could make material and normal maps for sprites.  There are many ways to do so, and in most cases you'll want to auto generate one with a good program.

One thing to consider is that this is still a 2D lighting solution (with 3D calculated lights).  So, the isometric buildings might be difficult to get to look right with shadows.

It may seem complicated compared to some assets, but this is the most streamlined and general solution for PBR lighting in GM that there is.  Inheriting from an object for some type of rendering object is usually pretty common, and the user guide plus tutorials do show this.  The example project that comes with Eclipse also could be looked at to get a better understanding of how to set things up.

Thank you for your patience with me. Turning up roughness and down metallic didn't seem to do much unfortunately. I'll try using the PBR packer and see if it changes anything.

Regarding setting the depth, the only one I found in the guide was set_depth(_depth) (0..1) which I am already doing but the light is not going behind my buildings when the y value goes below the building's y value. I am updating the depth of my buildings using update_depth() as well. I couldn't find anywhere in the guide for setting depth other than that function and increment_depth(_increment). The light always appears to be going over everything no matter where its position is.

//Layers depth setup

layer_depth("Instances", -1);
layer_depth("Light_Layer", 100);
layer_depth("Background", room_height + 100);

//Building / Solid Object Step Event
depth = room_height - y + 100;
update_depth();

//Light Step Event
x = mouse_x; y = mouse_y;
d = y / room_height;
set_depth(d);

(+1)

I'm happy to help, so no worries.  Anyone who purchases one of my assets should certainly get all the support I can provide.

Keep things like you have it, but also on your building, put the following in the create:

shadow_depth = y / room_height;

Sorry if this adds more confusion, but there are two places where depth plays a role and it is on purpose to give designers the option of how light and objects/shadows interact separate from the regular old depth sort.  

The rest is just for information purposes:

The normal depth value which you are setting fine and then using update_depth() after is what sorts the normal and material maps during pre-composition.  Then the shadow_depth is where a lights depth is compared to the current pixel's shadow depth.  This value is stored in the material map when drawn to the surface.

Hopefully this can help illustrate things better on how Eclipse renders everything.  Here is a deferred renderer I wrote in WebGL (warning large texture loading): https://badwrongg.github.io/webgl-deferred-pbr/

On the left you can see those four areas that are each part of the G-buffer (graphics buffer).  From top to bottom they are color, normal, material, and position.  In Eclipse everything is just like this, minus the position buffer because we can cheat in 2D with just a matrix during lighting.  So, when you set the shadow_depth its writing to one of those buffers and the light compares its own depth to that.

So, Eclipse is a 3D PBR renderer, but from a 2D orthographic perspective.  The extra parts that seem complicated are there to make it work well with GameMaker's default draw calls.  In other assets for GM that try to do similar things it is actually far more complicated and you have to deal with your own vertex buffers and other things for every draw call.  Once you get the hang of the shadow, light, and depth stuff the rest shouldn't be a big problem.

Lastly, for the texture packer asset you could go and get some normal maps from just any PBR texture and use them for your sprites.  On the tool you set the clip sprite which should be the same as your regular character sprite.  This will clip the normal map to fit exactly to your sprite.  Then in GM on your object just set the normal_map to point to the normal map that matches the current sprite.  What I do is create a struct that just stores all three and adds them by having a standard naming convention.  So, if the base sprite is "spr_player_run" then it simply grabs "spr_player_run_m" for the material and "spr_player_run_n" for the normal automatically.  Cuts down a ton of extra work.

(1 edit)

Yes!! Setting the shadow depth works! Thank you! And yeah regarding the PBR packer, I watched your video on it but I'm confused.

My character for example is a large sprite sheet with over 200 frames. The sprite sheet is 1384 x 384px I dragged it into the clip window. I then clicked on normal but it's showing a 64x64 image. Same with material.

I'm honestly really new to normals and maps/etc. but basically I just want my players to not be so white when the lights are shining on them. Same with my buildings. When I have the le_day_night_cycle object in, once morning hits, the building and players are completely illuminated with pure whiteness. I just want my sprites to look like they originally do when light gets shined on them: I'm not sure what normals I'm supposed to be downloading. I tried using the online one you suggested in your video and created a normals sprite sheet from my player's sprite sheet and when I imported it into the game and set it as the normal map on my player object: the pure whiteness when the light shined on the players was still there.

What sort of light settings are you using?   Also, the light color matters too and you could use smaller values and the light will have less radiance.  Like on the light you could use set_color(make_color_rgb(80, 80, 80)); 

When you dragged the image file into the clip window, did you drop it in the bottom right?  After that drag the same image file into the material window in the albedo slot.  That's the base color for your sprite or material and in the packer it is just there to preview things.  You can tick the Lit box to see a sort of preview using Eclipse and then play with values.  Once you have that figured out you can go to places like https://freepbr.com/ and just download materials that look like they would create what you need and just use the normal map.  It will of course be a textured look and not exact to the sprites pixels.  If you want that you can generate them as I think you already found the site, or there are other programs that generate much nicer normal maps.

Unfortunately this seems to be a lot of extra work at this point just to get my sprites to look normal under this lighting engine.

At this point I don't know if it's worth it to go forward with this lighting engine. It is way more complex than I thought it was going to be. My main goal was just to have lights at certain depths in an isometric environment but now I need to download materials, normals, etc. and I can't even get that to work.

Our game is going to consist of a lot of different sprites and if I have to generate different images for every single sprite I want to look normal under the lights then I'm not sure this is a good idea.

I don't know why but on the PBR Packer program, pressing "Save" sometimes doesn't do anything, nothing gets created on my file system.