TulioHenry
Member
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)
(draw)
(Script : InitShadowCasting)
(Script: ProjectShadow)
(Script: SignTest)
(Shader: shLight)
Vertex
Fragment
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?
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
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);
Code:
/// @description init shadow casting
vertex_format_begin();
vertex_format_add_position();
vertex_format_add_color();
VertexFormat = vertex_format_end();
VBuffer = vertex_create_buffer();
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);
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));
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 );
}
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;
}
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: