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

SOLVED Implementing the Day and night shader v1.2 from Gaming Reverends

R

RareDoggu

Guest
Hello, and first of all sorry if this looks like my first post, I've been here some time before with another account I can't access now somehow Raeldor.

So anyways to the subject, this month I was working on a nice looking way to implement a lighting system in my game (It doesn't need to cast real-time shadows but I liked how it looked in the Gaming Reverends day and night tutorial), and I've been trying to implement it in a mockup game before putting it on my game so far I've been successful (with some missteps on the way) but this week I've been having trouble implementing the light sources From the tutorial v1.2.

The thing is that I tried writing it myself, and even using his code from the source project. and even tried to write it in the source project myself directly from the tutorial and while in the source project it works, on mine it doesn't seem to pass the second texture to the shader.
1587227078851.png1587227096046.png1587227110168.png1587227128536.png
As you can see the surface for the lights is being set up properly (Ignore the noise its caused due to being recorded as a gif) but it doesn't blend with the day and night shader, like in his project.
1587227283052.png
Here is the main code its used in my project:
GML:
/// @descr Create event for the controller object

// BASICS:
// ----------------------------------------------------------------------------

// shader:
shader = shd_day_and_night_v1_1;
u_col = shader_get_uniform(shader, "col");
u_con_sat_brt = shader_get_uniform(shader, "con_sat_brt");

s_lights = shader_get_sampler_index(shader, "lights");
tex_lights = -1;
srf_lights = -1;

// COLOR VARS:
// ----------------------------------------------------------------------------
color_mix = -1;
color[0, 0] = undefined;

key_previous = -1;
key_next = -1;

con_sat_brt_mix = -1;

// KEY TIMES:
// ----------------------------------------------------------------------------


// arguments:       R      G       B      con     sat     brt    popS    popT

scr_add_key_time(030,    120,    225,    0.60,    1.00,  -0.20,    0.80,    0.65);    // 00h
scr_add_key_time(040,    125,    215,    0.65,    0.90,  -0.20,    0.70,    0.65);    // 02h
scr_add_key_time(080,    080,    185,    0.80,    0.60,  -0.15,    0.20,    0.80);    // 04h
scr_add_key_time(160,    145,    100,    1.20,    0.65,  -0.03,    0.00,    1.00);    // 08h
scr_add_key_time(128,    128,    128,    1.00,    1.00,    0.00,    0.00,    1.00);    // 10h
scr_add_key_time(128,    128,    128,    1.20,    0.85,    0.05,    0.00,    1.00);    // 12h
scr_add_key_time(128,    128,    128,    1.00,    1.00,    0.00,    0.00,    1.00);    // 14h
scr_add_key_time(140,    130,    120,    1.10,    0.80,    0.00,    0.00,    1.00);    // 16h
scr_add_key_time(145,    120,    090,    1.10,    0.75,    0.00,    0.00,    1.00);    // 18h
scr_add_key_time(080,    080,    185,    0.80,    0.60,  -0.15,    0.20,    0.80);    // 22h

number_of_key_times = array_height_2d(color);

// WATER REFLECTION:
// ----------------------------------------------------------------------------
var lyr_reflection = layer_get_id("Reflections");
layer_script_begin(lyr_reflection, scr_set_alpha_v1_2);
layer_script_end(lyr_reflection, scr_reset_alpha);

u_alpha = shader_get_uniform(shd_alpha, "alpha");
alpha = 0;

//RESIZE VIEW AND APPLICATION SURFACE (optional):
//-----------------------------------------------------------------------------
// don't forget to draw in a draw gui event if you dont want to scale the sprite
application_surface_draw_enable(false);
GML:
/// Step event for the controller object
/// @description mix colors / reflection alpha


// get key times:
var time = global.Daytime;

key_previous = min(floor(time * number_of_key_times), number_of_key_times-1);
key_next = ((key_previous+1) mod number_of_key_times);

// get lerp amount:
var lerp_amt = (time - key_previous/number_of_key_times) * number_of_key_times;

// mix colors:
color_mix = [lerp(color[key_previous,0], color[key_next,0], lerp_amt),
             lerp(color[key_previous,1], color[key_next,1], lerp_amt),
             lerp(color[key_previous,2], color[key_next,2], lerp_amt)];

con_sat_brt_mix =    [lerp(con_sat_brt[key_previous, 0], con_sat_brt[key_next, 0], lerp_amt),
                     lerp(con_sat_brt[key_previous, 1], con_sat_brt[key_next, 1], lerp_amt),
                     lerp(con_sat_brt[key_previous, 2], con_sat_brt[key_next, 2], lerp_amt),
                     lerp(con_sat_brt[key_previous, 3], con_sat_brt[key_next, 3], lerp_amt),
                     lerp(con_sat_brt[key_previous, 4], con_sat_brt[key_next, 4], lerp_amt)]

// reflection alpha:       
//              sin((2 * time            + phase) * pi) * scale + shift
alpha = clamp(sin((2 * global.Daytime + 0.4) * 3.14) * 1.3 + 0.3, 0, 1);
GML:
/// Draw GUI Begin event of the controller object.
/// @description draw effects

//Draw lights on surface
//---------------------------------------------------------------------------------------------------------

if (!surface_exists(srf_lights)) {
    srf_lights = surface_create(surface_get_width(application_surface), surface_get_height(application_surface));
    tex_lights = surface_get_texture(srf_lights);
}

surface_set_target(srf_lights);
    /*View:        - if there's many lights, add some code to check if the light would be drawn to the view
                - if the view size is different from the view port you maybe need to change the drawing scale
    Brightness:    - lights_strength controls the brightness of all lights
                - if you want to control the brightness of each individual light, there's two ways:
                    - for static brightness, just make their colour darker in the room editor
                    - for dynamic changes: change image_alpha */
                    
    // set up surface and GPU
    draw_clear(c_black);
    gpu_set_blendmode(bm_add);
    gpu_set_tex_filter(true); // optional
    
    // draw light sprites
    var lights_strength = global.Brightness;
    var vx = camera_get_view_x(view_camera[0]);
    var vy = camera_get_view_y(view_camera[0]);
    with(pLightMasks)
    {
        draw_sprite_ext(sprite_index, image_index, x - vx, y - vy, image_xscale, image_yscale, image_angle, image_blend, image_alpha * lights_strength);
    }
    // draw text
    draw_set_halign(fa_center);
    draw_set_font(fPixel);
    draw_text_color(320, 180, "Text Ilumination", c_gray, c_gray, c_gray, c_gray, lights_strength);
    draw_text_color(320, 200, "MOVING LIGHTS", c_gray, c_gray, c_gray, c_gray, lights_strength);
    draw_set_halign(fa_left);
    draw_set_font(-1);
    
    // reset GPU
    gpu_set_tex_filter(false); // optional
    gpu_set_blendmode(bm_normal);
surface_reset_target();

//Draw application surface
//---------------------------------------------------------------------------------------------------------

shader_set(shader);
    shader_set_uniform_f_array(u_col, color_mix);
    shader_set_uniform_f_array(u_con_sat_brt, con_sat_brt_mix);
    texture_set_stage(s_lights, tex_lights);
    var scale = 1;                                                //scr_camera_get_scale();
    if surface_exists(application_surface)
        draw_surface_ext(application_surface, 0, 0, scale, scale, 0, c_white, 1);
shader_reset();

//debug stuff
if (global.toggleMask)
{
    draw_surface_ext(srf_lights, 0, 0, scale, scale, 0, c_white, 1);
}
Code:
/// Fragment shader used to do the day and night (direrctly copied from the soruce project)
/*-----------------------------------------------------------------------------
Day and Night Shader: Tint, Contrast, Brightness, Saturation and Pop Lights
Fragment Shader: Apply effects. overlay tint
-----------------------------------------------------------------------------*/


varying vec2 v_vTexcoord;
varying vec4 v_vColour;

uniform vec3 col;
uniform float con_sat_brt[5];

uniform sampler2D lights;

#define contrast        con_sat_brt[0]
#define saturation        con_sat_brt[1]
#define brightness        con_sat_brt[2]
#define pop_strength    con_sat_brt[3]
#define pop_threshold    con_sat_brt[4]

void main()
{
    vec3 base_col    = texture2D( gm_BaseTexture, v_vTexcoord ).rgb;
    
    float grey        = dot(base_col, vec3(0.299, 0.587, 0.114));
    
    // overlay:
    vec3 out_col            = grey > 0.5 ? 1.0 - (1.0 - 2.0 * (base_col - 0.5)) * (1.0 - col) : 2.0 * base_col * col;
    // add saturation:
    out_col            = mix(vec3(grey), out_col, saturation);
    // add contrast:
    out_col            = (out_col - 0.5) * contrast + 0.5;
    // pop lights:
    out_col            = out_col + pop_strength * max(grey - pop_threshold, 0.0);
    // add brightnes:
    out_col            = out_col + brightness;
    
    // hanlde lights:
    vec3 lights_col = texture2D(lights, v_vTexcoord).rgb;
    grey            = dot(lights_col, vec3(0.333));
    //out_col            = mix(out_col, base_col * lights_col, grey);                    //Problem: can darken instead of lighten
    //out_col            = mix(out_col, base_col * normalize(lights_col) * 3.0, grey);    //Problem: creates unwanted noise
    out_col            = mix(out_col, base_col * normalize(lights_col + 0.05) * 3.0, grey);//Problems solved
    
    out_col            += 0.1 * lights_col; //Optional: it makes blacks not black anymore (so they chan shine too)
    
    gl_FragColor = vec4(out_col, 1.0);
}
So I really don't know how it doesn't work, I barely understand how shaders and surfaces, but until the point of putting masks all is working like in the tutorials.
 
R

RareDoggu

Guest
i tried using this in the debug part to see the game without the black part of the mask

GML:
// DEBUG LIGHTING SURFACE:
//-----------------------------------------------------------------------------
if (global.toggleMask)
{
gpu_set_blendmode(bm_add);
draw_surface_ext(srf_lights, 0, 0, scale, scale, 0, c_white, 1);
gpu_set_blendmode(bm_normal);
}
in the debug part (where the game shows the mask with the black bg as intended)


and its really wrong because its not using it as a mask



see, its only passing the greyscale as an alpha value when drawing the surface directly:





what i want is to have the mask surface go through the shader and manipulate that part of the color, bnut somehow the surface isn't getting picked up by the shader.
 
R

RareDoggu

Guest
Oh, I'm dumb, I found the issue. it was to do with that i havent changed what shader im calling, I had the updated version and the old version without the lights still in the game so in the end it was a thing i overlooked, because it was on a part where i hadn't touched when changing shaders.

I had reread the code so many times, and until i went to that part i didnt realize.

Sorry for the inconvenience all :oops:
 
G

GigaWight

Guest
Looking good, glad you were able to get it working. One of my biggest head-scratchers of perfectly good external code I found that stops working immediately when it gets anywhere near mine... and it's 99% always something I've overlooked. We live and learn.
 
Top