如何将多个矩阵发送到顶点着色器?


9

我正在使用骨骼/蒙皮练习动画。我正在尝试为着色器每个顶点发送一个矩阵。我可以想到这两种方法。

方法一

这样的每个骨基质都有一个统一的手柄

u_Bone0 = GLES20.glGetUniformLocation(mProgram, "u_Bone[0]");
u_Bone1 = GLES20.glGetUniformLocation(mProgram, "u_Bone[1]");

并在其中onDraw将它们每个发送到着色器: GLES20.glUniformMatrix4fv(u_Bone0, 1, false, matrix0, 0);

如果我有大量矩阵,显然这不是一个好方法。我的第二个想法我还没有尝试过,因为有很多代码可以重构

方法2

是用来glUniformMatrix4fv一次将它们全部发送出去(假设我有20个矩阵)

GLES20.glUniformMatrix4fv(u_Bones, 20, false, matrices, 0);

哪里matricesfloat[16 * 20]。但是,然后修改每个骨骼的矩阵变得有点乏味。例如,如果我想获得第3个矩阵,则需要

float[] _3rd = Arrays.copy(matrices, 3*16, 4*16);

而保存这些值可能会变得更加烦人。


我现在正在使用方法1,但看起来并不十分聪明...

将多个矩阵发送到OpenGL ES 2着色器的最佳方法是什么?

LE:我正在使用Android,因此我正在寻找Java解决方案。


只是一个旁注:如果矩阵太多,也可以通过fp纹理发送它们。
Kromster 2014年

Answers:


2

将多个矩阵发送到着色器很简单:

着色器:

uniform mat4 mBones[20]; //20 matrices
.. skipped code ..
vec4 vert = vec4(vPosition, 1.0) * mBones[int(vaBoneId)];

程序:

glUniformMatrix4fv(fShaderUnitSkeletal.uBones, 20, False, @bones20[0]); // Passing 20 matrices

但是,修改每个骨骼的矩阵与将它们传递到着色器的方式无关。如果您使用结构而不是数字数组,则可以使修改变得更简单。

bones20: array of TMatrix; // Declare array of matrices
bones20[2] := TMatrix.Identity; //Reset 3rd matrix

1
我正在使用Android / Java。因此,我不能使用“结构”或其他数据类型(抱歉,简短的评论,我无法详细说明atm,但稍后会再回来)
2014年

2

我建议使用VBO。用矩阵填充您的VBO,然后使用属性而不是制服将它们传递给他们。这样,VBO将在着色器中为每个顶点传递分配一个新的mat4。

在绘制前绑定VBO时(或为这些状态创建VAO):

  • 启用顶点属性(glEnableVertexAttribArray)
  • 将顶点属性除数设置为0(glVertexAttribDivisor)
  • 设置顶点属性指针(glVertexAttribPointer)

看看如何将mat4作为属性传递:https : //stackoverflow.com/questions/17355051/using-a-matrix-as-vertex-attribute-in-opengl3-core-profile

希望这可以帮助


1
有趣。但是,矩阵的更改可能会非常频繁(例如,我可能会在每帧中向其中之一添加额外的旋转)。他们不会保持不变。VBO是否适合这种情况?
2014年

是的,您只需使用glBufferData在每帧上载新矩阵
Luka

0

可以将方法1扩展为使用数组来抽象出代码中的矩阵数:(假设Java)

int[] u_Bone=new int[NUM_MATRICES];

for(int i=0;i<u_Bone.length;i++)
   u_Bone[i]=GLES20.glGetUniformLocation(mProgram, "u_Bone["+i+"]");

然后在设置矩阵时就可以

for(int i=0;i<matrix.length;i++)
    GLES20.glUniformMatrix4fv(u_Bone[i], 1, false, matrix[i], 0);

我最终实现了这一点,但是仍然没有太大的改进。但是到目前为止,这可能是最好的方法。
2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.