如何沿其原点旋转缓冲区几何体的各个平面
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.);
}
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;
}
存在由球体上的许多平面组成的缓冲区几何体。我正在尝试沿其原点单独旋转每个平面,因此整体动画看起来更像是爆炸。但是这个平面不是沿着它们自己的轴旋转,而是有点漂浮在球体上。
这是顶点着色器代码和所有代码的代码笔,以及触发动画的按钮。
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.);
}
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;
}