I would like to create a motion blur effect by rendering and additively mixing moving objects at several points on their path over the frame.
I thought that the calculation to determine the drawing location could be done in the vertex shader. It seems to me, however, that I may need to use a geometric shader if I want to avoid going through the geometry for each rendering.
What is my best course of action? I decide between:
- Manually collecting vertex data for each subframe and transferring it to the GPU every time (while I will not have a vertex program)
- Send the geometry along with the speed values. I can calculate the intermediate position in the vertex shader, although I'm not sure how to indicate that a certain speed value is assigned to certain groups of primitives. I will need to send the same vertices once for each subframe rendering, because the vertex shader cannot create new vertices.
- Use the geometric shader to create all the geometry for all the subframes. I should be able to get all the subframes without transferring data back and forth during the entire rendering process.
The balance I want to strike at is that I want at least redundant data transfer, supporting as much hardware as possible. It seems like I should use the Vertex buffer object to store the geometry data and just pass a few mouthpieces to send speed data to the vertex shader for each rendering. It works? Also, the VBO buffer is constant, so for the best performance, I have to go in and change the geometry data as needed, right?
Another potential problem that I don’t know with is that I want to accurately make my intermediate positions by interpolating translation and rotation, which rigid objects intersect in the frame, and not just interpolate only the resulting vertex positions. The difference here is that a rotating object will leave a curved strip.
Is there any way to prevent a call to a separate dynamic hard object? Maybe I could use a common vertex attribute to send my speed? This would be somewhat redundant because I could have an object with 100 vertices with the same speed data, but at least my shader can get the stream of this data this way.
It seems to me that there can not be too much to achieve vertex transformations on the GPU: I would need to transfer the velocity vector, the angular velocity scalar and the center of the mass vector as the vertex of the attributes. Sounds like a big waste of bandwidth. However, I can use this data for a potentially large number of "samples" (subframe rendering).
I worked for a very long time using OpenGL Immediate Mode, but this time I want to do everything right.
UPDATE. See the extended discussion of comments for the direction that has been followed. Now I’m sure that a few samples will not lead to a good result because of the “strobe light effect”: at some speeds, I will need blur for performance reasons. In this case, I need to accumulate blurry subframes; rendering subframes and then blurring will still leave artifacts.