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

Shaders Progressive construction shader

DjennyFloro

Member
Greetings everyone,

I am at the conceptual stage of my shader (not coded since I am trying to lay out how the shader should work). The goal is to animate the construction of a building.

Here's what I want to achieve:


step 1: the first row of pixels is some kind of neon blue glowing (1px large, perhaps 2 px large).
step 2: the first row of pixels is the sprite's pixels with an alpha of 0.1, the second row of pixels is neon blue glowing.
step 3: the first row of pixels is the sprite's pixels with an alpha of 0.2, the second row of pixels is the sprite's one with 0.1 and the third row of pixels is neon blue.
....

and so on, until I've reached the last row of pixels and it's of alpha 1.

I understand that I should have at least have a variable passed onto the shader that keeps track of the time and step of the construction I'm in. What I don't get, is where should I keep track of which row I'm in, and if I should make 2 shaders (one for the glowing blue bar that goes upward as the sprite's built, one for the sprite being built).

I've been looking at several tutorials, but the concept of this "row by row" construction seems absent, and I'm a bit at loss as to how this would go on.

Thanks to anyone who'll take the time to read and/or answer this thread.

Djenny Floro.
 

NightFrost

Member
Technically you could do this as a number of partial sprite draws but yes, if you're familiar with shaders this would work as a single shader. Since the draw call supplies the shader with the sprite to draw, you don't need to send it in yourself. You just need to send in the position of the moving construction line during given step. Insider the shader, you'd compare current pixel's vertical position to the supplied line position. If it is above, you draw nothing. If it is exactly the same, you draw a neon blue pixel. If it is below, you calculate difference between positions and generate alpha from that, then use the alpha when drawing a pixel from the supplied texture (the sprite image). On GMS side, you keep moving the draw position upwards, until it is 10 above the height of wall. That's when you deem the animation process done.
 

rytan451

Member
You could do this with a 4-triangle primitive. Using a strip, the top two vertices have alpha 0, the middle two vertices have alpha 1, and the bottom two vertices also have alpha 1. If your middle two vertices would go under the bottom of the sprite, then you'd just clamp them to the bottom of the sprite and calculate the alpha there (and you'd completely omit the last two vertices).
 

DjennyFloro

Member
I'm not familiar with the vertex one, and unsure I could pull this through, plus, would it be progressive? It feels like it would be more like a clustered construction than a "laser-driven" one as I am trying to achieve. Thanks for taking the time to answer my thread, I will still look into that possibility if I come across resources that explain better the vertice system.
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
A fragment shader takes a texture and texture coordinates and returns the resulting color.

It is possible to also pass in room coordinates, as shown here https://yal.cc/gamemaker-draw-clip/#rect-sh
Vertex:
Code:
attribute vec3 in_Position;
attribute vec4 in_Colour;
attribute vec2 in_TextureCoord;
//
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
varying vec3 v_vPosition;
//
void main() {
    v_vPosition = in_Position;
    gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION]
        * vec4(in_Position.x, in_Position.y, in_Position.z, 1.0);
    v_vColour = in_Colour;
    v_vTexcoord = in_TextureCoord;
}
Fragment:
Code:
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
varying vec3 v_vPosition;
//
void main() {
    vec4 col = v_vColour * texture2D(gm_BaseTexture, v_vTexcoord);
    // you can now use v_vPosition.x/y here
    gl_FragColor = col;
}
you could pass in a uniform for top Y and then do a few checks to figure out the color/replacement
 

DjennyFloro

Member
Sickness and tons of life events later, after years and finally getting better, I am able to come back to this shader.

Meanwhile, I found a video who explains what kind of shader I want to construct, but unfortunately, it's done in unity. So I have to translate this in Game Maker.

Video showing what effect I want to do

It seems complicated, and I'm trying to discern what part is the fragment shader, or what part is the vertex shader. If anyone has ideas / insights, I'd be very happy. Of course, I'll share the final code so everyone can see it later on.
 

FoxyOfJungle

Kazan Games
Sickness and tons of life events later, after years and finally getting better, I am able to come back to this shader.

Meanwhile, I found a video who explains what kind of shader I want to construct, but unfortunately, it's done in unity. So I have to translate this in Game Maker.

Video showing what effect I want to do

It seems complicated, and I'm trying to discern what part is the fragment shader, or what part is the vertex shader. If anyone has ideas / insights, I'd be very happy. Of course, I'll share the final code so everyone can see it later on.
He used Shader Graph, a visual editor feature of Unity, so I don't know how I could get the final code. But to do what you want, you could maybe use a luma texture.
Or maybe, you can use room coordinates as mentioned above. Look at this example, maybe it can give you some idea:

 
I got some tutorials on luma textures in GMS2. It's a long watch though (nearly 2 hours for all 5 lessons). In this playlist lessons 19a to 19e. Mind the base project file coming with the tutorial is broken since GMS 2.3. but the code in the video still works.
 
Top