我试图找到一种方法,将我的场景缩放到用户鼠标所在的位置。我发送到我的片段着色器uniform float scale
变量,并通过此变量乘以全景图和图像的坐标。但它只能缩放到画布中间。 Scale
变量的值可以达到1.到0.2。
这是我的画布里面有全景和图像的场景:
这是我的片段着色器:
precision highp float;
uniform float used_img_width;
uniform float used_img_height;
uniform float used_pano_width;
uniform float used_pano_height;
uniform float yaw;
uniform float pitch;
uniform float roll;
uniform float scale;
uniform float hfov;
varying vec2 screenPos;
uniform float cyl_radius;
uniform sampler2D foto;
uniform sampler2D panorama;
#define M_PI 3.1415926535897932384626433832795
mat4 makeTranslation(float tx, float ty, float tz) {
return mat4(
1., 0., 0., 0.,
0., 1., 0., 0.,
0., 0., 1., 0.,
tx, ty, tz, 1.
);
}
mat4 makeZRotation(float angleInDegrees) {
float angleInRadians = angleInDegrees * M_PI / 180.;
float c = cos(angleInRadians);
float s = sin(angleInRadians);
return mat4(
c, s, 0., 0.,
-s, c, 0., 0.,
0., 0., 1., 0.,
0., 0., 0., 1.
);
}
mat4 makeScale(float s) {
return mat4(
s, 0., 0., 0.,
0., s, 0., 0.,
0., 0., s, 0.,
0., 0., 0., 1.
);
}
mat4 myW2N(float ax, float ay, float zNear, float zFar) {
float cx = 1.0 / ax;
float cy = 1.0 / ay;
float z0 = -zNear;
float z1 = -zFar;
float az = (z0 + z1) / (z0 - z1);
float bz = (1. - az) * z0;
return mat4(
cx, 0., 0., 0.,
0., cy, 0., 0.,
0., 0., az, bz,
0., 0., -1., 0.
);
}
mat3 rotationW2R() {
return mat3(
0., 0., 1.,
1., 0., 0.,
0., 1., 0.
);
}
void main() {
float move_y = -1. * (pitch / (90. / (used_pano_height / used_img_height))); // pro pohyb po y-ove ose
float centre_y = pitch / 90.;
float condition_width = (used_img_width*0.6) / (used_pano_width*0.5) + ((1.-scale)*0.5);
float condition_height = (used_img_height*1.) / (used_pano_height*0.1) + (1.-scale);
float yaw2 = yaw + 270.;
if(yaw2 > 360.) yaw2 = yaw2 - 360.;
if(yaw2 < 0.) yaw2 = 360.- yaw2;
vec2 q = vec2(used_pano_width / used_img_width, used_pano_height / used_img_height);
vec2 fotoCoord = screenPos * q * scale; // image zoom
vec2 panoramaCoord = (screenPos * scale + 1.) * 0.5; // panorama zoom
panoramaCoord.x += yaw2 / 360.;
if( panoramaCoord.x > 1. ) panoramaCoord.x--;
if( screenPos.x > condition_width || screenPos.x < -condition_width || screenPos.y > (centre_y + condition_height) ||
screenPos.y < (centre_y - condition_height) ) {
vec4 c = texture2D(panorama, panoramaCoord);
gl_FragColor = vec4(c.rgb, 1.);
return;
}
else {
float a = fotoCoord.x;
float z = fotoCoord.y;
float radius = used_pano_width / (2. * M_PI);
vec3 d = rotationW2R() * radius * vec3(cos(a), sin(a), z);
float hFOV = hfov * 0.1; //TODO: based on EXIF
float aspectRatio = 1.5; //TODO: based on EXIF (used_img_width/used_img_height)
float ax = tan(hFOV * M_PI);
float ay = ax / aspectRatio;
mat4 res = makeZRotation(roll) * makeTranslation(0., move_y, 0.) * myW2N(ax,ay,6.,2.);
vec4 q1 = res * vec4(d, 1.);
vec2 p = q1.xy / q1.w;
p = 0.5 * (p + 1.0);
if (q1.w < 0. || any(lessThan(p, vec2(0.0,0.0))) || any(greaterThan(p, vec2(1.0,1.0)))) {
vec4 c = texture2D(panorama, panoramaCoord);
gl_FragColor = vec4(c.rgb, 1.0);
return;
}
vec4 c = texture2D(foto, p);
gl_FragColor = vec4(c.rgb, 1.0);
return;
}
}
拜托,有什么方法可以解决它吗?