2 Days ago I've never touched any kind of shader stuff before. Then I watched this series. Now I have my own day-night-lightsource engine, inspired by this one but still vastly different in certain key areas. For example, I do define the base_color, but I send it through the same process as the output_color,, when it comes to saturation, contrast, brightness, pop and treshold. Then I multiply my output_color vector components with uniforms, one for each color (this gives me more control PER color). I leave the base_color alone at this point. Then there's the lightsurface and textures, which are created in the same way. I do this: vec3 base_color = texture2D(gm_BaseTexture, v_vTexcoord).rgb; vec3 output_color = texture2D(gm_BaseTexture, v_vTexcoord).rgb; float grey = dot(output_color, vec3(0.300, 0.600, 0.100)); //add contrast: base_color = (output_color-0.5) * con+0.5; output_color = (output_color-0.5) * con+0.5; //pop color: base_color = output_color + pop*max(grey-tres, 0.0); output_color = output_color + pop*max(grey-tres, 0.0); //add saturation: base_color = mix(vec3(grey), output_color, sat); output_color = mix(vec3(grey), output_color, sat); //add brightness: base_color = output_color + bright; output_color = output_color + bright; //lights texture: vec3 lights_color = texture2D(lights, v_vTexcoord).rgb; //finalize day/night effect on JUST THE OUTPUT_COLOR output_color = vec3(output_color.r*daycolor_r, output_color.g*daycolor_g, output_color.b*daycolor_b); //per pixel basis mix of day/night output_color and non-effect base_color: output_color = lights_color.r > 0.0 && lights_color.g > 0.00 && lights_color.b > 0.00 ? (base_color*lights_color) + (output_color*abs(lights_color-1.0)) : (output_color.rgb + vec3(0.00)); gl_FragColor = vec4(output_color.r, output_color.g, output_color.b, 1.0); Simply put, on a per pixel basis, I check if the lightsurface is fully black, making each of its rgb components 0.0. If it is indeed 0.00 for each rgb component, i simply output the output_color vec3. If however, the lightmap is not a vec33(0.00), then it is either a greyshade or a fully white vec3(1.00). That's what the inline if statement does in my project. It's this answer in particular that makes things incredibly easy to use and understand: if somewhere on the lightmap there are pixels that aren't black, draw those pixels like this: output_color = (base_color*lights_color) + (output_color*abs(lights_color-1.0)) if the pixels are black, base_color*lights_color becomes 0, so any area outside the lightsource will not draw base_color. It will however, still draw output_color*abs(lights_color-1.0)), which at this point is justthe output_color as abs(0-1) = abs(-1) = 1 So at black pixels in the lightmap we draw 0*base_color+1*output_color. But we have that in-line if statement remember? In this case, that formula isn't even used, it just renders output_color. For black pixels then, both sides of the if statement answers output the same answer, you can't go wrong there. The magic only starts happening if the lightmap pixels aren't black, but shades of grey and white: if the pixels are purely white, lights_color is a vec3(1,1,1) Now only the first term is drawn, as the second term becomes output_color * 0 because lights_color-1.0 = (0.0,0.0,0.0): output_color = (base_color*lights_color) + (output_color*abs(lights_color-1.0)) So, at the center of the light, we don't draw the day/night effect output_color, but just the base_color But what about the in-between values, from the center of the light to the edge? Surely those must have a gradient, a sort of "flow from base_color smoothly to output_color" right? Well this formula covers that! In these cases, both terms in the formula hold a value and they are added together. They form a mix between base_color and output_color. Let's try it, at a halfway point from the light source to the edge, where the grey values are 0.5 (lights_color = vec3(0.5,0.5,0.5): The lights_color components are larger than 0, so we again have the formula: output_color = (base_color*lights_color) + (output_color*abs(lights_color-1.0)) which becomes: output_color = base_color * 0.5 + output_color * abs(0.5-1.0) output_color = base_color * 0.5 + output_color * 0.5 or rather, half of the base_color, and half of the output_color. A mix between "no effect pixels" and "daynight effect pixels". It just dims or lightens base_color and output_color, and they are tied together. So things like base_color *0.25 + output_color*0.75 would be at 75% the distance between the light source and the edge of the light, starting from the light source. Basically, the further away from the center, the darker base_color is drawn and the more lit up output_color is drawn. When we add them together, we get a new vec3 with the correct colors, as if they were mixed. it works great O_o And that, in only 2 days with ZERO experience in shaders, and all because of these tutorial videos. I would like your video 100 times if RUclips were to allow it.
I've been watching these for a while now but never actually commented. Awesome series. :) A possible future video idea is something I've been working on over the last few weeks in GMS 1.4 is diffusive and phong lighting and normal mapping. It's the fact that I can't seem to wrap my head around it that is keeping me held back but a tutorial from you on it would be ridiculously helpful, like your videos on bloom and luma masks were to me. Anyway, keep up the awesome work.
Should probably clarify, I have gone looking and even learnt about full, raw 3D GLSL lighting, I just can't seem to integrate what I've learnt into GMS. You just have a way with explanations in my opinion. :)
Thanks for the great feedback :) Phong shading sounds like 3D and I don't know anything about 3D - sorry. I might do normal maps someday but it would only be 2D and it's far from my top priority at the moment - sorry again :/
@@gamingreverends-devcorner1379 hey reverend ! could you add one day the functionality of shadows cast on the ground? and add part system ? thank you for reading my comment
I LOVE this. And I am excited to use this in my game projects. Will absolutely credit you whenever I eventually publish my work on Steam. So far Ariak (Z-tilting) and Gaming Reverend has been a tremendous help for a game dev/hobbyist such as myself. I listed just those two but truthfully we all get our knowledge from pretty much anywhere on YT or our favorite fellow game devs. Nonetheless, it just feels awesome that I have an actual purpose for a credits screen in my game now haha.
You are awesome, thank you so much! You also did a great job showing the old code and the new code at the same time, this made it really easy to see and understand what got changed. Thank you!
That's what is frightening about coding. If your code is well concepted, you will remark than it will be shrunk to essential, extremely powerfull and clean in readingness. Your video is the real deal about tutorial ... so thanks.
Hey there! Want to start off by saying your tutorials are incredible. Thank you for taking the time to make them, they have helped tremedously. Secondly I would like to ask you for some help with an issue. I know this video isn't new so I may not get an answer but here goes. I've managed to get my shader working like yours with lights too, but there is one light in the game that needs to constantly follow the player. When I have the light follow the player it doesn't follow him precisely, and when he starts running (faster speed variable) the light keeps getting farther from him. Is there a way to have the light follow the player? It can't be view based as the view stops if the character moves left, but the light should still follow him. Don't know if that's clear enough, but I'm looking forward to your future reply. Thanks again for your amazing tutorials!
Is it possible to achieve adding lights without the overlay? I prefer the lighting in V1_0 however I'm unsure how to use lights with that version as they seem quite tied to overlay and the renaming of base_col and out_col. Any help?
I haven't tried the lights yet and I will this week sometime but instead of putting the lights on the screen where they're that big couldn't we just resize then in the create event or something?
Hello! These tutorials are amazing. I decided to use version 1.0 for my lighting because I like the intensity of the colors without blending. It works better with my game's theme. However, lights at night are darker than lights during the day. They don't make things nearly as bright as they do in this tutorial. Do you have any ideas that could help my lights pierce through the dark purple nights in my game? Thanks in advance.
The lights are drawn to a surface and a surfaces origin is always the top-left corner. So you need to get the surfaces or cameras position in the room and subtract that when drawing to the cameras surface. Also make sure you only draw lights that are actually visible if the room is fairly large.
Simple but pretty light system! It is nice because you can make as many light as you want, and the optimisation seems to be good! Also, the light renders great, thanks to shaders, and different shapes can be use! I test a lot of light system for GM, but this is the most simple/efficient i found. The second is fakelight3, but i think this one is a little more beautiful with shaders. My light system cast shadows of tiles (based on Mike Dailly tutorial), but i'm limited with only 3 light per surface (4 if i use alpha channel), and then if i want to combine more than 4 light together, i need to blend surface and that's another story ahah (i'm not good enough for the moment). So my system work fine for my game, because i have little subrooms so 3 dynamics light per subrooms is quite enough, but it's cost a lot of memory and have this restrictions for only casting some shadows x). But i don't know ... i find these shadows really nice (add some volume) I can make them static (calculate shadows only once), but i'm still stuck by the maximum light per surface. If i findd that my system is too heavy and restrictif (only 4 lights), then i will take yours if you're okay! Thanks for this video!
I think a really nice lighting and shadow casting system is Mark Alexanders Aura 2.0 and it seems to be efficient even without shaders. But I haven't created a shadow casting lighting ever and am a bit intimitaded by the maths and possible performance problems :)
Inside the lit area, they are unfortunately. I think they should rather be reduced in strength. But since the shader doesn't make a difference between water and land, they are even increased in strength and washed out.
hmm... I have to admit, that though this is along the lines of that Moonlighter night-cycle we had talked about... I really like the stars too... strange how difficult it is to have both... I wonder if you have to slice out the lights earlier on... perhaps before you apply the blue itself? I understand you are working from the application surface, but I imagine, that you calculate where the lights are going to be BEFORE you do the rest of the steps... kinda like punching a hole in the blue as you apply it, and you overlay that with the light?... Am I making any sense here?
@@mirthcastle I think you'd need to find a way to separate water from the rest. i.e. draw the water to one surface and the rest to another surface. Then in the end you'll draw the water surface with different light settings than the rest - especially the popping lights factor or thershold would need to change. The main reason why the stars look washed out is that withing the lit area they shouldn't show at all or only darker. There are certainly different approaches but that's probably the first I would test. Just mind you're adding complexity and if you're running the game on a mobile, test your system early on to test the performance.
Hello, this tutorials are fantastic! I finally ended up doing what version 1 and 1.1 did and leant by myself some tricks about the game window and display along the way that will be useful in the future, though in this tutorial I'm having trouble finding why it doesn't work on my own dummy project. even if It works when I use the original base project when I put all the necessary stuff in mine it doesn't use the lights. Here in the forums I posted my issue: forum.yoyogames.com/index.php?threads/implementing-the-day-and-night-shader-v1-2-from-gaming-reverends.74117/
2 Days ago I've never touched any kind of shader stuff before. Then I watched this series. Now I have my own day-night-lightsource engine, inspired by this one but still vastly different in certain key areas.
For example, I do define the base_color, but I send it through the same process as the output_color,, when it comes to saturation, contrast, brightness, pop and treshold.
Then I multiply my output_color vector components with uniforms, one for each color (this gives me more control PER color). I leave the base_color alone at this point.
Then there's the lightsurface and textures, which are created in the same way.
I do this:
vec3 base_color = texture2D(gm_BaseTexture, v_vTexcoord).rgb;
vec3 output_color = texture2D(gm_BaseTexture, v_vTexcoord).rgb;
float grey = dot(output_color, vec3(0.300, 0.600, 0.100));
//add contrast:
base_color = (output_color-0.5) * con+0.5;
output_color = (output_color-0.5) * con+0.5;
//pop color:
base_color = output_color + pop*max(grey-tres, 0.0);
output_color = output_color + pop*max(grey-tres, 0.0);
//add saturation:
base_color = mix(vec3(grey), output_color, sat);
output_color = mix(vec3(grey), output_color, sat);
//add brightness:
base_color = output_color + bright;
output_color = output_color + bright;
//lights texture:
vec3 lights_color = texture2D(lights, v_vTexcoord).rgb;
//finalize day/night effect on JUST THE OUTPUT_COLOR
output_color = vec3(output_color.r*daycolor_r, output_color.g*daycolor_g, output_color.b*daycolor_b);
//per pixel basis mix of day/night output_color and non-effect base_color:
output_color = lights_color.r > 0.0 && lights_color.g > 0.00 && lights_color.b > 0.00 ? (base_color*lights_color) + (output_color*abs(lights_color-1.0)) : (output_color.rgb + vec3(0.00));
gl_FragColor = vec4(output_color.r, output_color.g, output_color.b, 1.0);
Simply put, on a per pixel basis, I check if the lightsurface is fully black, making each of its rgb components 0.0. If it is indeed 0.00 for each rgb component, i simply output the output_color vec3.
If however, the lightmap is not a vec33(0.00), then it is either a greyshade or a fully white vec3(1.00).
That's what the inline if statement does in my project.
It's this answer in particular that makes things incredibly easy to use and understand:
if somewhere on the lightmap there are pixels that aren't black, draw those pixels like this:
output_color = (base_color*lights_color) + (output_color*abs(lights_color-1.0))
if the pixels are black, base_color*lights_color becomes 0, so any area outside the lightsource will not draw base_color.
It will however, still draw output_color*abs(lights_color-1.0)), which at this point is justthe output_color as abs(0-1) = abs(-1) = 1
So at black pixels in the lightmap we draw 0*base_color+1*output_color.
But we have that in-line if statement remember? In this case, that formula isn't even used, it just renders output_color.
For black pixels then, both sides of the if statement answers output the same answer, you can't go wrong there.
The magic only starts happening if the lightmap pixels aren't black, but shades of grey and white:
if the pixels are purely white, lights_color is a vec3(1,1,1)
Now only the first term is drawn, as the second term becomes output_color * 0 because lights_color-1.0 = (0.0,0.0,0.0):
output_color = (base_color*lights_color) + (output_color*abs(lights_color-1.0))
So, at the center of the light, we don't draw the day/night effect output_color, but just the base_color
But what about the in-between values, from the center of the light to the edge?
Surely those must have a gradient, a sort of "flow from base_color smoothly to output_color" right?
Well this formula covers that!
In these cases, both terms in the formula hold a value and they are added together.
They form a mix between base_color and output_color.
Let's try it, at a halfway point from the light source to the edge, where the grey values are 0.5 (lights_color = vec3(0.5,0.5,0.5):
The lights_color components are larger than 0, so we again have the formula:
output_color = (base_color*lights_color) + (output_color*abs(lights_color-1.0))
which becomes:
output_color = base_color * 0.5 + output_color * abs(0.5-1.0)
output_color = base_color * 0.5 + output_color * 0.5
or rather, half of the base_color, and half of the output_color. A mix between "no effect pixels" and "daynight effect pixels".
It just dims or lightens base_color and output_color, and they are tied together.
So things like base_color *0.25 + output_color*0.75 would be at 75% the distance between the light source and the edge of the light, starting from the light source.
Basically, the further away from the center, the darker base_color is drawn and the more lit up output_color is drawn. When we add them together, we get a new
vec3 with the correct colors, as if they were mixed.
it works great O_o
And that, in only 2 days with ZERO experience in shaders, and all because of these tutorial videos. I would like your video 100 times if RUclips were to allow it.
I've been watching these for a while now but never actually commented.
Awesome series. :)
A possible future video idea is something I've been working on over the last few weeks in GMS 1.4 is diffusive and phong lighting and normal mapping. It's the fact that I can't seem to wrap my head around it that is keeping me held back but a tutorial from you on it would be ridiculously helpful, like your videos on bloom and luma masks were to me.
Anyway, keep up the awesome work.
Should probably clarify, I have gone looking and even learnt about full, raw 3D GLSL lighting, I just can't seem to integrate what I've learnt into GMS.
You just have a way with explanations in my opinion. :)
Thanks for the great feedback :)
Phong shading sounds like 3D and I don't know anything about 3D - sorry. I might do normal maps someday but it would only be 2D and it's far from my top priority at the moment - sorry again :/
Absolute life saver. Thank you so much!!
Thanks :)
@@gamingreverends-devcorner1379 hey reverend ! could you add one day the functionality of shadows cast on the ground? and add part system ? thank you for reading my comment
I LOVE this. And I am excited to use this in my game projects. Will absolutely credit you whenever I eventually publish my work on Steam. So far Ariak (Z-tilting) and Gaming Reverend has been a tremendous help for a game dev/hobbyist such as myself. I listed just those two but truthfully we all get our knowledge from pretty much anywhere on YT or our favorite fellow game devs. Nonetheless, it just feels awesome that I have an actual purpose for a credits screen in my game now haha.
Great series and thank you so so much for commenting everything it helps so much with understanding!
You are awesome, thank you so much! You also did a great job showing the old code and the new code at the same time, this made it really easy to see and understand what got changed.
Thank you!
That's what is frightening about coding. If your code is well concepted, you will remark than it will be shrunk to essential, extremely powerfull and clean in readingness.
Your video is the real deal about tutorial ... so thanks.
Tahnk you :)
wow thanks this is soo good
Hey there! Want to start off by saying your tutorials are incredible. Thank you for taking the time to make them, they have helped tremedously.
Secondly I would like to ask you for some help with an issue. I know this video isn't new so I may not get an answer but here goes.
I've managed to get my shader working like yours with lights too, but there is one light in the game that needs to constantly follow the player. When I have the light follow the player it doesn't follow him precisely, and when he starts running (faster speed variable) the light keeps getting farther from him. Is there a way to have the light follow the player? It can't be view based as the view stops if the character moves left, but the light should still follow him.
Don't know if that's clear enough, but I'm looking forward to your future reply.
Thanks again for your amazing tutorials!
Awesome!! You are great!
Is it possible to achieve adding lights without the overlay? I prefer the lighting in V1_0 however I'm unsure how to use lights with that version as they seem quite tied to overlay and the renaming of base_col and out_col. Any help?
Great stuff? How would I get it so that overlapping the lights doesn't make it so bright?
I haven't tried the lights yet and I will this week sometime but instead of putting the lights on the screen where they're that big couldn't we just resize then in the create event or something?
Yes you could, but then you need one object for every light size
Hello! These tutorials are amazing. I decided to use version 1.0 for my lighting because I like the intensity of the colors without blending. It works better with my game's theme. However, lights at night are darker than lights during the day. They don't make things nearly as bright as they do in this tutorial. Do you have any ideas that could help my lights pierce through the dark purple nights in my game? Thanks in advance.
Can anybody please tell me how to adjust the code if the view size is different from the view port?
how Can I define the lights in the room to be static and not move with the camera[0]?
The lights are drawn to a surface and a surfaces origin is always the top-left corner. So you need to get the surfaces or cameras position in the room and subtract that when drawing to the cameras surface. Also make sure you only draw lights that are actually visible if the room is fairly large.
@@gamingreverends-devcorner1379 Thank u so much
@@shadowjhone Hiii. did u get it?
Simple but pretty light system! It is nice because you can make as many light as you want, and the optimisation seems to be good! Also, the light renders great, thanks to shaders, and different shapes can be use! I test a lot of light system for GM, but this is the most simple/efficient i found. The second is fakelight3, but i think this one is a little more beautiful with shaders.
My light system cast shadows of tiles (based on Mike Dailly tutorial), but i'm limited with only 3 light per surface (4 if i use alpha channel), and then if i want to combine more than 4 light together, i need to blend surface and that's another story ahah (i'm not good enough for the moment). So my system work fine for my game, because i have little subrooms so 3 dynamics light per subrooms is quite enough, but it's cost a lot of memory and have this restrictions for only casting some shadows x). But i don't know ... i find these shadows really nice (add some volume)
I can make them static (calculate shadows only once), but i'm still stuck by the maximum light per surface. If i findd that my system is too heavy and restrictif (only 4 lights), then i will take yours if you're okay! Thanks for this video!
I think a really nice lighting and shadow casting system is Mark Alexanders Aura 2.0 and it seems to be efficient even without shaders. But I haven't created a shadow casting lighting ever and am a bit intimitaded by the maths and possible performance problems :)
Is very awesome but how i add light particles now ?
by drawing the surface of the particle system on the lights surface, with the light objects
NO THAT DON'T WORK
Are you planning in showing lights with normal maps?
No plans in that department yet - sorry :(
The Stars seem to be washed out?
Inside the lit area, they are unfortunately. I think they should rather be reduced in strength. But since the shader doesn't make a difference between water and land, they are even increased in strength and washed out.
hmm... I have to admit, that though this is along the lines of that Moonlighter night-cycle we had talked about... I really like the stars too... strange how difficult it is to have both...
I wonder if you have to slice out the lights earlier on... perhaps before you apply the blue itself? I understand you are working from the application surface, but I imagine, that you calculate where the lights are going to be BEFORE you do the rest of the steps... kinda like punching a hole in the blue as you apply it, and you overlay that with the light?... Am I making any sense here?
@@mirthcastle I think you'd need to find a way to separate water from the rest. i.e. draw the water to one surface and the rest to another surface. Then in the end you'll draw the water surface with different light settings than the rest - especially the popping lights factor or thershold would need to change. The main reason why the stars look washed out is that withing the lit area they shouldn't show at all or only darker.
There are certainly different approaches but that's probably the first I would test. Just mind you're adding complexity and if you're running the game on a mobile, test your system early on to test the performance.
Hello, this tutorials are fantastic! I finally ended up doing what version 1 and 1.1 did and leant by myself some tricks about the game window and display along the way that will be useful in the future, though in this tutorial I'm having trouble finding why it doesn't work on my own dummy project. even if It works when I use the original base project when I put all the necessary stuff in mine it doesn't use the lights. Here in the forums I posted my issue: forum.yoyogames.com/index.php?threads/implementing-the-day-and-night-shader-v1-2-from-gaming-reverends.74117/