Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save MGDSStudio/0b2640dbe5fe20adf3362187352d01cb to your computer and use it in GitHub Desktop.
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.
// 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