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

Three.js中ShaderMaterial动画需适配对象本地坐标系的问题

修复Three.js ShaderMaterial中Points对象旋转失效的问题

你的问题核心是:着色器里直接覆盖了经过modelMatrix变换后的坐标,把Points对象的旋转、缩放等本地变换给完全忽略了。

原来的代码逻辑是先通过modelMatrix * vec4(position, 1.0)计算了带对象变换的坐标,但紧接着用球体公式直接赋值modelPosition.x/y/z,相当于把粒子直接放到了世界坐标系的环形位置,完全无视了Points对象自身的rotation.z设置。而MeshStandardMaterial会保留顶点的原始变换逻辑,所以旋转效果正常。

快速修复方法

不用额外添加旋转因子,只需要调整坐标计算的顺序:先算出粒子在Points对象本地坐标系下的环形位置,再用modelMatrix把这个位置变换到世界空间。

修改后的顶点着色器代码:

#define PI 3.1415926535897932384626433832795
uniform float uSize;
attribute float aScale;
attribute vec4 aParticle;
uniform float uTime;
varying vec3 vColor;

void main()
{
/**
 * Particle Local Position
 */
    float moveT = aParticle.g;
    float moveS = aParticle.r + uTime * aParticle.b;

    float fullRotate = step(360.0, moveS);
    moveS = moveS - (fullRotate * 360.0);

    float radMoveS = moveS * (PI / 180.0);
    float radMoveT = moveT * (PI / 180.0);

    // 先计算本地坐标系下的粒子环形位置
    vec3 localPosition;
    localPosition.x = aParticle.a * cos(radMoveS) * sin(radMoveT);
    localPosition.y = aParticle.a * cos(radMoveT);
    localPosition.z = aParticle.a * sin(radMoveS) * sin(radMoveT);

/**
 * Apply Model Transform
 */
    vec4 modelPosition = modelMatrix * vec4(localPosition, 1.0);

    vec4 viewPosition = viewMatrix * modelPosition;
    vec4 projectedPosition = projectionMatrix * viewPosition;
    gl_Position = projectedPosition;

/**
 * Size
 */
    gl_PointSize = uSize * aScale;
    //Attenuation
    gl_PointSize *= ( 1.0 / - viewPosition.z );

/**
* Color
*/
    vColor = color;
}

原理说明

modelMatrix已经包含了Points对象的所有本地变换(旋转、缩放、平移),现在先在本地坐标系算出粒子的环形路径,再通过modelMatrix把这个路径变换到世界空间,自然就会继承对象的rotation.z倾斜效果,和MeshStandardMaterial的行为保持一致。

内容的提问来源于stack exchange,提问作者cannon303

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 11:35:22