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
相关产品推荐
相关产品推荐

