Created
June 24, 2024 13:37
-
-
Save MGDSStudio/0b2640dbe5fe20adf3362187352d01cb to your computer and use it in GitHub Desktop.
This shader is used to create an effect of a sprite dissolving in a portal (when the protagonist visits a portal) in my game. The sprite should have the same size as the source image file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright © 2024 MGDS Studio. All rights reserved. | |
#ifdef GL_ES | |
#define LOWP lowp | |
precision mediump float; | |
#else | |
#define LOWP | |
#endif | |
const float VISIBLE_LINES_COUNT = 7.0; // Visible areas pieces | |
const float INVISIBLE_LINES_COUNT = VISIBLE_LINES_COUNT-1.0; //Invisible areas between visible. They will be increased | |
const float TIME = 1.2; //Max time for dissolvin | |
const float START_ALPHA = 0.0; //Start alpha for dissolving | |
const float END_ALPHA = 0.75; //End alpha for dissolving | |
const float END_HEIGHT = 1.0/(INVISIBLE_LINES_COUNT); //End height for every area which will be increased at TIME-moment | |
varying vec2 v_texCoords; //From 0.0 to 1.0! Only readable in fragment shader | |
uniform sampler2D u_texture; | |
uniform float time; //Time from shader launch. Value must be set up from the game in seconds | |
void renderTransparent(); | |
/** Remember! Coordinates from bottom! | |
* Incoming data only time in seconds! | |
* shaderProgram.setUniformf("time", deltaTime); | |
*/ | |
void main(void) { | |
float actualInvisibleHeight = (END_HEIGHT)*(time/TIME); //(0 .. 1) | |
float halfTestAreaHeight = actualInvisibleHeight/2.0; | |
float top; //top line of the single area | |
float bottom; //bottom line of the single area | |
bool areaInside = false; | |
float actualY = END_HEIGHT/2.0; | |
for (float i = 0.0; i < INVISIBLE_LINES_COUNT; i+=1.0){ | |
float fI = float(i); //Convert to float | |
top = actualY+halfTestAreaHeight; //Top line (Y-pos) of this invisible area | |
bottom = actualY-halfTestAreaHeight; //Top line (Y-pos) of this invisible area | |
if (v_texCoords.y>=bottom && v_texCoords.y <= top){ | |
areaInside = true; //Line in invisible area. Will not be rendered | |
break; | |
} | |
actualY+=END_HEIGHT; | |
} | |
if (areaInside){ | |
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); | |
} | |
else { | |
renderTransparent(); | |
} | |
} | |
void renderTransparent(){ | |
float actualAlpha = 1.0-(START_ALPHA+(END_ALPHA-START_ALPHA)*(time/TIME)); | |
if (actualAlpha > 1.0) actualAlpha = 1.0; | |
else if (actualAlpha <0.0) actualAlpha = 0.0; | |
vec4 color = texture2D(u_texture, v_texCoords); | |
float originalAlpha = color.a; | |
if (originalAlpha<actualAlpha){ | |
actualAlpha = originalAlpha; | |
} | |
gl_FragColor = vec4(color.r, color.g, color.b, actualAlpha); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment