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

Lightning System goes too dark with many Instances

Well, i was trying to make a light system where i could manipulate to use on my project, so i seached for some tutorials, and then i found the Mike Dailly's tutorial.
here is part 1:https://www.yoyogames.com/blog/419/realtime-2d-lighting-in-gamemaker-studio-2-part-1
and part 2: https://www.yoyogames.com/blog/420/realtime-2d-lighting-in-gamemaker-studio-2-part-2

So i followed all instrunctions but i found a problem, the many instances of "Light" i have the darker the room was getting, and i don't know why this is happening.

the Code:
(create)
Code:
lightSurf = -1;
rad = 200;        // the radius of the light
lightAlpha = 0.5;   //alpha of the light
fixed = false;

//shader variables
LightPosRadius = shader_get_uniform(shLight,"u_fLightPositionRadius"); //possiçao radial da luz

InitShadowCasting(); //initialize the lig
(draw)
Code:
if(!surface_exists(lightSurf)){
    lightSurf = surface_create(room_width,room_height);
}

if(fixed){
    var lx = x;
    var ly = y;
}else{
    var lx = mouse_x;       // the light position, based around the mouse location
    var ly = mouse_y;
}


var startx = floor(lx-rad);
var endx = floor(lx+rad);
var starty = floor(ly-rad);
var endy = floor(ly+rad);

//surface
surface_set_target(lightSurf);
draw_clear_alpha(0,0); //clean the alpha for gou purposes

vertex_begin(VBuffer, VertexFormat); //open vertex creation

with(oWall){
    // get corners of the WALL
    var px1 = bbox_left;     // top left
    var py1 = bbox_top;
    var px2 = bbox_right;    // bottom right
    var py2 = bbox_bottom;

    if( !SignTest( px1,py1, px2,py1, lx,ly) ){
        ProjectShadow(other.VBuffer,  px1,py1, px2,py1, lx,ly );
    }
    if( !SignTest( px2,py1, px2,py2, lx,ly) ){
        ProjectShadow(other.VBuffer,  px2,py1, px2,py2, lx,ly );
    }
    if( !SignTest( px2,py2, px1,py2, lx,ly) ){
        ProjectShadow(other.VBuffer,  px2,py2, px1,py2, lx,ly );
    }
    if( !SignTest( px1,py2, px1,py1, lx,ly) ){
        ProjectShadow(other.VBuffer,  px1,py2, px1,py1, lx,ly );                  
    }
}

vertex_end(VBuffer);  //close vertex creation
vertex_submit(VBuffer,pr_trianglelist,-1); //draw the vertex

surface_reset_target();

//draw the surface with shader
shader_set(shLight);
shader_set_uniform_f( LightPosRadius, lx,ly,rad,0.0 )
draw_surface_ext(lightSurf,0,0,1,1,0,image_blend,lightAlpha);
shader_reset();

//debug arear of light
draw_set_color(c_yellow);
draw_rectangle(startx,starty, endx,endy,true);
(Script : InitShadowCasting)
Code:
/// @description init shadow casting
vertex_format_begin();
vertex_format_add_position();
vertex_format_add_color();
VertexFormat = vertex_format_end();

VBuffer = vertex_create_buffer();
(Script: ProjectShadow)
Code:
/// @description cast a shadow of this line segment from the point light
/// @param VB Vertex buffer
/// @param Ax  x1
/// @param Ay  y1
/// @param Bx  x2
/// @param By  y2
/// @param Lx  Light x
/// @param Ly  Light Y

var _vb = argument0;
var _Ax = argument1;
var _Ay = argument2;
var _Bx = argument3;
var _By = argument4;
var _Lx = argument5;
var _Ly = argument6;

// shadows are infinite - almost, just enough to go off screen
var SHADOW_LENGTH = 1100;

var Adx,Ady,Bdx,Bdy,len

// get unit length to point 1
Adx = _Ax-_Lx;  
Ady = _Ay-_Ly;  
len = (1.0*SHADOW_LENGTH)/sqrt( (Adx*Adx)+(Ady*Ady) );      // unit length scaler * Shadow length
Adx = _Ax + Adx * len;
Ady = _Ay + Ady * len;

