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
}