本文参考自:http://www.renjihe.com/index.php/archives/776
放大效果:
缩小效果:
片元着色器代码:
[cpp]view plaincopy
constfloatin_circle_radius = 96.;//从客户端传入的放大镜圆半径
constfloatin_zoom_times = 2.;//从客户端传入的放大镜放大倍数
constfloatimageWidth = 640.;//从客户端传入的图片宽数据
constfloatimageHeight = 640.;//从客户端传入的图片高数据
uniform sampler2D Texture0;
varying vec2 vUV;
vec2 in_circle_pos = vec2(320., imageHeight-320.);//从客户端传入的放大镜圆心位置
// 转换为纹理范围
vec2 transForTexPosition(vec2 pos)
{
returnvec2(float(pos.x/imageWidth),float(pos.y/imageHeight));
}
// Distance of Points
floatgetDistance(vec2 pos_src, vec2 pos_dist)
{
floatquadratic_sum = pow((pos_src.x - pos_dist.x), 2.) + pow((pos_src.y - pos_dist.y), 2.);
returnsqrt(quadratic_sum);
}
vec2 getZoomPosition()
{// zoom_times>1. 是放大, 0.< zoom_times <1.是缩小
floatzoom_x =float(gl_FragCoord.x-in_circle_pos.x) / in_zoom_times;
floatzoom_y =float(gl_FragCoord.y-in_circle_pos.y) / in_zoom_times;
returnvec2(float(in_circle_pos.x + zoom_x),float(-in_circle_pos.y + zoom_y));
}
vec4 getColor()
{
// ❤
vec2 pos = getZoomPosition();
float_x = floor(pos.x);
float_y = floor(pos.y);
floatu = pos.x - _x;
floatv = pos.y - _y;
//双线性插值采样
vec4 data_00 = texture2D(Texture0, transForTexPosition(vec2(_x, _y)));
vec4 data_01 = texture2D(Texture0, transForTexPosition(vec2(_x, _y + 1.)));
vec4 data_10 = texture2D(Texture0, transForTexPosition(vec2(_x + 1., _y)));
vec4 data_11 = texture2D(Texture0, transForTexPosition(vec2(_x + 1., _y + 1.)));
return(1. - u) * (1. - v) * data_00 + (1. - u) * v * data_01 + u * (1. - v) * data_10 + u * v * data_11;
}
voidmain(void)
{
vec2 frag_pos = vec2(gl_FragCoord.x, gl_FragCoord.y);
//若当前片段位置距放大镜圆心距离大于圆半径时,直接从纹理中采样输出片段颜色
if(getDistance(in_circle_pos, frag_pos) > in_circle_radius)
gl_FragColor = texture2D(Texture0, vUV);
else
//距离小于半径的片段,二次线性插值获得顔色。
gl_FragColor = getColor();
}