nuclear@13: uniform sampler2D tex; nuclear@13: uniform float aspect, scale; nuclear@13: uniform float lens_center_offset; nuclear@13: uniform vec4 dist_factors; nuclear@18: uniform vec2 tex_scale; nuclear@13: nuclear@14: vec2 distort_texcoords(in vec2 tc); nuclear@13: float barrel_scale(float x, in vec4 k); nuclear@13: nuclear@13: void main() nuclear@13: { nuclear@14: vec2 tc = distort_texcoords(gl_TexCoord[0].xy); nuclear@13: nuclear@18: float vis = any(greaterThan(tc, vec2(1.0))) || any(lessThan(tc, vec2(0.0))) ? 0.0 : 1.0; nuclear@14: nuclear@18: gl_FragColor.rgb = texture2D(tex, tc * tex_scale).rgb * vis; nuclear@13: gl_FragColor.a = 1.0; nuclear@13: } nuclear@13: nuclear@14: vec2 distort_texcoords(in vec2 tc) nuclear@13: { nuclear@13: // map tc [0, 1] -> [-1, 1] nuclear@13: vec2 pt = tc * 2.0 - 1.0; nuclear@13: nuclear@13: pt.x += lens_center_offset * 2.0; nuclear@13: pt.y /= aspect; // correct for aspect ratio nuclear@13: nuclear@13: float rad = barrel_scale(dot(pt, pt), dist_factors); nuclear@13: pt *= rad; // scale the point by the computer distortion radius nuclear@13: nuclear@14: pt /= scale; nuclear@13: pt.y *= aspect; nuclear@13: pt.x -= lens_center_offset * 2.0; nuclear@13: nuclear@13: // map back to range [0, 1] nuclear@13: return pt * 0.5 + 0.5; nuclear@13: } nuclear@13: nuclear@13: float barrel_scale(float rad, in vec4 k) nuclear@13: { nuclear@13: float radsq = rad * rad; nuclear@13: float radquad = radsq * radsq; nuclear@13: return k.x + k.y * radsq + k.z * radquad + k.w * radquad * radsq; nuclear@13: }