Three.js中等矩形全景图Y轴偏移异常问题求助
问题:全景纹理的Y轴上下偏移实现错误
我有一个混合两张全景等矩形纹理的网格,需要通过设置X/Y轴角度单独偏移其中一张纹理。目前X轴左右偏移正常,但Y轴角度设置后,纹理是顺时针旋转而非上下偏移,调整旋转顺序也未解决问题。
现有代码
JavaScript 控制代码
// 用法: applyOffset(90, 90); 第一个参数是左右偏移角度,第二个是上下偏移角度 const applyOffset = (xAngle, yAngle) => { const offsetXradians = xAngle * (Math.PI / 180.0); const offsetYradians = yAngle * (Math.PI / 180.0); uniforms['offset0'].value.set(offsetXradians, offsetYradians, 0); }; // uniform定义: uniforms['offset0'] = { type: "v3", value: new THREE.Vector3(0, 0, 0) }
GLSL 旋转矩阵函数
mat3 rotationMatrix3(vec3 angles) { mat3 rotationX = mat3(1, 0, 0, 0, cos(angles.x), sin(angles.x), 0, -sin(angles.x), cos(angles.x)); mat3 rotationY = mat3(cos(angles.y), 0, -sin(angles.y), 0, 1, 0, sin(angles.y), 0, cos(angles.y)); mat3 rotationZ = mat3(cos(angles.z), sin(angles.z), 0, -sin(angles.z), cos(angles.z), 0, 0, 0, 1); return rotationX * rotationY * rotationZ; }
片元着色器核心代码
void main() { vec3 vWorldPositionScaled0 = mix(vWorldPosition, tCubePosition0, scale0); vWorldPositionScaled0.x *= -1.0; vec3 vWorldPositionScaled1 = mix(vWorldPosition, tCubePosition1, scale1); vWorldPositionScaled1.x *= -1.0; vec4 tex0, tex1; mat3 rotationMatrix0 = rotationMatrix3(offset0); vWorldPositionScaled0 = rotationMatrix0 * vWorldPositionScaled0; mat3 rotationMatrix1 = rotationMatrix3(offset1); vWorldPositionScaled1 = rotationMatrix1 * vWorldPositionScaled1; tex0 = textureCube(tCube0, vec3( tFlip * vWorldPositionScaled0.x, vWorldPositionScaled0.yz )); tex1 = textureCube(tCube1, vec3( tFlip * vWorldPositionScaled1.x, vWorldPositionScaled1.yz )); gl_FragColor = mix(tex1, tex0, mixAlpha); }
解决方案
问题核心是旋转轴与控制参数的对应关系错误:你期望Y轴角度控制上下偏移(纬度方向),但当前代码将Y轴角度绑定到绕Y轴的旋转(这会改变经度,导致左右旋转);而上下偏移需要绕X轴旋转,左右偏移需要绕Y轴旋转。
修改后的旋转矩阵函数
mat3 rotationMatrix3(vec3 angles) { // angles.x: 左右偏移角度(对应绕Y轴旋转) // angles.y: 上下偏移角度(对应绕X轴旋转) // 绕X轴旋转:控制上下偏移(修改采样坐标的纬度分量) mat3 rotationX = mat3( 1.0, 0.0, 0.0, 0.0, cos(angles.y), sin(angles.y), 0.0, -sin(angles.y), cos(angles.y) ); // 绕Y轴旋转:控制左右偏移(修改采样坐标的经度分量) mat3 rotationY = mat3( cos(angles.x), 0.0, -sin(angles.x), 0.0, 1.0, 0.0, sin(angles.x), 0.0, cos(angles.x) ); // 旋转顺序:先应用上下偏移,再应用左右偏移,符合操作逻辑 return rotationY * rotationX; }
方向修正(可选)
如果上下偏移方向与预期相反,调整rotationX矩阵的正弦符号即可:
mat3 rotationX = mat3( 1.0, 0.0, 0.0, 0.0, cos(angles.y), -sin(angles.y), 0.0, sin(angles.y), cos(angles.y) );
原理说明
- 绕X轴旋转会改变采样坐标的Y/Z分量,对应全景图的纬度方向,实现上下偏移
- 绕Y轴旋转会改变采样坐标的X/Z分量,对应全景图的经度方向,实现左右偏移
- 采用
rotationY * rotationX的顺序,先执行上下偏移再执行左右偏移,避免万向锁干扰,符合日常操作直觉
内容的提问来源于stack exchange,提问作者Vad
相关产品推荐
相关产品推荐

