如何沿其自身原点旋转缓冲区几何体的各个平面
缓冲区几何体由球体上的许多平面组成。我试图沿着每个平面的原点单独旋转,因此整体动画看起来更像爆炸。但这个平面不是沿着自己的轴旋转,而是漂浮在球体上。
以下是顶点着色器代码和包含所有代码的 codepen,以及触发动画的按钮。
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.);
}
There's buffer geometry that consists of many planes on sphere. I'm trying to rotate each plane indidividually along its own origin, so overall animation will look more like explosion. But instead of rotating along their own axis this planes is kind of floating on a sphere.
Here are vertex shader code and codepen with all code, and button to trigger animation.
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.);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您在 quat_from_axis_angle() 中的 half_angle 单位有问题,
删除 rad 转换,当 utime > 时,它会变成 。 1 秒:
You have a problem with half_angle unit in quat_from_axis_angle()
remove the rad conversion and it will turn , when utime > 1 second :