/*
* KNWebGLShader.js
* Keynote HTML Player
*
* Created by Tungwei Cheng
* Copyright (c) 2016-2019 Apple Inc. All rights reserved.
*/
var KNWebGLShader = {};
KNWebGLShader.defaultTexture = {
attribNames: ["Position", "TexCoord"],
uniformNames: ["MVPMatrix", "Texture"],
vertex: "\
#ifdef GL_ES\n\
precision highp float;\n\
#endif\n\
uniform mat4 MVPMatrix;\n\
attribute vec4 Position;\n\
attribute vec2 TexCoord;\n\
varying vec2 v_TexCoord;\n\
void main()\n\
{\n\
v_TexCoord = TexCoord;\n\
gl_Position = (MVPMatrix * Position);\n\
}\
",
fragment: "\
#ifdef GL_ES\n\
precision mediump float;\n\
#endif\n\
uniform sampler2D Texture;\n\
varying vec2 v_TexCoord;\n\
void main()\n\
{\n\
gl_FragColor = texture2D(Texture, v_TexCoord);\n\
}\
"
};
KNWebGLShader.defaultTextureAndOpacity = {
attribNames: ["Position", "TexCoord"],
uniformNames: ["MVPMatrix", "Texture", "Opacity"],
vertex: "\
#ifdef GL_ES\n\
precision highp float;\n\
#endif\n\
uniform mat4 MVPMatrix;\n\
attribute vec4 Position;\n\
attribute vec2 TexCoord;\n\
varying vec2 v_TexCoord;\n\
void main()\n\
{\n\
v_TexCoord = TexCoord;\n\
gl_Position = (MVPMatrix * Position);\n\
}\
",
fragment: "\
#ifdef GL_ES\n\
precision mediump float;\n\
#endif\n\
uniform sampler2D Texture;\n\
uniform float Opacity;\n\
varying vec2 v_TexCoord;\n\
void main()\n\
{\n\
vec4 texColor = texture2D(Texture, v_TexCoord);\n\
gl_FragColor = vec4(Opacity) * texColor;\n\
}\
"
};
KNWebGLShader.contentsAndOpacity = {
attribNames: ["Position", "TexCoord"],
uniformNames: ["MVPMatrix", "Texture", "Texture2", "mixFactor", "Opacity"],
vertex: "\
#ifdef GL_ES\n\
precision highp float;\n\
#endif\n\
uniform mat4 MVPMatrix;\n\
attribute vec4 Position;\n\
attribute vec2 TexCoord;\n\
varying vec2 v_TexCoord;\n\
void main()\n\
{\n\
v_TexCoord = TexCoord;\n\
gl_Position = (MVPMatrix * Position);\n\
}\
",
fragment: "\
#ifdef GL_ES\n\
precision mediump float;\n\
#endif\n\
uniform sampler2D Texture;\n\
uniform sampler2D Texture2;\n\
uniform float mixFactor;\n\
uniform float Opacity;\n\
varying vec2 v_TexCoord;\n\
void main()\n\
{\n\
vec4 outgoingColor = texture2D(Texture2, v_TexCoord);\n\
vec4 incomingColor = texture2D(Texture, v_TexCoord);\n\
vec4 result = mix(outgoingColor, incomingColor, mixFactor);\n\
gl_FragColor = vec4(Opacity) * result;\n\
}\
"
};
KNWebGLShader.contents = {
attribNames: ["Position", "TexCoord"],
uniformNames: ["MVPMatrix", "Texture", "Texture2", "mixFactor"],
vertex: "\
#ifdef GL_ES\n\
precision highp float;\n\
#endif\n\
uniform mat4 MVPMatrix;\n\
attribute vec4 Position;\n\
attribute vec2 TexCoord;\n\
varying vec2 v_TexCoord;\n\
void main()\n\
{\n\
v_TexCoord = TexCoord;\n\
gl_Position = (MVPMatrix * Position);\n\
}\
",
fragment: "\
#ifdef GL_ES\n\
precision mediump float;\n\
#endif\n\
uniform sampler2D Texture;\n\
uniform sampler2D Texture2;\n\
uniform float mixFactor;\n\
varying vec2 v_TexCoord;\n\
void main()\n\
{\n\
vec4 outgoingColor = texture2D(Texture2, v_TexCoord);\n\
vec4 incomingColor = texture2D(Texture, v_TexCoord);\n\
vec4 result = mix(outgoingColor, incomingColor, mixFactor);\n\
gl_FragColor = result;\n\
}\
"
};
KNWebGLShader.iris = {
attribNames: ["Position", "TexCoord"],
uniformNames: ["PercentForAlpha", "Scale", "Mix", "Texture", "MVPMatrix", "Opacity"],
vertex: "\
#ifdef GL_ES\n\
precision highp float;\n\
#endif\n\
uniform mat4 MVPMatrix;\n\
attribute vec4 Position;\n\
attribute vec2 TexCoord;\n\
varying vec2 v_TexCoord;\n\
void main()\n\
{\n\
v_TexCoord = TexCoord;\n\
gl_Position = MVPMatrix * Position;\n\
}\
",
fragment: "\
#ifdef GL_ES\n\
precision mediump float;\n\
#endif\n\
uniform sampler2D Texture;\n\
uniform float Opacity;\n\
uniform float PercentForAlpha;\n\
uniform float Scale;\n\
uniform float Mix;\n\
varying vec2 v_TexCoord;\n\
void main()\n\
{\n\
vec4 incomingTexColor = texture2D(Texture, v_TexCoord);\n\
vec4 clear = vec4(0.0, 0.0, 0.0, 0.0);\n\
float tolerance = PercentForAlpha/5.0;\n\
vec2 powers = vec2((v_TexCoord.x - 0.5) * Scale,v_TexCoord.y - 0.5);\n\
powers *= powers;\n\
float radiusSqrd = PercentForAlpha * PercentForAlpha;\n\
float dist = (powers.x+powers.y)/((0.5*Scale)*(0.5*Scale)+0.25);\n\
float gradient = smoothstep(radiusSqrd, radiusSqrd+tolerance, dist);\n\
gl_FragColor = vec4(Opacity) * mix(clear, incomingTexColor, abs(Mix - gradient));\n\
}\
"
};
KNWebGLShader.twist = {
attribNames: ["Position", "TexCoord", "Normal"],
uniformNames: ["TextureMatrix", "SpecularColor", "FlipNormals", "MVPMatrix", "Texture"],
vertex: "\
#ifdef GL_ES\n\
precision highp float;\n\
#endif\n\
uniform mat4 MVPMatrix;\n\
uniform mat3 TextureMatrix;\n\
uniform float SpecularColor;\n\
uniform mediump float FlipNormals;\n\
attribute vec3 Position;\n\
attribute vec3 Normal;\n\
attribute vec2 TexCoord;\n\
varying vec2 v_TexCoord;\n\
varying vec3 v_DiffuseColor;\n\
varying vec3 v_SpecularColor;\n\
const vec3 c_AmbientColor = vec3(0.2);\n\
const vec3 c_DiffuseColor = vec3(1);\n\
const float c_LightExponent = 32.0;\n\
const vec3 c_LightDirection = vec3(0.1580, +0.5925, 0.7900);\n\
const vec3 c_LightHalfPlane = vec3(0.0835, +0.3131, 0.9460);\n\
void main()\n\
{\n\
vec3 thisNormal = Normal * FlipNormals;\n\
// Lighting\n\
float ndotl = max(0.0, dot(thisNormal, c_LightDirection));\n\
float ndoth = max(0.0, dot(thisNormal, c_LightHalfPlane));\n\
v_DiffuseColor = (c_AmbientColor + ndotl * c_DiffuseColor);\n\
v_SpecularColor = (ndoth <= 0.0) ? vec3(0) : (pow(ndoth, c_LightExponent) * vec3(SpecularColor));\n\
gl_Position = MVPMatrix * vec4(Position, 1.0);\n\
v_TexCoord = (TextureMatrix * vec3(TexCoord,1.0)).xy;\n\
}\
",
fragment: "\
#ifdef GL_ES\n\
precision mediump float;\n\
#endif\n\
uniform sampler2D Texture;\n\
varying vec2 v_TexCoord;\n\
varying vec3 v_DiffuseColor;\n\
varying vec3 v_SpecularColor;\n\
void main()\n\
{\n\
vec4 texColor = texture2D(Texture, v_TexCoord);\n\
// Lighting\n\
texColor.xyz = texColor.xyz * v_DiffuseColor + v_SpecularColor;\n\
gl_FragColor = texColor;\n\
}\
"
};
KNWebGLShader.colorPlanes = {
attribNames: ["Position", "TexCoord"],
uniformNames: ["MVPMatrix", "FlipTexCoords", "Texture", "ColorMask"],
vertex: "\
#ifdef GL_ES\n\
precision highp float;\n\
#endif\n\
uniform mat4 MVPMatrix;\n\
uniform vec2 FlipTexCoords;\n\
attribute vec2 Position;\n\
attribute vec2 TexCoord;\n\
varying vec2 v_TexCoord;\n\
void main()\n\
{\n\
v_TexCoord = vec2(FlipTexCoords.x == 0.0 ? TexCoord.x : 1.0-TexCoord.x, FlipTexCoords.y == 0.0 ? TexCoord.y : 1.0-TexCoord.y);\n\
gl_Position = MVPMatrix * vec4(Position, 0,1);\n\
}\
",
fragment: "\
#ifdef GL_ES\n\
precision mediump float;\n\
#endif\n\
uniform sampler2D Texture;\n\
uniform vec4 ColorMask;\n\
varying vec2 v_TexCoord;\n\
void main()\n\
{\n\
vec4 texColor = texture2D(Texture, v_TexCoord);\n\
texColor *= ColorMask;\n\
gl_FragColor = texColor;\n\
}\
"
};
KNWebGLShader.flop = {
attribNames: ["Position", "TexCoord", "Normal"],
uniformNames: ["TextureMatrix", "FlipNormals", "MVPMatrix", "Texture"],
vertex: "\
\n\
#ifdef GL_ES\n\
precision highp float;\n\
#endif\n\
\n\
uniform mat4 MVPMatrix;\n\
uniform mat3 TextureMatrix;\n\
uniform float FlipNormals;\n\
\n\
attribute vec3 Position;\n\
attribute vec3 Normal;\n\
attribute vec2 TexCoord;\n\
\n\
varying vec2 v_TexCoord;\n\
varying vec3 v_DiffuseColor;\n\
\n\
const vec3 c_AmbientColor = vec3(0.1);\n\
const vec3 c_DiffuseColor = vec3(1);\n\
const float c_LightExponent = 32.0;\n\
\n\
const vec3 c_LightDirection = vec3(0.000, +0.000, 0.900);\n\
\n\
void main()\n\
{\n\
vec3 thisNormal = Normal * FlipNormals;\n\
\n\
// Lighting\n\
vec3 lightDirection = vec3(c_LightDirection.x,c_LightDirection.y,c_LightDirection.z);\n\
\n\
float ndotl = max(0.0, dot(thisNormal, lightDirection));\n\
\n\
v_DiffuseColor = (c_AmbientColor + ndotl * c_DiffuseColor);\n\
\n\
gl_Position = MVPMatrix * vec4(Position, 1);\n\
v_TexCoord = (TextureMatrix * vec3(TexCoord,1)).xy;\n\
}\
",
fragment: "\
\n\
#ifdef GL_ES\n\
precision mediump float;\n\
#endif\n\
\n\
uniform sampler2D Texture;\n\
\n\
varying vec2 v_TexCoord;\n\
varying vec3 v_DiffuseColor;\n\
\n\
void main()\n\
{\n\
vec4 texColor = texture2D(Texture, v_TexCoord);\n\
\n\
// Lighting\n\
texColor.xyz = texColor.xyz * v_DiffuseColor;\n\
gl_FragColor = texColor;\n\
}\
"
};
KNWebGLShader.anvilsmoke = {
attribNames: ["Rotation", "Speed", "Scale", "LifeSpan", "ParticleTexCoord", "Center", "Position"],
uniformNames: ["Percent", "Opacity", "ParticleTexture", "MVPMatrix"],
vertex: "\
\n\
uniform mat4 MVPMatrix;\n\
uniform float Percent;\n\
uniform float Opacity;\n\
\n\
attribute vec2 Position;\n\
attribute vec2 Center;\n\
attribute vec2 ParticleTexCoord;\n\
attribute vec3 Rotation;\n\
attribute vec3 Speed;\n\
attribute float Scale;\n\
attribute vec2 LifeSpan;\n\
\n\
varying vec4 v_Color;\n\
varying vec2 v_TexCoord;\n\
\n\
const float Pi = 3.1415926;\n\
const float Pi_2 = 1.5707963;\n\
const float TwoPi = 6.2831852;\n\
\n\
const float sineConstB = 1.2732396; /* = 4./Pi; */\n\
const float sineConstC = -0.40528476; /* = -4./(Pi*Pi); */\n\
\n\
vec3 fastSine(vec3 angle)\n\
{\n\
vec3 theAngle = mod(angle + Pi, TwoPi) - Pi;\n\
return sineConstB * theAngle + sineConstC * theAngle * abs(theAngle);\n\
}\n\
\n\
mat3 fastRotationMatrix(vec3 theRotation)\n\
{\n\
vec3 sinXYZ = fastSine(theRotation);\n\
vec3 cosXYZ = fastSine(Pi_2 - theRotation);\n\
mat3 rotMatrix = mat3( cosXYZ.y*cosXYZ.z, sinXYZ.x*sinXYZ.y*cosXYZ.z+cosXYZ.x*sinXYZ.z, -cosXYZ.x*sinXYZ.y*cosXYZ.z+sinXYZ.x*sinXYZ.z,\n\
-cosXYZ.y*sinXYZ.z, -sinXYZ.x*sinXYZ.y*sinXYZ.z+cosXYZ.x*cosXYZ.z, cosXYZ.x*sinXYZ.y*sinXYZ.z+sinXYZ.x*cosXYZ.z,\n\
sinXYZ.y, -sinXYZ.x*cosXYZ.y, cosXYZ.x*cosXYZ.y);\n\
return rotMatrix;\n\
}\n\
\n\
void main()\n\
{\n\
float realPercent = (Percent-LifeSpan.x)/LifeSpan.y;\n\
realPercent = clamp(realPercent, 0.0, 1.0);\n\
realPercent = sqrt(realPercent);\n\
\n\
/* SCALE */\n\
vec4 originalPosition = vec4(Position,0,1);\n\
vec4 center = vec4(Center, 0,1);\n\
vec3 scaleDirectionVec = vec3(originalPosition.xy-center.xy,0) * Scale * mix(0.1, 1.0, realPercent);\n\
\n\
/* ROTATE */\n\
mat3 rotMatrix = fastRotationMatrix(Rotation * realPercent);\n\
vec3 rotatedVec = rotMatrix * scaleDirectionVec;\n\
vec4 position = center + vec4(rotatedVec,0);\n\
\n\
float speedAdjust = realPercent;\n\
vec3 thisSpeed = Speed;\n\
thisSpeed.x *= sqrt(realPercent);\n\
thisSpeed.y *= realPercent*realPercent;\n\
position += vec4(thisSpeed, 0);\n\
\n\
float thisOpacity = Opacity;\n\
thisOpacity *= (1.0 - realPercent); /* fade out gradually */\n\
thisOpacity *= min(1.0, realPercent*20.0); /* fade in quickly */\n\
\n\
/* output */\n\
gl_Position = MVPMatrix * position;\n\
//v_Color = vec4(1.0, 1.0, 1.0, thisOpacity); //we applied a fix here, might not work everywhere\n\
v_Color = vec4(thisOpacity);\n\
v_TexCoord = ParticleTexCoord;\n\
}\n\
",
fragment: "\
\n\
#ifdef GL_ES\n\
precision mediump float;\n\
#endif\n\
uniform sampler2D ParticleTexture;\n\
\n\
varying vec4 v_Color;\n\
varying vec2 v_TexCoord;\n\
\n\
void main()\n\
{\n\
vec4 texColor = texture2D(ParticleTexture, v_TexCoord);\n\
\n\
texColor *= v_Color;\n\
\n\
gl_FragColor = texColor;\n\
}\n\
"
};
KNWebGLShader.anvilspeck = {
attribNames: ["Speed", "Scale", "LifeSpan", "ParticleTexCoord", "Center", "Position"],
uniformNames: ["Percent", "Opacity", "ParticleTexture", "MVPMatrix"],
vertex: "\
\n\
uniform mat4 MVPMatrix;\n\
uniform float Percent;\n\
uniform float Opacity;\n\
\n\
attribute vec2 Position;\n\
attribute vec2 Center;\n\
attribute vec2 ParticleTexCoord;\n\
attribute vec3 Speed;\n\
attribute float Scale;\n\
attribute vec2 LifeSpan;\n\
\n\
varying vec4 v_Color;\n\
varying vec2 v_TexCoord;\n\
\n\
const float Pi = 3.1415926;\n\
const float Pi_2 = 1.5707963;\n\
const float TwoPi = 6.2831852;\n\
\n\
const float sineConstB = 1.2732396; /* = 4./Pi; */\n\
const float sineConstC = -0.40528476; /* = -4./(Pi*Pi); */\n\
\n\
vec3 fastSine(vec3 angle)\n\
{\n\
vec3 theAngle = mod(angle + Pi, TwoPi) - Pi;\n\
return sineConstB * theAngle + sineConstC * theAngle * abs(theAngle);\n\
}\n\
\n\
void main()\n\
{\n\
float realPercent = (Percent-LifeSpan.x)/LifeSpan.y;\n\
realPercent = clamp(realPercent, 0.0, 1.0);\n\
\n\
/* SCALE */\n\
vec4 originalPosition = vec4(Position,0,1);\n\
vec4 center = vec4(Center, 0,1);\n\
vec3 thisScale = Scale * vec3(1, Speed.z, 1) * mix(0.1, 1.0, realPercent);\n\
vec3 scaleDirectionVec = vec3(originalPosition.xy-center.xy,0) * thisScale;\n\
\n\
vec4 position = center + vec4(scaleDirectionVec,0);\n\
\n\
float speedAdjust = realPercent;\n\
vec3 thisPos = vec3(Speed.x * realPercent,\n\
Speed.y * fastSine(Pi*0.85*vec3(realPercent,0,0)).x, /* arc with gravity */\n\
0);\n\
position += vec4(thisPos, 0);\n\
\n\
float thisOpacity = Opacity;\n\
thisOpacity *= (1.0 - realPercent); /* fade out gradually */\n\
thisOpacity *= min(1.0, realPercent*20.0); /* fade in quickly */\n\
\n\
/* output */\n\
gl_Position = MVPMatrix * position;\n\
v_Color = vec4(thisOpacity);\n\
v_TexCoord = ParticleTexCoord;\n\
}\
",
fragment: "\
\n\
#ifdef GL_ES\n\
precision mediump float;\n\
#endif\n\
uniform sampler2D ParticleTexture;\n\
\n\
varying vec4 v_Color;\n\
varying vec2 v_TexCoord;\n\
\n\
void main()\n\
{\n\
vec4 texColor = texture2D(ParticleTexture, v_TexCoord);\n\
\n\
texColor *= v_Color;\n\
\n\
gl_FragColor = texColor;\n\
}\
"
};
KNWebGLShader.flame = {
attribNames: ["Rotation", "Speed", "LifeSpan", "ParticleTexCoord", "Center", "Position"],
uniformNames: ["Percent", "Duration", "Opacity", "RotationMax", "SpeedMax", "ParticleTexture", "MVPMatrix"],
vertex: "\
\n\
precision highp float;\n\
\n\
uniform mat4 MVPMatrix;\n\
uniform float Percent;\n\
uniform float Duration;\n\
\n\
attribute vec3 Rotation;\n\
attribute vec3 Speed;\n\
uniform float Opacity;\n\
attribute vec2 LifeSpan;\n\
attribute vec2 ParticleTexCoord;\n\
attribute vec2 Position;\n\
attribute vec2 Center;\n\
\n\
uniform mediump float RotationMax;\n\
uniform mediump float SpeedMax;\n\
\n\
varying vec4 v_Color;\n\
varying vec2 v_TexCoord;\n\
\n\
const float Pi = 3.1415926;\n\
const float Pi_2 = 1.5707963;\n\
const float TwoPi = 6.2831852;\n\
\n\
const float sineConstB = 1.2732396; /* = 4./Pi; */\n\
const float sineConstC = -0.40528476; /* = -4./(Pi*Pi); */\n\
\n\
float fastSine(float angle)\n\
{\n\
float theAngle = mod(angle + Pi, TwoPi) - Pi;\n\
return sineConstB * theAngle + sineConstC * theAngle * abs(theAngle);\n\
}\n\
\n\
const vec4 kStartColor = vec4( 1.0, 1.0, 1.0, 0.0 ); /* white */\n\
const vec4 kMidColor = vec4( 0.97, 1.0, 0.32, 0.0 ); /* yellow */\n\
const vec4 kEndColor = vec4( 0.9, 0.0, 0.0, 0.0 ); /* red */\n\
const float kColorMidPoint = 0.1;\n\
\n\
vec4 flameColor(float aPercent)\n\
{\n\
float thePercent = aPercent;\n\
/* CONSTANTS */\n\
float beginCutoff = 0.4/Duration; /* start slow (not bright white) */\n\
float smokeCutoff = 1.0 - (0.95/Duration); /* end with black, basically */\n\
float alphaCutoff = 1.0 - 0.5/Duration; /* fade out towards the end */\n\
\n\
float alpha = (thePercent < alphaCutoff) ? 1.0 : (1.0-(thePercent-alphaCutoff)/(1.0-alphaCutoff));\n\
vec4 theColor = vec4(0,0,0, alpha * 0.75);\n\
\n\
if (Percent < beginCutoff) {\n\
float colorCutoff = beginCutoff*3.0;\n\
thePercent += mix(colorCutoff, 0.0, Percent/beginCutoff);\n\
}\n\
\n\
if (thePercent < kColorMidPoint) {\n\
float newPercent = thePercent/kColorMidPoint;\n\
theColor += mix(kStartColor, kMidColor, newPercent);\n\
} else {\n\
float newPercent = (thePercent-kColorMidPoint)/(1.0-kColorMidPoint);\n\
theColor += mix(kMidColor, kEndColor, newPercent);\n\
}\n\
\n\
if (Percent > smokeCutoff) {\n\
/* smoke */\n\
float smokeAmount = (Percent - smokeCutoff)/(1.0 - smokeCutoff);\n\
smokeAmount = sqrt(smokeAmount);\n\
smokeAmount *= (0.25+thePercent*thePercent);\n\
theColor = vec4(theColor.rgb * max(0.0, 1.0-smokeAmount), theColor.a);\n\
}\n\
\n\
return theColor;\n\
}\n\
\n\
void main()\n\
{\n\
float realPercent = (Percent-LifeSpan.x)/LifeSpan.y;\n\
bool shouldDiscard = realPercent < 0.0 || realPercent > 1.0;\n\
realPercent = clamp(realPercent, 0.0, 1.0);\n\
\n\
vec4 scaleDirectionVec = vec4(Position-Center,0,0);\n\
\n\
/* ROTATE */\n\
float halfPercent = realPercent/2.0;\n\
vec3 thisRotation = Rotation * RotationMax;\n\
float theRotation = thisRotation.x + thisRotation.z * (halfPercent * (halfPercent + 1.0));\n\
float sinRot = fastSine(theRotation);\n\
float cosRot = fastSine(Pi_2 - theRotation);\n\
mat3 rotMatrix = mat3(cosRot,-sinRot,0, sinRot,cosRot,0, 0,0,1);\n\
vec3 rotatedVec = rotMatrix * scaleDirectionVec.xyz;\n\
\n\
/* SCALE */\n\
float scaleAdjust = (0.1 + 1.0-(1.0-realPercent)*(1.0-realPercent));\n\
vec4 position = vec4(Center,0,1) + vec4(rotatedVec * scaleAdjust * (shouldDiscard ? 0.001 : 1.0), 0);\n\
\n\
/* POSITION */\n\
vec3 thisSpeed = Speed * SpeedMax;\n\
vec4 upVector = vec4(0.0, realPercent*realPercent * -thisSpeed.y, 0.0, 0.0);\n\
position += upVector;\n\
\n\
v_Color = flameColor(realPercent)*Opacity;\n\
gl_Position = MVPMatrix * position;\n\
v_TexCoord = ParticleTexCoord;\n\
}\
",
fragment: "\
\n\
#ifdef GL_ES\n\
precision mediump float;\n\
#endif\n\
uniform sampler2D ParticleTexture;\n\
\n\
varying vec4 v_Color;\n\
varying vec2 v_TexCoord;\n\
\n\
void main()\n\
{\n\
vec4 texColor = texture2D(ParticleTexture, v_TexCoord);\n\
\n\
texColor *= v_Color;\n\
\n\
gl_FragColor = texColor;\n\
}\n\
"
};
KNWebGLShader.confetti = {
attribNames: ["Rotation", "Speed", "TexCoord", "Center", "Position"],
uniformNames: ["Percent", "Opacity", "ParticleTexture", "MVPMatrix"],
vertex: "\
\n\
precision highp float;\n\
uniform mat4 MVPMatrix;\n\
\n\
uniform float Percent;\n\
uniform mediump float Opacity;\n\
\n\
attribute vec2 Position;\n\
attribute vec2 Center;\n\
attribute vec2 TexCoord;\n\
attribute vec3 Rotation;\n\
attribute vec3 Speed;\n\
\n\
varying vec4 v_Color;\n\
varying vec2 v_TexCoord;\n\
\n\
const float Pi = 3.1415926;\n\
const float Pi_2 = 1.5707963;\n\
const float TwoPi = 6.2831852;\n\
\n\
const float sineConstB = 1.2732396;\n\
const float sineConstC = -0.40528476;\n\
\n\
vec3 fastSine(vec3 angle)\n\
{\n\
vec3 theAngle = mod(angle + Pi, TwoPi) - Pi;\n\
return sineConstB * theAngle + sineConstC * theAngle * abs(theAngle);\n\
}\n\
\n\
mat3 fastRotationMatrix(vec3 theRotation)\n\
{\n\
vec3 sinXYZ = fastSine(theRotation);\n\
vec3 cosXYZ = fastSine(Pi_2 - theRotation);\n\
mat3 rotMatrix = mat3( cosXYZ.y*cosXYZ.z, sinXYZ.x*sinXYZ.y*cosXYZ.z+cosXYZ.x*sinXYZ.z, -cosXYZ.x*sinXYZ.y*cosXYZ.z+sinXYZ.x*sinXYZ.z,\n\
-cosXYZ.y*sinXYZ.z, -sinXYZ.x*sinXYZ.y*sinXYZ.z+cosXYZ.x*cosXYZ.z, cosXYZ.x*sinXYZ.y*sinXYZ.z+sinXYZ.x*cosXYZ.z,\n\
sinXYZ.y, -sinXYZ.x*cosXYZ.y, cosXYZ.x*cosXYZ.y);\n\
return rotMatrix;\n\
}\n\
\n\
void main()\n\
{\n\
/* SCALE */\n\
vec4 originalPosition = vec4(Position, 0, 1);\n\
vec3 scaleDirectionVec = vec3(Position-Center,0);\n\
\n\
/* ROTATE */\n\
mat3 rotMatrix = fastRotationMatrix(Rotation * Percent);\n\
vec3 rotatedVec = scaleDirectionVec * rotMatrix;\n\
vec4 position = vec4(Center,0,1) + vec4(rotatedVec,0);\n\
\n\
float colorAdjust = abs((rotMatrix * vec3(0,0,1)).z);\n\
\n\
float speedAdjust = Percent;\n\
position += vec4(Speed, 0) * speedAdjust;\n\
\n\
/* output */\n\
gl_Position = MVPMatrix * position;\n\
v_Color = vec4(vec3(colorAdjust), Opacity);\n\
v_TexCoord = TexCoord;\n\
}\
",
fragment: "\
\n\
precision mediump float;\n\
\n\
uniform sampler2D ParticleTexture;\n\
//uniform float Opacity;\n\
\n\
varying vec4 v_Color;\n\
varying vec2 v_TexCoord;\n\
\n\
void main()\n\
{\n\
vec4 texColor = texture2D(ParticleTexture, v_TexCoord);\n\
\n\
texColor *= v_Color;\n\
//texColor.a = Opacity;\n\
\n\
gl_FragColor = texColor;\n\
}\
"
};
KNWebGLShader.diffuse = {
attribNames: ["Rotation", "Speed", "TexCoord", "Center", "Position", "LifeSpan"],
uniformNames: ["Percent", "Opacity", "ParticleTexture", "MVPMatrix", "RotationMax", "SpeedMax"],
vertex: "\
\n\
precision highp float;\n\
\n\
uniform mat4 MVPMatrix;\n\
\n\
uniform float Percent;\n\
uniform mediump float Opacity;\n\
\n\
attribute vec2 Position;\n\
attribute vec2 Center;\n\
attribute vec2 TexCoord;\n\
\n\
attribute mediump vec3 Rotation;\n\
uniform mediump float RotationMax;\n\
attribute mediump vec3 Speed;\n\
uniform mediump float SpeedMax;\n\
attribute mediump vec2 LifeSpan;\n\
\n\
varying vec4 v_Color;\n\
varying vec2 v_TexCoord;\n\
\n\
const float Pi = 3.1415926;\n\
const float Pi_2 = 1.5707963;\n\
const float TwoPi = 6.2831852;\n\
\n\
const float sineConstB = 1.2732396;\n\
const float sineConstC = -0.40528476;\n\
\n\
vec3 fastSine(vec3 angle)\n\
{\n\
vec3 theAngle = mod(angle + Pi, TwoPi) - Pi;\n\
return sineConstB * theAngle + sineConstC * theAngle * abs(theAngle);\n\
}\n\
\n\
mat3 fastRotationMatrix(vec3 theRotation)\n\
{\n\
vec3 sinXYZ = fastSine(theRotation);\n\
vec3 cosXYZ = fastSine(Pi_2 - theRotation);\n\
mat3 rotMatrix = mat3( cosXYZ.y*cosXYZ.z, sinXYZ.x*sinXYZ.y*cosXYZ.z+cosXYZ.x*sinXYZ.z, -cosXYZ.x*sinXYZ.y*cosXYZ.z+sinXYZ.x*sinXYZ.z,\n\
-cosXYZ.y*sinXYZ.z, -sinXYZ.x*sinXYZ.y*sinXYZ.z+cosXYZ.x*cosXYZ.z, cosXYZ.x*sinXYZ.y*sinXYZ.z+sinXYZ.x*cosXYZ.z,\n\
sinXYZ.y, -sinXYZ.x*cosXYZ.y, cosXYZ.x*cosXYZ.y);\n\
return rotMatrix;\n\
}\n\
\n\
void main()\n\
{\n\
float realPercent = (Percent-LifeSpan.x)/LifeSpan.y;\n\
float doDiscard = (realPercent > 1.0) ? 0.0 : 1.0;\n\
realPercent = clamp(realPercent, 0.0,1.0);\n\
float revPercent = 1.0-realPercent;\n\
\n\
//SCALE\n\
vec4 originalPosition = vec4(Position, 0, 1);\n\
vec3 scaleDirectionVec = vec3(Position-Center,0);\n\
\n\
//ROTATE\n\
vec3 thisRotation = Rotation * RotationMax;\n\
mat3 rotMatrix = fastRotationMatrix(thisRotation * realPercent);\n\
vec3 rotatedVec = scaleDirectionVec * rotMatrix;\n\
vec4 position = vec4(Center,0,1) + vec4(rotatedVec,0) * doDiscard;\n\
\n\
vec3 thisSpeed = Speed * SpeedMax;\n\
float l2r = -thisSpeed.x/abs(thisSpeed.x);\n\
float reverseVector = l2r*(thisSpeed.x+abs(thisSpeed.y)) * realPercent/8.0;\n\
\n\
float speedMultiplier = 1.-pow(revPercent, 2.0);\n\
vec3 dist = thisSpeed * speedMultiplier;\n\
dist.x += reverseVector;\n\
position.xyz += dist;\n\
\n\
float colorAdjust = abs((rotMatrix * vec3(0,0,1)).z);\n\
\n\
//output\n\
gl_Position = MVPMatrix * position;\n\
v_Color = vec4(vec3(colorAdjust), 1) * (revPercent*Opacity);\n\
v_TexCoord = TexCoord;\n\
}\
",
fragment: "\
\n\
precision mediump float;\n\
\n\
uniform sampler2D Texture;\n\
uniform float Opacity;\n\
\n\
varying vec4 v_Color;\n\
varying vec2 v_TexCoord;\n\
\n\
void main()\n\
{\n\
vec4 texColor = texture2D(Texture, v_TexCoord);\n\
\n\
texColor *= v_Color;\n\
\n\
gl_FragColor = texColor;\n\
}\
"
};
KNWebGLShader.fireworks = {
attribNames: ["Color", "Speed", "LifeSpan", "Scale", "ParticleTexCoord", "Center", "Position"],
uniformNames: ["Percent", "PreviousPercent", "Gravity", "StartScale", "ShouldSparkle", "SparklePeriod", "ParticleBurstTiming", "PreviousParticleBurstTiming", "SpeedMax", "ParticleTexture", "Opacity", "MVPMatrix"],
vertex: "\
\n\
precision highp float;\n\
\n\
uniform mat4 MVPMatrix;\n\
\n\
uniform float Percent;\n\
uniform float PreviousPercent;\n\
uniform float Gravity;\n\
uniform float StartScale;\n\
uniform float ShouldSparkle;\n\
uniform float SparklePeriod;\n\
uniform float ParticleBurstTiming;\n\
uniform float PreviousParticleBurstTiming;\n\
uniform float SpeedMax;\n\
\n\
attribute vec2 Position;\n\
attribute vec2 Center;\n\
attribute vec2 ParticleTexCoord;\n\
\n\
attribute vec4 Color;\n\
attribute vec3 Speed;\n\
attribute vec2 LifeSpan;\n\
attribute float Scale;\n\
\n\
varying vec4 v_Color;\n\
varying vec2 v_TexCoord;\n\
\n\
void main()\n\
{\n\
float realPercent = (Percent-LifeSpan.x)/LifeSpan.y;\n\
realPercent = clamp(realPercent, 0.0, 1.0);\n\
\n\
float prevRealPercent = (PreviousPercent-LifeSpan.x)/LifeSpan.y;\n\
prevRealPercent = clamp(prevRealPercent, 0.0,1.0);\n\
\n\
vec4 center = vec4(Center,0,1);\n\
vec4 scaleDirectionVec = vec4(Position-Center,0,0);\n\
\n\
// TRANSLATE\n\
vec3 translation = Speed * (SpeedMax * ParticleBurstTiming); // (1.0-pow(1.0-realPercent, ExplosionPower));\n\
translation.y -= Gravity * (Percent - LifeSpan.x); // Gravity is in terms of global percent, not particle system percent\n\
\n\
vec3 prevTranslation = Speed * (SpeedMax * PreviousParticleBurstTiming);\n\
prevTranslation.y -= Gravity * (PreviousPercent - LifeSpan.x); // Gravity is in terms of global percent, not particle system percent\n\
\n\
vec3 blurOffset = translation - prevTranslation; // Blur in direction of velocity\n\
\n\
// project centerVec onto translationOffset to get direction\n\
blurOffset *= (dot(blurOffset, scaleDirectionVec.xyz) >= 0.0 ? 1.0 : -1.0);\n\
\n\
center.xyz += translation;\n\
\n\
// SCALE\n\
float scalePercent = (1.0-(1.0-realPercent)*(1.0-realPercent));\n\
float scaleAdjust = mix(StartScale, Scale, scalePercent);\n\
// scale down to zero, unless we're sparkling\n\
scaleAdjust *= (ShouldSparkle>0.5 ? 0.25 : 1.0-scalePercent);\n\
vec4 position = center + scaleDirectionVec * scaleAdjust;\n\
position += vec4(blurOffset,0);\n\
\n\
// SPARKLE\n\
float sparkleOpacity = fract(realPercent*realPercent * SparklePeriod);\n\
sparkleOpacity = smoothstep(0.0, 1.0, sparkleOpacity);\n\
\n\
// COLOR\n\
vec4 color = mix(vec4(1), Color, scalePercent * (ShouldSparkle<0.5 ? 1.0 : 0.5)); // white to color\n\
color *= (ShouldSparkle<0.5 ? 1.0 : sparkleOpacity); // apply sparkle opacity\n\
color *= (realPercent>=1.0 ? 0.0 : 1.0);\n\
v_Color = color;\n\
\n\
gl_Position = MVPMatrix * position;\n\
v_TexCoord = ParticleTexCoord;\n\
}\
",
fragment: "\
\n\
precision mediump float;\n\
\n\
uniform sampler2D ParticleTexture;\n\
uniform float Opacity;\n\
\n\
varying vec4 v_Color;\n\
varying vec2 v_TexCoord;\n\
//varying float particleTexPercent;\n\
\n\
void main()\n\
{\n\
vec4 texColor = texture2D(ParticleTexture, v_TexCoord);\n\
\n\
texColor *= v_Color * Opacity;\n\
//texColor.a *= Opacity;\n\
\n\
//texColor = vec4(v_TexCoord, 0, 1);\n\
\n\
gl_FragColor = texColor;\n\
}\
"
};
KNWebGLShader.fireworkstrails = {
attribNames: [ "Position", "TexCoord"],
uniformNames: ["Texture", "Opacity", "NoiseAmount", "NoiseSeed", "NoiseMax", "MVPMatrix"],
vertex: "\
\n\
precision highp float;\n\
\n\
uniform mat4 MVPMatrix;\n\
\n\
attribute vec2 Position;\n\
attribute vec2 TexCoord;\n\
\n\
varying vec2 v_TexCoord;\n\
\n\
void main()\n\
{\n\
gl_Position = MVPMatrix * vec4(Position, 0,1);\n\
v_TexCoord = TexCoord;\n\
}\
",
fragment: "\
precision mediump float;\n\
\n\
uniform sampler2D Texture;\n\
uniform float Opacity;\n\
uniform float NoiseAmount;\n\
uniform vec2 NoiseSeed;\n\
uniform float NoiseMax;\n\
\n\
//varying vec4 v_Color;\n\
varying vec2 v_TexCoord;\n\
//varying float particleTexPercent;\n\
\n\
float rand(vec2 co){\n\
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n\
}\n\
\n\
float inverseSquare(float a) {\n\
return 1.0-(1.0-a)*(1.0-a);\n\
}\n\
\n\
void main()\n\
{\n\
vec4 texColor = texture2D(Texture, v_TexCoord);\n\
\n\
//texColor = bloom(texColor);\n\
\n\
// Dither transparency to add noise\n\
float randomNoise = NoiseMax*rand(v_TexCoord*NoiseSeed);\n\
float randomAmount = NoiseAmount * 1.5*max(0.0, texColor.a-0.3333);\n\
\n\
float thisOpacity = Opacity * mix(1.0, randomNoise, randomAmount);\n\
texColor *= thisOpacity;\n\
\n\
//texColor = vec4(v_TexCoord, 0, 1);\n\
\n\
gl_FragColor = texColor;\n\
}\
"
};
KNWebGLShader.horizontalGaussianBlur = {
attribNames: [ "Position"],
uniformNames: ["Texture", "TextureSize", "MVPMatrix"],
vertex: "\
\n\
precision highp float;\n\
\n\
uniform mat4 MVPMatrix;\n\
\n\
attribute vec2 Position;\n\
\n\
void main()\n\
{\n\
gl_Position = MVPMatrix * vec4(Position, 0, 1);\n\
}\
",
fragment: "\
precision highp float;\n\
\n\
uniform sampler2D Texture;\n\
uniform vec2 TextureSize;\n\
\n\
const vec2 offset1 = vec2(1.3846153846, 0);\n\
const vec2 offset2 = vec2(3.2307692308, 0);\n\
const float weight0 = 0.2270270270;\n\
const float weight1 = 0.3162162162;\n\
const float weight2 = 0.0702702703;\n\
\n\
void main()\n\
{\n\
vec4 color = texture2D(Texture, gl_FragCoord.xy*TextureSize) * weight0;\n\
\n\
color += texture2D(Texture, (gl_FragCoord.xy + offset1)*TextureSize) * weight1;\n\
color += texture2D(Texture, (gl_FragCoord.xy - offset1)*TextureSize) * weight1;\n\
\n\
color += texture2D(Texture, (gl_FragCoord.xy + offset2)*TextureSize) * weight2;\n\
color += texture2D(Texture, (gl_FragCoord.xy - offset2)*TextureSize) * weight2;\n\
\n\
gl_FragColor = color;\n\
}\
"
};
KNWebGLShader.verticalGaussianBlur = {
attribNames: [ "Position"],
uniformNames: ["Texture", "TextureSize", "MVPMatrix"],
vertex: "\
\n\
precision highp float;\n\
\n\
uniform mat4 MVPMatrix;\n\
\n\
attribute vec2 Position;\n\
\n\
void main()\n\
{\n\
gl_Position = MVPMatrix * vec4(Position, 0, 1);\n\
}\
",
fragment: "\
precision highp float;\n\
\n\
uniform sampler2D Texture;\n\
uniform vec2 TextureSize;\n\
\n\
const vec2 offset1 = vec2(0, 1.3846153846);\n\
const vec2 offset2 = vec2(0, 3.2307692308);\n\
const float weight0 = 0.2270270270;\n\
const float weight1 = 0.3162162162;\n\
const float weight2 = 0.0702702703;\n\
\n\
void main()\n\
{\n\
vec4 color = texture2D(Texture, gl_FragCoord.xy*TextureSize) * weight0;\n\
\n\
color += texture2D(Texture, (gl_FragCoord.xy + offset1)*TextureSize) * weight1;\n\
color += texture2D(Texture, (gl_FragCoord.xy - offset1)*TextureSize) * weight1;\n\
\n\
color += texture2D(Texture, (gl_FragCoord.xy + offset2)*TextureSize) * weight2;\n\
color += texture2D(Texture, (gl_FragCoord.xy - offset2)*TextureSize) * weight2;\n\
\n\
gl_FragColor = color;\n\
}\
"
};
KNWebGLShader.bloom = {
attribNames: [ "Position", "TexCoord"],
uniformNames: ["Texture", "BlurTexture", "BloomAmount", "MVPMatrix"],
vertex: "\
\n\
precision highp float;\n\
\n\
uniform mat4 MVPMatrix;\n\
\n\
attribute vec2 Position;\n\
attribute vec2 TexCoord;\n\
\n\
varying vec2 v_TexCoord;\n\
\n\
void main()\n\
{\n\
v_TexCoord = TexCoord;\n\
gl_Position = MVPMatrix * vec4(Position, 0, 1);\n\
}\
",
fragment: "\
precision mediump float;\n\
\n\
uniform sampler2D Texture;\n\
uniform sampler2D BlurTexture;\n\
uniform float BloomAmount;\n\
\n\
varying vec2 v_TexCoord;\n\
\n\
void main()\n\
{\n\
vec4 color = texture2D(Texture, v_TexCoord);\n\
vec4 blurColor = texture2D(BlurTexture, v_TexCoord);\n\
\n\
color += (blurColor + color) * BloomAmount;\n\
gl_FragColor = color;\n\
}\
"
};
KNWebGLShader.shimmerObject = {
attribNames: [ "Position", "Center", "TexCoord", "Color", "Speed"],
uniformNames: ["Percent", "Opacity", "RotationMatrix", "SpeedMax", "Texture", "MVPMatrix"],
vertex: "\
\n\
precision highp float;\n\
\n\
uniform mat4 MVPMatrix;\n\
uniform float Percent;\n\
uniform float Opacity;\n\
\n\
uniform mat3 RotationMatrix;\n\
\n\
attribute vec2 Position;\n\
attribute vec2 Center;\n\
attribute vec2 TexCoord;\n\
attribute vec4 Color;\n\
\n\
attribute vec3 Speed;\n\
uniform float SpeedMax;\n\
\n\
varying vec4 v_Color;\n\
varying vec2 v_TexCoord;\n\
\n\
void main()\n\
{\n\
float thisPercent = Percent;\n\
float invPercent = 1.0-thisPercent;\n\
float thisPercent2 = thisPercent*thisPercent;\n\
\n\
/* CENTER */\n\
vec3 scaleDirectionVec = vec3((Position.x-Center.x),(Position.y-Center.y),0);\n\
\n\
/* ROTATE */\n\
vec3 rotatedVec = RotationMatrix * scaleDirectionVec.xyz;\n\
\n\
/* SCALE */\n\
float scale = invPercent;\n\
vec4 position = vec4(Center.xy,0,1) + vec4(rotatedVec,0) * scale;\n\
\n\
vec3 thisSpeed = Speed * SpeedMax;\n\
position.xyz += thisSpeed * thisPercent*(3.0 + mix(thisPercent2*thisPercent, 1.0-invPercent*invPercent, thisPercent2));\n\
\n\
vec4 outColor = Color;\n\
outColor = vec4(Opacity);\n\
\n\
/* output */\n\
gl_Position = MVPMatrix * position;\n\
v_Color = outColor;\n\
v_TexCoord = TexCoord;\n\
}\n\
",
fragment: "\
precision mediump float;\n\
\n\
uniform sampler2D Texture;\n\
\n\
varying vec4 v_Color;\n\
varying vec2 v_TexCoord;\n\
\n\
void main()\n\
{\n\
vec4 color = texture2D(Texture, v_TexCoord);\n\
\n\
color *= v_Color;\n\
\n\
gl_FragColor = color;\n\
}\
"
};
KNWebGLShader.shimmerParticle = {
attribNames: [ "Position", "Center", "ParticleTexCoord", "Color", "LifeSpan", "Speed", "Scale"],
uniformNames: ["Percent", "Opacity", "ParticleScalePercent", "RotationMatrix", "SpeedMax", "ParticleTexture", "MVPMatrix"],
vertex: "\
\n\
precision highp float;\n\
\n\
uniform mat4 MVPMatrix;\n\
uniform float Percent;\n\
uniform float Opacity;\n\
\n\
uniform float ParticleScalePercent;\n\
uniform mat3 RotationMatrix;\n\
\n\
attribute vec2 Position;\n\
attribute vec2 Center;\n\
attribute vec2 ParticleTexCoord;\n\
attribute vec4 Color;\n\
attribute vec2 LifeSpan;\n\
\n\
attribute vec3 Speed;\n\
uniform float SpeedMax;\n\
attribute float Scale;\n\
\n\
varying vec4 v_Color;\n\
varying vec2 v_TexCoord;\n\
\n\
float scaleUpDown(float x) {\n\
float result = 1.0 - abs(2.0*(x-0.5));\n\
result *= result;\n\
return result;\n\
}\n\
\n\
void main()\n\
{\n\
/* LIFESPAN */\n\
float realPercent = (Percent-LifeSpan.x)/LifeSpan.y;\n\
float doDiscard = (realPercent > 1.0 || realPercent < 0.0) ? 0.0 : 1.0;\n\
realPercent = clamp(realPercent, 0.0,1.0);\n\
float realPercent2 = realPercent*realPercent;\n\
float invPercent2 = 1.0-realPercent;\n\
invPercent2 *= invPercent2;\n\
\n\
vec3 scaleDirectionVec = vec3((Position.x-Center.x),(Position.y-Center.y),0);\n\
\n\
/* ROTATE */\n\
vec3 rotatedVec = RotationMatrix * scaleDirectionVec.xyz;\n\
\n\
/* SCALE */\n\
float scalePercent = (LifeSpan.x <= 0.001 ? ParticleScalePercent : scaleUpDown(realPercent));\n\
float scale = scalePercent * Scale * doDiscard;\n\
vec4 position = vec4(Center,0,1) + vec4(rotatedVec,0) * scale;\n\
\n\
vec3 thisSpeed = Speed * SpeedMax;\n\
position.xyz += thisSpeed * realPercent*(3.0 + mix(realPercent*realPercent2, 1.0-invPercent2, realPercent2));\n\
\n\
// Only adjust opacity on particles that last the duration of the animation\n\
float thisOpacity = (LifeSpan.x <= 0.001 ? Opacity : 1.0);\n\
vec4 color = vec4(Color.rgb, 1) * thisOpacity;\n\
\n\
v_Color = color;\n\
v_TexCoord = ParticleTexCoord;\n\
gl_Position = MVPMatrix * position;\n\
}\n\
",
fragment: "\
precision mediump float;\n\
\n\
uniform sampler2D ParticleTexture;\n\
\n\
varying vec4 v_Color;\n\
varying vec2 v_TexCoord;\n\
\n\
void main()\n\
{\n\
vec4 color = texture2D(ParticleTexture, v_TexCoord);\n\
\n\
color *= v_Color;\n\
\n\
gl_FragColor = color;\n\
}\
"
};
KNWebGLShader.sparkle = {
attribNames: ["Scale", "LifeSpan", "Speed", "ParticleTexCoord", "Center", "Position"],
uniformNames: ["Percent", "Opacity", "Color", "SpeedMax", "ParticleTexture", "MVPMatrix"],
vertex: "\
\n\
precision highp float;\n\
\n\
uniform mat4 MVPMatrix;\n\
uniform float Percent;\n\
\n\
attribute vec2 Position;\n\
attribute vec2 Center;\n\
uniform float Opacity;\n\
attribute vec2 ParticleTexCoord;\n\
uniform vec4 Color;\n\
\n\
attribute mediump vec3 Speed;\n\
uniform mediump float SpeedMax;\n\
attribute mediump float Scale;\n\
attribute mediump vec2 LifeSpan;\n\
\n\
varying vec4 v_Color;\n\
varying vec2 v_TexCoord;\n\
\n\
float ReverseSquareOfFloat(float f) {\n\
return 1.0 - (1.0-f)*(1.0-f);\n\
}\n\
\n\
void main()\n\
{\n\
float doDiscard = 0.0;\n\
float realPercent = (Percent-LifeSpan.x)/LifeSpan.y;\n\
if (realPercent < 0.0 || realPercent > 1.0) {\n\
doDiscard = 1.0;\n\
realPercent = 1.0;\n\
}\n\
\n\
vec4 position;\n\
vec4 scaleDirectionVec = vec4((Position.x-Center.x),(Position.y-Center.y),0,0);\n\
\n\
// SCALE\n\
float scaleAdjust = realPercent;\n\
if (scaleAdjust < 0.1) {\n\
scaleAdjust /= 0.1;\n\
scaleAdjust = sqrt(scaleAdjust);\n\
} else {\n\
scaleAdjust = 1.0-(scaleAdjust-0.1)/0.9;\n\
scaleAdjust = scaleAdjust*scaleAdjust*scaleAdjust;\n\
}\n\
scaleAdjust *= (doDiscard==0.0 ? 1.0 : 0.0);\n\
position = vec4(Center,0,1) + scaleDirectionVec * scaleAdjust * Scale;\n\
\n\
// POSITION\n\
vec3 thisSpeed = Speed * SpeedMax;\n\
position += vec4(thisSpeed, 0) * realPercent;\n\
\n\
float invPercent = 1.0 - realPercent;\n\
vec3 rgbColor = mix(Color.rgb, vec3(1,1,1), invPercent*invPercent*invPercent);\n\
\n\
/* output */\n\
gl_Position = MVPMatrix * position;\n\
v_Color = vec4(rgbColor, (1.0-realPercent*realPercent)*Opacity);\n\
v_TexCoord = ParticleTexCoord;\n\
}\
",
fragment: "\
\n\
precision mediump float;\n\
\n\
uniform sampler2D ParticleTexture;\n\
\n\
varying vec4 v_Color;\n\
varying vec2 v_TexCoord;\n\
\n\
void main()\n\
{\n\
vec4 texColor = texture2D(ParticleTexture, v_TexCoord);\n\
\n\
texColor *= v_Color;\n\
\n\
gl_FragColor = texColor;\n\
}\
"
};