3D Lightning: why i can lose the floor and the roof?

C

cambalinho

Guest
using the light, when i start, the light works normaly. but when i move, depending on start\end world distance, i can lose the floor and the roof.
why i can lose the floor\roof(go to black color)?
did i miss something or have to do with deph, instead only Z and Range?
 
M

Multimagyar

Guest
not too much of an information you gave people to work with but if it just goes black I going to assume that your floor and roof does not have a correct normal to work with. That being said it's hard to tell with so little information. could also be draw_set_colour is just simply being black.
 
C

cambalinho

Guest
on objWorld Draw event(Deph=0, objCamera Depth=999999):
Code:
//clear game room:
draw_set_colour(c_white);
draw_set_alpha(1);

//draw the floor:
d3d_draw_floor(0,0,0,w,h,0, background_get_texture(bkgFloor),4000/background_get_width(bkgFloor),4000/background_get_height(bkgFloor));

//draw the roof:
d3d_draw_floor(w,h,500,0,0,500, background_get_texture(bkgAbove),4000/background_get_width(bkgAbove),4000/background_get_height(bkgAbove));
light on objCamera Step event:
Code:
lightrange=2500;
zlight=30;
d3d_light_enable(0,false);
d3d_light_define_point(0, objCamera.x, objCamera.y, zlight, lightrange,c_white);
d3d_light_enable(0,true);
the light is done, but after some position, i will lose the floor and the roof.
but when i start, i can see the roof and floor correctly
 
M

Multimagyar

Guest
I'd need to dig into the default shader that YYG created for the purpose, but unless your floor and roof is flipping upside down, I would assume. ASSUME I'm not certain that the built in light does it's job in a per vertex basis.

note: it did not let me rest so I looked it up.

Yes the default one uses per vertex lighting which can be less expensive but also means you have to be close to a vertex point with your light to actually take effect. having a huge flat plane in the middle of nowhere with all edge faaaar faaar away will result in complete darkness. I would recommend writing a shader that does the same on per pixel level. which should not be hard and by today's standard not expensive either.
 
@Multimagyar just to be clear, we are talking about a point light here. A direction light will not have the same problem.

Yes op, you will need to write a new shader. Of course you could try breaking up the floor / ceiling into smaller parts which will mitigate the point per-vertex lighting problem to some extent.
 
C

cambalinho

Guest
for now i don't know anything about Shaders. only that we can use it for nice effects. and i don't if we can just add the effect to a sprite instead all sprites\controls.
maybe you can put me on right way

but continue with the problem: the light point can be changed for we don't lose some light?
 
Last edited by a moderator:
I don't understand the questions in your previous post.

By the way, an alternative to making your own shader could be to break up the floor and ceiling into smaller parts. It isn't perfect, but it should work a little better than having the entire floor and ceiling being just a single quad.
 
C

cambalinho

Guest
what you been by that?
Code:
//draw the floor:
d3d_draw_floor(0,0,0,w,h,0, background_get_texture(bkgFloor),4000/background_get_width(bkgFloor),4000/background_get_height(bkgFloor));
insted draw it at once, i must draw it more times with little size until the floor\roof size?
i was mean that i need start(for start) shaders.. i need some advices
 
M

Multimagyar

Guest
I was certain it is point light not directional... And per vertex directional light still can cause artifacts but not these kind of issues.
If you want to use the default lights that you use right now, imagine your floor made out of 4 points well defined. your light need to be close to one of the edge points to make lights in which case you would need to cut up your terrain into pieces and the more you cut it up the more accurate your light will be somehow like this
var cutup=50;
var chunkwidth=w/cutup;
var chunkheight=h/cutup;
for (var i=0; i<cutup; i+=1)
{
for (var j=0; j<cutup; j+=1)
{
d3d_draw_floor(chunkwidth*i,chunkheight*j,0,chunkwidth*(i+1),chunkheight*(j+1),0, background_get_texture(bkgFloor),4000/background_get_width(bkgFloor),4000/background_get_height(bkgFloor));
}
}
Something like this should make the desired effect more visible however. it going to kill some performace as you are drawing 50*50 primitive.

