• 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!

Fps lowering with only one light

inertias

Member
Hey everyone, so I was looking at this tutorial to make a lighting system:
I got it working, but am having an issue with the fps dropping dramatically.

Only spawning one light cuts my fps in half (60 down to 30). Here is the code:

2 objects, 1 called obj_surface_light and obj_lightsource

in obj_surface_light:

create event
Code:
depth = -100;
light_surf = surface_create(room_width, room_height);
step event
Code:
if (surface_exists(light_surf))
{   
    surface_set_target(light_surf);
    draw_clear(c_black);
    with (obj_lightsource) //take control of light source object
    {
        
        gpu_set_blendmode (bm_zero);
        draw_sprite_ext(spr_lightmap, 0, x, y, x_radius, y_radius, 0, c_black, 1);
        gpu_set_blendmode(bm_zero);
        draw_sprite_ext(spr_lightmap, 0, x, y, x_radius, y_radius, 0, c_orange, 0.1);
        gpu_set_blendmode(bm_normal);
    }
    surface_reset_target();
    draw_surface_ext(light_surf, 0, 0, 1, 1, 0, c_white, 0.8);
}

else {light_surf = surface_create(room_width, room_height)}
the obj_lightsource just has x_radius and y_radius set to 2 in the create event.

So yeah, was wondering if anyone can spot where there are performance issues with this. Thanks!
 
G

guyinboots

Guest
Surfaces can lag you out I think if their the size of a really big room. Check how big your room is and try to make the surface only the size of the actual screen :D,
 
The surface should be the size of your view port. When drawing to it, you'll want to set a view and projection equal to your "view".

Additionally, don't set the blendmode inside of the with statement.
 

inertias

Member
The surface should be the size of your view port. When drawing to it, you'll want to set a view and projection equal to your "view".

Additionally, don't set the blendmode inside of the with statement.
So i'm a bit confused as to how this is supposed to work. If I make the surface the size of the view, it's not actually following the view, so if I move my player outside the view I won't have my lighting effects follow me. How can I make the surface move with my camera view?

Also, for those talking about room size, yeah I realized this will be an issue. What I wrote above is asking about that. I actually added a "draw_clear_alpha(c_black, 1);" line under the "draw_clear(c_black);" and it seems to have improved the fps back to 60 without any noticeable differences to the light effect. Maybe this is a proper solution?
 

Relic

Member
The only proper solution is one where you understand the cause of the problem and then enact a solution to fix the problem.

I don’t know why that extra line would improve anything- I would have assumed it would make it worse (even more draw code=slower FPS)

If you do run in to the issue again, you draw the surface at the view coordinates of the camera, not the room.
 

inertias

Member
The only proper solution is one where you understand the cause of the problem and then enact a solution to fix the problem.

I don’t know why that extra line would improve anything- I would have assumed it would make it worse (even more draw code=slower FPS)

If you do run in to the issue again, you draw the surface at the view coordinates of the camera, not the room.
You're right, I think I spoke too soon. I'm not entirely sure what was causing the slowdown in the first place, but this just goes to show I need to learn more about this stuff before jumping in. :)

Thanks for the help.
 
Large surfaces are awful for rendering. You'll need to draw the surface just a little larger than your viewport, then have your lights offset and drawn onto the surface. This is how I handle lighting in my game after running into a similar issue.
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
So i'm a bit confused as to how this is supposed to work. If I make the surface the size of the view, it's not actually following the view, so if I move my player outside the view I won't have my lighting effects follow me. How can I make the surface move with my camera view?
You draw the surface at the VIEW position, and then in the code that draws to the surface you subtract the view x/y positions, so:

Code:
var _xoff = camera_get_view_x(view_camera[0]);
var _yoff = camera_get_view_y(view_camera[0]);
surface_set_target(surf);
draw_sprite(sprite_index, image_index, x - _xoff, y - _yoff);
surface_reset_target();
This will ensure that everything draws to the surface correctly, while keeping the size of the surface to a minimum.
 
Top