You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 08:14:59