在两个不同的vbo之间插值时,网格面会迷失方向

时间:2019-04-30 22:54:35

标签: java opengl-es glsl shader interpolation

因此,我将Java与opengl es一起使用,并使用obj(波前)解析器显示一个网格。我有一个从Blender导出的网格,到目前为止,我可以将其显示到Android手机显示屏上。我现在正尝试使用关键帧动画对网格进行动画处理,因为骨架动画很难实现。我在两个不同的位置有两个网格的vbo。我不确定着色器中是否存在用于关键帧动画的事实上的标准方法,但是我找不到它,因此我想出了一个公式,可以帮助我在给定时间在这两个vbo之间进行插值。公式如下

float ratio = ((passedTime/AnimationDuration))

在VertexShader中:

GLPosition = ratio * (this is difference->)(endVBOVertex - StartVBOVertex)) + startVBOVertex.

因此,如果AnimationDuration为8秒,passedTime为4秒,则比率等于.5。然后将该比率乘以起始vbo和终止vbo中顶点之间的差。然后将此值添加到startVbo顶点,以便可以为每个顶点计算正确的位置。因此,如果ratio = 0,则将0乘以等于0的差,然后将其添加到原始vbo顶点起点。让我们拥有开始时的网格姿势。如果比率= 1,则将其乘以差值,然后将其添加到起始vbo顶点位置,从而得到网格处于最终位置的最终vbo。当比率为0或1时,网格看起来很好。但是,(这是问题)在0到1之间,网格的某些面旋转了,从而在网格中留下了孔。在比率= .50时,最糟糕的情况是使某些面旋转45度左右。留下一个带有菱形的网格的矩形表面,并通过三角形看到4个。当我接近0或1时,这些受影响的面会旋转回正确的位置,从而使整个网格正确。在这两个vbo之间进行插值时,网格的位置也看起来不错。意味着总体上可以以适当的姿势看到网格,但是某些面孔正在旋转并以一种怪异的方式受到影响(比率在0-1之间),这使我看不到网格。

{如果您能做到这一点,我将非常感谢您的宝贵时间,如果我有任何不清楚的地方,我深表歉意。我也要说非常感谢您的所有建议。

我启用了深度测试,我知道我正在正确分配所有制服和属性,因为我将无法以比例= 0 ||的正确姿势结束网格。 1. Vbo的顶点数相同。

这是我的顶点着色器:

uniform mat4 u_Matrix;//uniform for our matrix

attribute vec4 a_Position;//Original vertex position

attribute vec2 a_TextureCoordinates;

varying vec2 v_TextureCoordinates;

attribute vec4 b_Position;//Next vertex position to interpolate too

attribute vec2 b_TextureCoordinates;


uniform float ratio;

// (currentTime - StartTime)/animationDuration
//so If the animation lasts 8 seconds and 4 seconds have passed ratio
//will equal .5 and half the difference it takes for the first vbo to reach the second vbo will be added.

void main() {  
      v_TextureCoordinates = (a_TextureCoordinates + ((b_TextureCoordinates - a_TextureCoordinates) * ratio));
      gl_Position = u_Matrix * (a_Position + ((b_Position - a_Position) * ratio));
}

这是我的片段着色器:

precision mediump float;

uniform sampler2D u_TextureUnit;


varying vec2 v_TextureCoordinates;


void main() {
      gl_FragColor = texture2D(u_TextureUnit,v_TextureCoordinates);
}

Close Up of Head

Ratio at 50%

2 个答案:

答案 0 :(得分:0)

基本上,您正在对网格数据进行标准lerp(线性插值),可以使用mix()函数完成此操作。

v_TextureCoordinates = mix(a_Position, b_Position, ratio);
gl_Position = mix(a_TextureCoordinates, b_TextureCoordinates, ratio);

在着色器中,一切对我来说看起来不错。我有点担心您是否要插值UV纹理坐标???对于角色动画这是非常不寻常的方法吗?通常,动画时纹理坐标不会改变。

顶点融合的一大问题是,如果姿势明显不同,您将得到一些非常奇怪的变形。我猜您的手工艺品可能是由于这个? (通常首选动画层次结构的原因之一)

答案 1 :(得分:0)

如果要进行“旋转”插值,则需要一个枢轴,一个旋转点。

顶点坐标的插值可能是这样的:

attribute vec4  a_Position;
attribute vec4  b_Position;
unifrom   vec3  u_pivot;
uniform   float ratio;

void main()
{  
    vec3  v_a   = a_Position.xyz - u_pivot; 
    vec3  v_b   = b_Position.xyz - u_pivot;
    float len_a = length(v_a); 
    float len_b = length(v_b);

    float len_x = mix(len_a, len_b, ratio);
    vec3  v_x   = normlize(mix(len_a, len_b, ratio)) * len_x;

    gl_Position = u_Matrix * vec4(u_pivot + v_x, 1.0);
}