如何沿其原点旋转缓冲区几何体的各个平面

How to rotate individual planes of buffer geometry along their own origin

存在由球体上的许多平面组成的缓冲区几何体。我正在尝试沿其原点单独旋转每个平面,因此整体动画看起来更像是爆炸。但是这个平面不是沿着它们自己的轴旋转,而是有点漂浮在球体上。

这是顶点着色器代码和所有代码的代码笔,以及触发动画的按钮。

uniform float uTime;
uniform float uProgress;
uniform float uGravity;

attribute vec3 attributePositionDest;
attribute vec3 attributeCentroid;
attribute vec3 attributeAxis;
attribute float attributeGravityVelocity;

varying vec3 vEye;
varying vec3 vNormal;
varying vec3 vReflect;

// http://www.geeks3d.com/20141201/how-to-rotate-a-vertex-by-a-quaternion-in-glsl/
vec4 quat_from_axis_angle(vec3 axis, float angle) {
  vec4 qr;
  float half_angle = (angle * 0.5) * 3.14159 / 180.0;
  qr.x = axis.x * sin(half_angle);
  qr.y = axis.y * sin(half_angle);
  qr.z = axis.z * sin(half_angle);
  qr.w = cos(half_angle);
  return qr;
}
vec3 rotate_vertex_position(vec3 position, vec3 axis, float angle) { 
  vec4 q = quat_from_axis_angle(axis, angle);
  vec3 v = position.xyz;
  return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);
}

// main
void main() {
  vec3 positionAdjusted = position;
  float vTemp =  1. - ((attributeCentroid.x + attributeCentroid.y)*0.5 + 1.)/2.;

  float tProgress = max(0.0, (uProgress - vTemp*0.5) / 0.25) * uProgress;
  float vectorLength = length(position);
  float gravityAdjustment = (uGravity + attributeGravityVelocity) * uTime * vectorLength * 0.25;

  positionAdjusted = mix(positionAdjusted, attributePositionDest, tProgress); // translate to destination
  positionAdjusted = rotate_vertex_position(positionAdjusted, attributeAxis, max(1., uTime * 0.5)); // rotate plane
  positionAdjusted = vec3(positionAdjusted.x, positionAdjusted.y + gravityAdjustment, positionAdjusted.z); // add gravity

  vec4 worldPosition = modelMatrix * vec4(positionAdjusted, 1.0);
  vec3 worldNormal = normalize(mat3(modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz) * normal);
  vec3 I = worldPosition.xyz - cameraPosition;

  // set varying vars
  vNormal = normal;
  vEye = normalize(vec3(modelViewMatrix * vec4(positionAdjusted, 1.0)));
  vReflect = reflect(I, worldNormal);

  gl_Position = projectionMatrix * modelViewMatrix * vec4(positionAdjusted, 1.);
}

https://codepen.io/olhapi/pen/vYWrXMK?editors=0010

quat_from_axis_angle()

中的 half_angle 单位有问题

移除 rad 转换,当 utime > 1 秒时它将转为 :

vec4 quat_from_axis_angle(vec3 axis, float angle) {
  vec4 qr;
  float half_angle = (angle * 0.5); // * 3.14159 / 180.0;
  qr.x = axis.x * sin(half_angle);
  qr.y = axis.y * sin(half_angle);
  qr.z = axis.z * sin(half_angle);
  qr.w = cos(half_angle);
  return qr;
}