I recommend looking into vertex buffers. Mostly if you are going to move onto GMS2 at somepoint primitives like d3d_draw_floor will not exists.
 
C

cambalinho

Guest
uses very CPU(it's slow). i use that 'for' for the floor and roof. if i use it for all sprites(like big walls), i will 'kill' my CPU :(
what you can advice more?

anotherthing that i don't understand: why 50? what means?
 
M

Multimagyar

Guest
indeed it does. you are calling 50*50*2 drawing calls that's 500 draw calls of primitives per second. with vertex buffers for instance if you put them in 2 fields you would have a static model you could draw 2 times instead of 500

as I said you could make the floor out of triangles for a vertex buffer or if you don't want to get into buffers you have to get into shaders and make a shader that works with per pixel meaning the light will work, and the floor/roof will require less imaginary point to work with. best would be the combination of two.

Fortunately there is quite a few example of shaders out there for lights in Game Maker that you could use and handling vertex buffers are not that hard.
Unfortunately or fortunately because gives you more power, in Game Maker you kind of have to work your way from the ground up for a 3D thing.

50 is a random number I choose could be just 2 3 - 103123235

I'm not sure which rout you would want to go down.

but for buffers you have a few functions to keep in mind fortunately for that you just have to open the GML documentation and look under vertex_ functions. They also have a bit of example for that.
not sure how much help you will need with that.

if it's too difficult to understand there might be something like a d3d_model_create function with d3d_model_floor and roof functions to add to the model and you would have to do it only once and then just draw it still reducing the draw calls from 500 to 2? that would result in similar faster appearance with same results. I'm not sure since there d3d_ functions has been removed in GMS2.
 
C

cambalinho

Guest
using your idea, i changed it:
Code:
var width=w/500+1;
var height=h/500+1
var chunkwidth=w/width;
var chunkheight=h/height;
for (var i=0; i<width; i+=1)
{
    for (var j=0; j<height; j+=1)
    {
        if chunkheight*(j+1)>h then break;
        d3d_draw_floor(chunkwidth*i,chunkheight*j,0,chunkwidth*(i+1),chunkheight*(j+1),0, background_get_texture(bkgFloor),500/background_get_width(bkgFloor) ,500/background_get_height(bkgFloor));
    }
    if chunkwidth*(i+1)>w then break;
}
these code seems to work. so i did the same for the big walls:
i use 3D transformations for X, and Y
Code:
d3d_transform_set_identity();
d3d_transform_add_rotation_z(0);
d3d_transform_add_translation(x,y+15,0);
var width=w/500+1; //the light range is 500(for test and play)
var height=w/500+1;
var chunkwidth=w/width;
var chunkheight=h/height;
for (var i=0; i<width; i+=1)
{
    for (var j=0; j<height; j+=1)
    {
        if chunkheight*(j+1)>h then break;
        d3d_draw_wall(chunkwidth*(i+1),chunkheight*(j+1),500, chunkwidth*i,chunkheight*j,0, background_get_texture(bkgWall),500/background_get_width(bkgWall)+1 ,500/background_get_height(bkgWall)+1);
    }
    if chunkwidth*(i+1)>w then break;
}
d3d_transform_set_identity();
but i see some problems:
https://imgur.com/a/McpHK
on image you can see the parts of the wall and their distances.
but uses much more less CPU. in time i will fix the problems.
thanks for all
 
If I were you, I'd put everything (that isn't going to move) into a static vertex buffer. That way, you don't need to recalculate it all every frame. Just calculate it once and done. It will draw super fast, even if there are quite a lot of primitives.
 
C

cambalinho

Guest
the Vertex Drawing Texture don't works with Light(i'm testing that now)
 

Bunelee

Member
I'm having a similar issue... I want to know how to light the floor. It's appearing properly, but in my ambient light colour. What do I do? I tried flipping the Z1 and Z2 values but nothing happened...
The room has only one light (moonlight) coming from the moon object drawing a moon model (textured ellipsoid) at a high Z value. From that same Z value the light is shining. Please help...
 
Top