简体   繁体   中英

Why I should use Constant Vertex Attributes instead of Uniforms?

I have ready several topics about Constant Vertex Attributes and Uniforms.Have find out some differences but could not understand why I need them. It seems I can always use uniforms instead of CVAs. Is there any good usecase for them?

I don't think Constant Vertex Attribute (or CVA) is standard terminology. At least I had never heard it, and the people in the gamedev question you link were confused about it as well. So I don't believe it's widely used.

But based on the context, I figured out what you are asking about. You're thinking about the case where you use attributes in the vertex shader. But instead of pulling them from a buffer, you set them with calls like glVertexAttrib4f() before you make a draw call, which means that the value remains constant until you change it again. The spec calls these values simply "current vertex attribute values".

Now, if you should use attributes this way, or uniforms, there's no clear cut answer. As so often, the relative performance will be very platform/hardware dependent. My personal point of view is:

  • Uniforms should be used for values that change relatively rarely. Ideally at most once per frame, or at least much less frequently than each draw call.
  • Attributes should be used for values that change frequently. For example, if you want to change the value before each draw call, I would use an attribute.

This is also consistent with what the spec says. In the intro section about uniforms, it says (emphasis added):

Values for these uniforms are constant over a primitive, and typically they are constant across many primitives .

Uniform updates can be quite efficient on some platforms, and it's certainly not unusual for apps to change uniform values fairly frequently. But IMHO, it's not the intended use of uniforms. They are not called uniform for nothing!

There are some additional differences that might make one or the other more appealing depending on the use case:

  • Using an attribute can be very convenient if you sometimes use per vertex values from a buffer for the same type of rendering, and sometimes you want to use per primitive values. With attributes, you can keep using the same shader for these two cases, while you would need a different shader if you used a unifom.
  • Attributes are much more limited in the types they support, and in the number of them that is typically supported.
  • Uniform values are part of the per program state. Attribute values are part of the global state.

The keypoint here is the usage of glEnableVertexAttribArray and glDisableVertexAttribArray . From OpenGL ES 3.0 programming guide 2nd Ed.

The commands glEnableVertexAttribArray and glDisableVertexAttribArray are used to enable and disable a generic vertex attribute array, respectively. If the vertex attribute array is disabled for a generic attribute index, the constant vertex attribute data specified for that index will be used.

Consider the following scenario: you have some objects to be drawn with uniform color and some that have color specified for every vertex. You could use one vertex shader and pass the constant color associated to the vertices as if it was variable, but doing so you double the memory needed. Of course you could use another shader where you have an uniform to specify the color, so you optimise the memory but you need two shaders. Disabling the vertex attribute for color instead lets you use the same shader and optimise the memory used at the same time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM