1
\$\begingroup\$

First thing: this is more of a conceptual question than an implementation oriented one, but still tips about implementation will be very much welcome if you happen to have any (athough I have some experience programming different parts of games, graphics are certainly my weak spot - as you will see).

So, I have an application in which all high-poly objects have their vertices grouped in an object-specific AABB-tree to speed up the narrow-phase of collision detection. Now, it occurred to me the following. Since that structure is already in place, would it be possible to use it for culling parts of objects instead of the usual all-or-nothing approach of the frustum and occlusion culling techniques?

The idea for that is simple in concept. Instead of testing for visibility only using the whole objects' AABB, I would do that first but in the positive cases I would proceed to visibility checks of the sub-AABBs containing that object's vertices. Once identified the sub-AABBs that are visible, only the triangles that are contained in these sub-AABBs would be sent to the GPU for rendering.

Therefore, in a more systematized way, my three related questions are:

1) is such an approach even possible in what regards the way GPU gets and processes the mesh geometry information pulled from CPU?

2) given that in such scenario the CPU would have to break the meshes somehow and pass to the GPU only the vertices that were identified as being in the visible parts of the visible objects, wouldn't that pose additional load on the processing time such that the cost would overcome the gains?

3) most importantly, passing to the GPU only some triangles of a mesh could cause graphically distorted results when shader and texture are rendered for that partially-only rendered object?

I searched quite a bit for academic references on this subject but came almost empty. I would gladly welcome reading suggestions of any sort.

\$\endgroup\$
1
\$\begingroup\$

I'll answer your question(s) in the order you asked:

Therefore, in a more systematized way, my three related questions are:

1) is such an approach even possible in what regards the way GPU gets and processes the mesh geometry information pulled from CPU?

It's possible to only send N vertices from a vertex buffer using the offset & size arguments in most APIs.

2) given that in such scenario the CPU would have to break the meshes somehow and pass to the GPU only the vertices that were identified as being in the visible parts of the visible objects, wouldn't that pose additional load on the processing time such that the cost would overcome the gains?

Absolutely - in modern GPUs the overhead of each draw call is very high, so your proposed plan is likely not of great benefit unless the model is exceptionally high polygon. Imagine a case where the arm, head and foot of a model are visible because the model is 'looking into' the frame. You would have three draw calls - one for the arm, one for the head and one for the foot. This defeats any optimizations. Remember that the hardware performs viewport clipping - the triangles are transformed into clip space and potentially rejected there prior to any rasterization. This is relatively efficient. Furthermore, meshes are split on material boundaries, which might be spread all over the model which complicates the value of your approach. Often a single vertex buffer is shared among multiple materials - a collection of shader parameters and textures. Each material must be issued with a unique draw call. Artists often make every effort to use a single material per model to minimize draw calls but it isn't always possible.

3) most importantly, passing to the GPU only some triangles of a mesh could cause graphically distorted results when shader and texture are rendered for that partially-only rendered object?

No - this won't cause any problems as long as you guarantee sending all of the visible, front-facing triangles - the GPU only cares about what is visible, not the ones that are clipped off screen.

Ultimately, I don't think this is worth the extra effort as breaking up the draw calls will reducing batching, which is really important for performance.

\$\endgroup\$
  • \$\begingroup\$ Thanks for answering. So, about point 2, that's the thing I'm now working on: it's not clear that there would be more drawcalls in what I'm trying to test. Thinking better, the CPU wouldn't have to break the mesh, but just send fewer triangles to be drawn. Just like culling was performed in the triangle level a few years ago, instead of at the mesh level. I'm more concerned, however, with what you mentioned about the material boundaries. Could you elaborate on that? I'm trying to learn more about it but couldn't find much on those terms \$\endgroup\$ – MAnd Nov 17 '15 at 16:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.