static string m_FragShader =
@"uniform sampler2D texture; //new texture
uniform vec4 sv_Aspect; //aspect: [width, height, 1/width, 1/height]
uniform vec2 sv_Zoom; //zoom: [zoom, zoom_exp]
uniform vec2 sv_CenRot; //center of rotation: [cen_x, cen_y]
uniform vec2 sv_Stretch; //stretching: [stretch_x, stretch_y]
uniform vec2 sv_Rot; //rotation: [cos(rot), sin(rot)]
uniform vec2 sv_Trans; //translation: [dx, dy]
uniform vec4 sv_ColDamp; //color dampening: [color add, color mult, alpha add, alpha mult]
void main()
{
//get initial tex coord
vec2 uv = gl_TexCoord[0].xy;
//scale to [-1, 1] and calculate radius
uv = 2 * uv * sv_Aspect.zw - vec2(1, 1);
float rad = sqrt(uv.x * uv.x + uv.y * uv.y);
//apply zoom
uv /= pow(sv_Zoom.x, pow(sv_Zoom.y, rad));
//center to center of rotation
vec2 CR = 2 * (sv_CenRot - vec2(0.5, 0.5));
uv -= CR;
//apply stretching and rotation
uv /= sv_Stretch;
uv = vec2(uv.x * sv_Rot.x - uv.y * sv_Rot.y
, uv.x * sv_Rot.y + uv.y * sv_Rot.x);
//return to 0, 0 center and apply translation
uv += CR;
uv += 2 * sv_Trans;
//convert to regular coords, and sample
uv = 0.5 * sv_Aspect.xy * (uv + vec2(1, 1));
vec4 pixel = texture2D(texture, uv);
//apply color dampening and output
pixel.rgb = sv_ColDamp.y * (pixel.rgb - sv_ColDamp.xxx);
pixel.a = sv_ColDamp.w * (pixel.a - sv_ColDamp.z);
gl_FragColor = pixel;
}";
//...
static void LoadShader()
{
m_Shader = Shader.FromString(null, m_FragShader);
m_Shader.SetParameter("texture", Shader.CurrentTexture);
//aspect info (for scaling)
m_Shader.SetParameter("sv_Aspect", (float)m_Width, (float)m_Height, 1f / (float)m_Width, 1f / (float)m_Height);
//MOTION VARS
//EACH EFFECT PROCESSED 1/FRAME
//
// zoom: > 0
// 0 < zoom < 1 - zooms out
// 1 < zoom - zooms in
// zoom_exp: > 0
// cen_x/cen_y: each in 0...1
// 0 is far left/top
// 1 is far right/bottom
// stretch_x/stretch_y: both > 0
// 0 < stretch < 1 - compresses
// 1 < stretch - stretches
// rot:
// rot < 0 - cw
// rot > 0 - ccw
// trans_x/trans_y:
// trans < 0 moves left/up
// trans > 0 moves right/down
// color dampening: each in 0...1
// subtractive removes linearly from color/alpha
// multiplicative scales color/alpha towards 0 (after subtraction)
//zoom: [zoom, zoom_exp]
m_Shader.SetParameter("sv_Zoom", 1f, 1f);
//center of rotation: [cen_x, cen_y]
m_Shader.SetParameter("sv_CenRot", 0.5f, 0.5f);
//stretching: [stretch_x, stretch_y]
m_Shader.SetParameter("sv_Stretch", 1f, 1f);
//rotation: [cos(rot), sin(rot)]
float rot = 0f;
m_Shader.SetParameter("sv_Rot", (float)Math.Cos(rot), (float)Math.Sin(rot));
//translation: [trans_x, trans_y]
m_Shader.SetParameter("sv_Trans", 0f, 0f);
//color dampening: [color subtractive, color multiplicative, alpha subtractive, alpha multiplicative]
m_Shader.SetParameter("sv_ColDamp", 0.002f, 0.98f, 0f, 1f);
}