Legacy GM Multiple Lighting not working

T

TLeM0

Guest
Hi!
I have been recently trying on doing a FPS test on a 3D room with multiple lights inside. I placed about 20 lights in the room, but when I launch the game, only 1 light works and all the the other walls that were supposed to be lit, aren't.

Here is are some information from objects that include code for lighting:

Code:
Information about object: obj
Sprite: sprite0
Solid: false
Visible: true
Depth: 0
Persistent: false
Parent:
Children:
Mask:

No Physics Object
Create Event:

execute code:

d3d_start();
d3d_set_lighting(true)
d3d_set_hidden(true)
d3d_set_perspective(true)
d3d_set_shading(true)
d3d_set_culling(false)

zdir = 0

display_mouse_set(display_get_width()/2,display_get_height()/2)

Step Event:

execute code:

speed = 0;

if keyboard_check(ord("W")){speed = 8}
if keyboard_check(ord("A")){x += lengthdir_x(8,direction+90) y += lengthdir_y(8,direction+90)}
if keyboard_check(ord("S")){speed = -6}
if keyboard_check(ord("D")){x += lengthdir_x(8,direction-90) y += lengthdir_y(8,direction-90)}

Draw Event:

execute code:

draw_set_color(c_white)

direction -= (display_mouse_get_x()-(display_get_width()/2))/10
zdir -= (display_mouse_get_y()-(display_get_height()/2))/4

display_mouse_set(display_get_width()/2,display_get_height()/2)

var camx, camy, camz;

camx = x+lengthdir_x(100,direction)
camy = y+lengthdir_y(100,direction)
camz = zdir

d3d_set_projection(x,y,100,camx,camy,camz,0,0,1)
Code:
Information about object: object4
Sprite: sprite4
Solid: false
Visible: true
Depth: -2
Persistent: false
Parent:
Children:
Mask:

No Physics Object
Draw Event:

execute code:

d3d_light_define_point(1, x,y,1,2000,c_white)
d3d_light_enable(1, true)
I'm looking forward to solutions!
 
Last edited by a moderator:

BLang

Member
Did you apply any shaders? How are your lights set up? Also, I'm pretty sure that GMS has a hard limit on how many lights you can have (8, I think?).
 
T

TLeM0

Guest
Did you apply any shaders? How are your lights set up? Also, I'm pretty sure that GMS has a hard limit on how many lights you can have (8, I think?).
No, I did not apply any shaders, and yeah 8 is the max amount of lights. Idk why, but is there any alternative?
 

BLang

Member
You have two choices, the way I see it.
  1. Use 8 lights, but make it seem like there's more of them - disable all lights and enable only the closest eight lights.
  2. Write your own lighting shader which supports more lights, or see if there's something you can use on the marketplace. Maybe even check out the old GMC archives.
 
T

TLeM0

Guest
You have two choices, the way I see it.
  1. Use 8 lights, but make it seem like there's more of them - disable all lights and enable only the closest eight lights.
  2. Write your own lighting shader which supports more lights, or see if there's something you can use on the marketplace. Maybe even check out the old GMC archives.
How about that shading option? I never used shaders and I'd like to learn something from creating this shader for multiple lights.
 
T

TLeM0

Guest
Another problem I have is when I step out of the room, the walls are straight black. I did assign my light to the player now, but it seems that light works only on one side of a wall. How can I fix this?
 

Yal

🐧 *penguin noises*
GMC Elder
I'd recommend only enabling the 8 closest lights, it's pretty simple to set up (don't forget point_distance_3d()) and you'd generally not need 8 lights at a time in the first place.

Walls are only lit at the 'front' side, so if you want the backside lit as well, you need to add a backside manually by creating a wall facing the other direction a bit behind the normal wall. Or make your walls very narrow blocks instead of completely flat walls.
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
How about that shading option? I never used shaders and I'd like to learn something from creating this shader for multiple lights.
There were a couple of shaders on the old forums, like this one.
Built-in lighting is the standard DirectX lighting system, which is noticeably point-based and not really good by nowadays standards. I'd strongly suggest using anything else instead.
 
I

icuurd12b42

Guest
I assume object4 is the light

the depth is -2. are you sure it's deeper than the rest of the object that will draw with the light ON? those light_define and light_enabled need to be set before any 3d drawing... so it should be crazy deep like you camera should be.

camera (the set projection code) should be at depth
1000000
and the lights at depth
100000

second, you are using 1 as light ID. if you want more they need to have light id 2,3,4,5 up to 8 as id.

3rd, you can only use 8 3d lights at a time. you can have smart code to find the nearest 8 light instances and define 3d light at the beginning of the draw of your light enabled objects...

find nearest 8 instance of light_obj
enable 8 3d light from the instances found
draw model
disable the 3d lights

4th, what Yellow said above...
 
T

TLeM0

Guest
I'd recommend only enabling the 8 closest lights, it's pretty simple to set up (don't forget point_distance_3d()) and you'd generally not need 8 lights at a time in the first place.

Walls are only lit at the 'front' side, so if you want the backside lit as well, you need to add a backside manually by creating a wall facing the other direction a bit behind the normal wall. Or make your walls very narrow blocks instead of completely flat walls.
Well since everyone has been telling me to do this thing, I'll give it a try. BUT, I have no idea how to. I am sorry, but I never got into 3D so much, but I'd appreciate it very much if someone like gave me the code and run me trough it, or just give a tutorial that includes this. TY very much so far.
 

Yal

🐧 *penguin noises*
GMC Elder
Something like this?
Code:
    var c, ap;
    ap = ds_priority_create()
    with(parent_lightsource){
        ds_priority_add(ap,id,point_distance(x,y,parent_camera.x,parent_camera.y))
    }
    for(c = 0;c < min(8,ds_priority_size(ap));c += 1){
        with(ds_priority_find_min(ap)){
            if(directional){
                d3d_light_define_direction(c,dx,dy,dz,color)
            }
            else{
                d3d_light_define_point(c,x,y,litez,r,color)
            }
        }
        ds_priority_delete_min(ap)
        d3d_light_enable(c,true)
    }
    for(c = c/*Yup, continue from that value*/;c < 8;c += 1){
        d3d_light_enable(c,false)
    }
    ds_priority_destroy(ap)
 
Top