|
shun_iwasawa |
36e06f |
#ifdef GL_ES
|
|
shun_iwasawa |
36e06f |
precision mediump float;
|
|
shun_iwasawa |
36e06f |
#endif
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
uniform mat3 worldToOutput;
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
uniform vec4 outputRect;
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
varying vec4 inputRect[1];
|
|
shun_iwasawa |
36e06f |
varying mat3 worldToInput[1];
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
uniform vec2 center;
|
|
shun_iwasawa |
36e06f |
uniform float radius;
|
|
shun_iwasawa |
36e06f |
uniform float blur;
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
float det(mat3 m) { return m[0][0] * m[1][1] - m[0][1] * m[1][0]; }
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
float scale = sqrt(abs(det(worldToOutput)));
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
vec2 center_ = (worldToOutput * vec3(center, 1.0)).xy;
|
|
shun_iwasawa |
36e06f |
float rad_ = scale * max(radius, 0.0);
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
const float pi = 3.141592653;
|
|
shun_iwasawa |
36e06f |
const float pi_twice = 2.0 * pi;
|
|
shun_iwasawa |
36e06f |
const float pi_half = pi / 2.0;
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
void addPoint(inout vec4 rect, vec2 p) {
|
|
shun_iwasawa |
36e06f |
rect.xy = min(rect.xy, p.xy);
|
|
shun_iwasawa |
36e06f |
rect.zw = max(rect.zw, p.xy);
|
|
shun_iwasawa |
36e06f |
}
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
void addBlurredPointBox(inout vec4 rect, vec2 p)
|
|
shun_iwasawa |
36e06f |
{
|
|
shun_iwasawa |
36e06f |
// Remember the *definition* of angle: angle = arc length / radius
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
// Build p's blurred angular range
|
|
shun_iwasawa |
36e06f |
float distance = length(p - center_);
|
|
shun_iwasawa |
36e06f |
float angle = atan(p.y - center_.y, p.x - center_.x);
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
// If rad_ > 0, we assume that the blurred length is proportional to (distance - rad_);
|
|
shun_iwasawa |
36e06f |
float dist_ = max(distance - rad_, 0.0);
|
|
shun_iwasawa |
36e06f |
float blurLen = radians(max(blur, 0.0)) * dist_;
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
// The actual blurring angle is then found as (blurLen_ / distance)
|
|
shun_iwasawa |
36e06f |
float blur_ = blurLen / max(distance, 0.01); // Jump the singularity
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
vec2 angleRange = vec2(angle - blur_, angle + blur_); // Couldn't make it an array with
|
|
shun_iwasawa |
36e06f |
// explicit initialization... GLSL complained -.-
|
|
shun_iwasawa |
36e06f |
// Include the points at angleRange's extremes
|
|
shun_iwasawa |
36e06f |
addPoint(rect, center_ + distance * vec2(cos(angleRange.x), sin(angleRange.x)));
|
|
shun_iwasawa |
36e06f |
addPoint(rect, center_ + distance * vec2(cos(angleRange.y), sin(angleRange.y)));
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
// At pi/2 multiples we get a box extreme. Include them if present.
|
|
shun_iwasawa |
36e06f |
float blur_twice = 2.0 * blur_;
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
if(mod( - angleRange.x, pi_twice) < blur_twice)
|
|
shun_iwasawa |
36e06f |
addPoint(rect, center_ + vec2(distance, 0.0));
|
|
shun_iwasawa |
36e06f |
if(mod(pi_half - angleRange.x, pi_twice) < blur_twice)
|
|
shun_iwasawa |
36e06f |
addPoint(rect, center_ + vec2(0.0, distance));
|
|
shun_iwasawa |
36e06f |
if(mod(pi - angleRange.x, pi_twice) < blur_twice)
|
|
shun_iwasawa |
36e06f |
addPoint(rect, center_ + vec2(-distance, 0.0));
|
|
shun_iwasawa |
36e06f |
if(mod(-pi_half - angleRange.x, pi_twice) < blur_twice)
|
|
shun_iwasawa |
36e06f |
addPoint(rect, center_ + vec2(0.0, -distance));
|
|
shun_iwasawa |
36e06f |
}
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
void main( void )
|
|
shun_iwasawa |
36e06f |
{
|
|
shun_iwasawa |
36e06f |
worldToInput[0] = worldToOutput; // Let the input and output references be the same
|
|
shun_iwasawa |
36e06f |
inputRect[0] = outputRect;
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
// Add the bounding box of each blurred corner
|
|
shun_iwasawa |
36e06f |
addBlurredPointBox(inputRect[0], outputRect.xy);
|
|
shun_iwasawa |
36e06f |
addBlurredPointBox(inputRect[0], outputRect.xw);
|
|
shun_iwasawa |
36e06f |
addBlurredPointBox(inputRect[0], outputRect.zy);
|
|
shun_iwasawa |
36e06f |
addBlurredPointBox(inputRect[0], outputRect.zw);
|
|
shun_iwasawa |
36e06f |
|
|
shun_iwasawa |
36e06f |
gl_Position = vec4(0.0); // Does not link without
|
|
shun_iwasawa |
36e06f |
}
|