// get unit length to point 2
Bdx = _Bx-_Lx;  
Bdy = _By-_Ly;  
len = (1.0*SHADOW_LENGTH) / sqrt( (Bdx*Bdx)+(Bdy*Bdy) );    // unit length scaler * Shadow length
Bdx = _Bx + Bdx * len;
Bdy = _By + Bdy * len;


// now build a quad
vertex_position(_vb, _Ax,_Ay);
vertex_argb(_vb, $ff000000);
vertex_position(_vb, _Bx,_By);
vertex_argb(_vb, $ff000000);
vertex_position(_vb, Adx,Ady);
vertex_argb(_vb, $ff000000);

vertex_position(_vb, _Bx,_By);
vertex_argb(_vb, $ff000000);
vertex_position(_vb, Adx,Ady);
vertex_argb(_vb, $ff000000);
vertex_position(_vb, Bdx,Bdy);
vertex_argb(_vb, $ff000000);
(Script: SignTest)
Code:
/// @description which side of a line is the point on.
/// @param Ax
/// @param Ay
/// @param Bx
/// @param By
/// @param Lx
/// @param Ly

var _Ax = argument0;
var _Ay = argument1;
var _Bx = argument2;
var _By = argument3;
var _Lx = argument4;
var _Ly = argument5;

return ((_Bx - _Ax) * (_Ly - _Ay) - (_By - _Ay) * (_Lx - _Ax));
(Shader: shLight)
Vertex
Code:
//
// Simple passthrough vertex shader
//
attribute vec3 in_Position;                  // (x,y,z)
//attribute vec3 in_Normal;                  // (x,y,z)     unused in this shader.
attribute vec4 in_Colour;                    // (r,g,b,a)
attribute vec2 in_TextureCoord;              // (u,v)

varying vec2 v_vTexcoord;
varying vec4 v_vColour;
varying vec2 v_vScreenPos;

void main()
{
    vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0);
    gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos;
  
    v_vColour = in_Colour;
    v_vTexcoord = in_TextureCoord;
    v_vScreenPos =  vec2( in_Position.x, in_Position.y );
}
Fragment
Code:
//
// Simple passthrough fragment shader
//
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
varying vec2 v_vScreenPos;

uniform vec4 u_fLightPositionRadius;        // x=lightx, y=lighty, z=light radius, w=unused


void main()
{
    // Work out vector from room location to the light
    vec2 vect = vec2( v_vScreenPos.x-u_fLightPositionRadius.x, v_vScreenPos.y-u_fLightPositionRadius.y );

    // work out the length of this vector
    float dist = sqrt(vect.x*vect.x + vect.y*vect.y);

    // if in range use the shadow texture, if not it's black.
    if( dist< u_fLightPositionRadius.z ){
        // work out the 0 to 1 value from the centre to the edge of the radius (some a luz)
        float falloff = dist/u_fLightPositionRadius.z;
      
        // get the shadow texture
         vec4 col =  texture2D( gm_BaseTexture, v_vTexcoord );
      
        if( col.a<=0.01 ){
            gl_FragColor = v_vColour;         
        }else{   
            gl_FragColor = col;
        }     
      
        // now LERP from the shadow volume shape to total shadow
        gl_FragColor = mix( gl_FragColor, vec4(0.0,0.0,0.0,0.7), falloff);  //no lugar do alpha tava 0.7(vec4)
      
    }else{
        //if out of light radious, set everything black
        gl_FragColor = vec4(0.0,0.0,0.0,0.7);
    }
  
    //change final alpha
    gl_FragColor.a *= 0.1;
}
The oWall is the shadow casters and it has no code.

OBS: Sorry for the big amount of code

Edit:
I guess i found a part of the problem, looks like that every time that i create another light instance it maker another shadow projection with vertex_position and vertex_argb, that makes the room darker, because they are one above other.
So how can i make the other projection color the same tone as the first, so they stay the same value?
 
Last edited:
Top