2
votes

I'm about to do an Opengl ES implementation of blend shapes/morph targets and I'm not quite sure about the best way for me to do this. The problems I am facing is that I want the interpolation of the vertex data to occur on the GPU but I also want the number of blend shapes to be arbitrary.

To clarify, I do not want my vertex shader to look like this: Glitchy Facial Morph Target Animation in OpenGL (C++). The problem with this implementation is that the number of meshes to blend between is static in the shader. I am going to process multiple meshes that have different numbers of blend shapes associated to them and I dont want to create separate shader for each if possible. Creating hard-coded shaders for meshes with around 20 blend shapes will also look quite ugly imo.

So I was thinking of using some kind of dynamic array to hold all the data. However, I'm uncertain if you can allocate dynamically sized arrays in the vertex shader? In Vertex shader with array inputs the op has the size set to a constant. The only way I could think about creating my array is the use a uniform variable to hold the size but I'm guessing that won't compile since the array cannot be allocated with an unknown variable.

So what I'm trying to find is a good way to store my data(number of blend shapes, weights, vertices, normals) and to access them during runtime in my vertex shader so I can effectively interpolate on the GPU.

Any ideas on how to accomplish this?

EDIT Forgot to mention its for OpenGL ES

1
Not sure if it will help you or not but in C++ a dynamic array == std::vectorNathanOliver
@NathanOliver Yea, the data storage in C++ is not the problem right now. Thanks anyway!Grodslukarn

1 Answers

2
votes

What you're looking for is Shader Storage Buffer Objects (SSBO's) and they'll basically let you do exactly what you're trying to do.

Big caveat though: they're only available on GL4.x class hardware, specifically 4.3+. This is becoming less and less of a problem each year, but if the computer's GPU is more than 5 years old, it may not work.

If you're dealing with OpenGL ES, you'll still (probably) have Uniform Buffer Objects which only require OpenGL 3.x hardware. They're a lot more limited than SSBOs (spec only guarantees 65kb of data, and even modern hardware doesn't typically give space beyond that) but it's much more likely to be compatible with your hardware.

In an absolute worst-case scenario, you could also use textures as buffers that you write arbitrary data to, then reinterpret the data on the shader. It's very hacky, but it'll bypass the space restrictions of UBO's, and will probably be compatible with your hardware at almost any level.