Most efficient algorithm for mesh-level, optimal occlusion culling? - algorithm

I am new to culling. On a first glance, it seems that most occlusion culling algorithms are object-level, not examining single meshes, which would be practical for game rendering.
What I am looking for is an algorithm that culls all meshes within a single object that are occluded for a given viewpoint, with high accuracy. It needs to be at least O(n log n), a naive mesh-by-mesh comparison (O(n^2)) is too slow.
I notice that the Blender GUI identifies the occluded meshes for you in real-time, even if you work with large objects of 10,000+ meshes. What algorithm is used there, pray tell?

Blender performs both view frustum culling and occlusion culling, based on the dynamic AABB tree acceleration structures from the Bullet physics library. Occluders and objects are represented by their bounding volume (axis aligned bounding box).
View frustum culling just traverses the AABB tree, given a camera frustum.
The occlusion culling is based on a occlusion buffer, a kind of depth buffer that is initialized using a very simple software-renderer: a basic ray tracer using the dynamic AABB tree acceleration structures. You can choose the resolution of the occlusion buffer to trade accuracy versus efficiency.
See also documentation http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.49/Game_Engine#Performance
Blender implementation from the Blender source tree:
blender\source\gameengine\Physics\Bullet\CcdPhysicsEnvironment.cpp method
bool CcdPhysicsEnvironment::cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4 *planes, int nplanes, int occlusionRes)
and the Bullet Physics SDK has some C++ sample code in Bullet/Extras/CDTestFramework.

Have you looked into things like Octrees?

The reason why culling is not made on the mesh level is that a mesh is a very dumb renderer level object while a game-object is at the scene level, where all the culling occurs. There are no mesh level culling decision being taken, they are simply a way to batch primitives with similar shader states if their objects needs to be renderered.
If you really need to cull at mesh level, then you might want to create one object per mesh and then create a group object that contains the mesh-objects. Be aware that you might actually lose performance since culling at mesh level is usually not worth it; it might break the flow of data transfers to the hardware.

Usually the first thing you do is see if the meshes have any chance of occluding each other. Often times with a simple bounding primitive (bounding boxes or bounding spheres). If I recall correctly, Octrees will help with this.

I tried the naive approach which was actually sufficiently fast for my app.
For each triangle in mesh, check if occluded by any other triangle in mesh, thus O(n2). (I got high accuracy results from only checking whether the center point on each triangle was occluded or not, though you should at least check the triangle corner vertices, too, if accuracy is important).
On a pentium 4 machine (c++) a binary STL object of ~10,000 triangles took about 1 minute to complete.
The algorithm can be optimized up to ~40 percent by sorting the triangles first, for example by area size or distance from view point (more likely to occlude, so you can skip more checks).
Next optimization step would be to put the triangles in an octree, which should greatly reduce number of occlusion checks.

Related

Real-time vector field interpolation for ballistics simulation

I'm working on a real-time ballistics simulation of many particles under the effect of highly non-uniform wind. The wind data is obtained from CFD in a form of 2D discretized vector field (unstructured mesh, each grid point has associated with it a vector which tells the direction and magnitude of air velocity).
The problem is that I need to be able to extract the wind vector at any position that a particle occupies, so that aerodynamic drag can be computed and injected into ballistics physics. This is trivial if the wind data can be approximated by an analytical/numerical vector field where a vector can be computed with an algebraic expression. However, the wind data I'm working with is quite complex and there doesn't seem to be any way to approximate it.
I have two ideas:
Find a way to interpolate the vector field every time each particle's position is updated. This sounds computationally expensive, so I'm not sure if it can be done real-time. Also, the mesh is unstructured, and I'm not sure if 2D interpolation can be done with this kind of mesh.
Just pick the grid point closest to the particle's position and get the vector from there (given that the mesh is fine enough for this to accurately represent the actual vector field). This will then turn into a real-time nearest-neighbor problem with rapid and numerous queries.
I'm not sure if these are the only two solutions for this problem, and if these can be done in real-time at all. How should I go about solving this?

Frustum culling on gpu

I am a 3D computer graphics learner and I want to implement frustum culling to work on the gpu. I've already implemented it with software rendering system. That culling worked with polygon with minimum of 3 vertices and, if it was outside the frustum, added a new point on the frustum inside. Here is algorithm implementation just in case.
And, as I want to implement that algorithm on the gpu, I have several questions with it:
I was thinking to implement frustum culling with geometry shader, but that seems that I won't be able to cull UVs coordinates then, is it Right? Or there is a way to pass, somehow, those UV's coordinates, cull them in geometry shader, and pass them next to the fragment shader?
I thought to implement it in vertex shader, but won't I be able to get all vertices for current triangle? Maybe I just don't quite know a way to corretly get all vertices per face? Wouldn't I just to cull only one by one vertex?
Maybe I just don't know the right way to implement frustum culling on gpu. Can there be a better algorithm to implement frustum culling? Thanks.
I believe what you have implemented is 'clipping'.
'frustum culling' usually refers to a technique where you discard invisible elements as a whole and I believe that is not what you are asking here.
back to clipping,
Graphics API by default will clip polygons in normalized device coordinate space. For example with OpenGL, out side of 2x2x2 cube with center at (0,0,0) will be clipped automatically after the vertex shader.

Vector image editing by dragging a polygon as a brush

The goal is to do simple vector image editing by dragging the mouse across the screen like a polygon-shaped paintbrush, creating the Minkowski sum of the brush and the path of the mouse. The new polygon would be subtracted from any previously existing polygons of a different color and merged with any existing polygons of the same color.
The plan is to take each mouse movement as a line segment from the mouse's previous position to its current position, calculate the Minkowski sum on that line segment, then do use the Weiler–Atherton clipping algorithm to update the existing polygons to include that Minkowski sum.
Since it seems likely that Weiler–Atherton would cause UI delays if run for every mouse movement, we plan to delay that step by putting it into another thread that can take its time catching up to the latest mouse movements, or alternatively save all Weiler–Atherton calculations until the drawing is finished, then do it as a bulk operation when saving. We worry that this may lead to the accumulation of a very large number of overlapping polygons, to the point that UI would be delayed by the time required to render them all.
The question is: Is the above plan the way that Inkscape and other serious vector graphics editing software would perform this operation? It seems like a mad plan, both in the trickiness of the algorithm and its computational complexity. What would an expert do?
Another option under consideration: Do the painting using simple raster operations and then convert the raster into a vector image as the final step. Conversion from raster to vectors seems no less tricky than Weiler–Atherton, and quality of the final output might suffer, but could it be the better option?
While the user is holding down the mouse button and drawing, you can remember all the mouse movement line segments, and simultaneously render the brush*line Minkowski sums to a screen resolution bitmap.
You can use the bitmap for painting the screen until the user releases the button. At that time you can calculate the union of all the line segment Minkowski sums and add the resulting shape to your drawing.
To calculate the union of so many shapes simultaneously, some kind of sweep-line algorithm would be best. You should be able to do the job in O(N log N) or linear time, which will not cause any noticeable delay.
IMO the bottleneck in Weiler-Atherton is the detection of the intersections, which requires O(N²) operations when applied by brute-force. the rest of the processing is a reorganization of the links between the vertices and intersections, which should be limited to O(N), or even O(NI), where NI denotes the number of intersections.
In this particular case, you can probably speed-up the search for intersections by means of gridding or a hierarchy of bounding boxes. (Note that gridding parallels the idea of Matt to use auxiliary bitmap rendering.)
Unless you really have billion edges, I wouldn't fear the running time.
If you want to do this like professional vector graphics softwares do with arbitrary brush shapes (including features such as the brush shape can react to speed or stylus pressure), it can be quite involved unfortunately.
I was experimenting with the method described in "Ahn, Kim, Lim - Approximate General Sweep Boundary of a 2D Curved Object". It seems to handle a lot of cases that I would expect from a professional drawing application —especially the details where the brush shape can be dynamic while sweeping; adaptively generate the boundary curve for the resolution you want; variable width offsetting of 2d curves; etc..
It seems you can simplify this method if you don't need a generalised method. But I would like to add it here as a reference.
PS: I was searching for a non-paywalled link to include here in the answer and then this came up – Looking for an efficient algorithm to find the boundary of a swept 2d shape. Looks very similar to what you're trying to do :).

3D mesh edge detection / feature line computation algorithm

I have a program that visualizes triangular meshes and allows the users to draw on the meshes using a pen. I want to have a "snapping" mode in my system. The snapping mode performs drawing corrections for the user in the sense that the user-drawn lines are snapped to the nearest edge (or the silhouette) of that part of the mesh.
I'm looking for an algorithm that compute the edges visible on the mesh from a given point of view. By edges, I'm referring to the outlines of the shape: corner points and the lines between them (similar to the definition of an edge in computer vision/image processing -- such as Canny edges).
So far I've thought of two approaches for this:
Edge detection: so far I've only found this paper. Their method is understandable, yet the implementation is not trivial (due to tensor computations and some ambiguity in their explanations). The problem with this approach is that it produces "edge strength values" which is a value in the range [0, 1] for every vertex. The value of 1 indicates an edge vertex with a high confidence. This introduces extra thresholding parameters in the system which I'd rather not have. Their output looks like this (range [0, 1] scaled to [0, 65535]):
Rendering or non-photorealistic methods such as the one asked in this question or this paper. They seem to be able to create the silhouette that I'm after as can be seen below:
I'm not a graphics expert and as of yet I don't know whether their methods can be used for computation of the feature lines rather than rendering.
I was wondering if anybody has any ideas about a good algorithm for what I want to do. Since the system is very interactive, the performance is important. The snapping feature does not have to be enabled all the time (therefore, if the method is computationally expensive, some delay in when "snapping enabled" mode is toggled can be tolerated while the algorithm is computing the edges.) Also, if you know of any implementation (preferably open source), I'd be grateful if you could share it with me.
There are two types of edges that you want to detect:
silhouette edges are viewpoint dependent, they correspond to the places where the line of sight tangents the surfaces. With a triangulated model, they are easy to determine, as they are shared by a front-facing triangle and a back-facing one.
"angular" edges are viewpoint independent and formed by a discontinuity in the tangent plane direction. As a triangulated model has itself this kind of discontinuity, there is no exact criterion to find them. Just set a threshold on the angle formed by two triangles. This threshold must be such that smooth patches do not trigger.
By this approach, you will find the wanted edges in 3D.
This is not enough, as part of them are hidden by other surfaces. You have the option of integrating them as edges in the 3D model and letting the rendering engine do its job, or, if you have the courage, to implement an hidden lines removal algorithm. (The wikipedia link is a little terse.)
Since posting the question, something else came into my head. Since 2D edge detection is a very well-studied problem, one way of tackling the problem is performing 2D edge detection on the projection image of the mesh.
In other words, given a specific view of the mesh, one could generate a 2D image. A 2D edge detection algorithm (such as Canny edge detector) could then be run on the 2D image and the results can be back-projected to 3D to determine the silhouettes of the mesh in question. One possible advantage of this is simplicity!
Edit (2017):
Even though I moved away from this, I returned to this problem again for a different purpose. To anybody else looking into this problem: there is a paper that talks about various contours from meshes that's worth reading (the paper is "Suggestive Contours for Conveying Shape" by DeCarlo et al.).
Working implementation of the methods discussed in the paper are available here.

3D algorithm for clamping a model to view frustum

What would be an efficient approach for constraining an object so that it's always at least partially intersecting the view frustum?
The use case is that when viewing a model I want to clamp camera panning, as well as model translation, so that the view frustum is never looking at empty space.
One approach I tried was to wrap the model objects in bounding volumes, then enforce the constraint when those fall outside the frustum. I've tried bounding boxes so far, but am considering using a minimal convex hull.
The problem is that that when you zoom in close enough, it's still possible to be looking at empty space within the boundary, as shown in the attached diagram.
This is for a WebGL application, so needs to be fairly efficient in JavaScript, and also for thousand of vertices.
Ideally you would have a aabb tree of your mesh, and then you can recursively project on camea/screen until you get an intersection ?
http://www.codersnotes.com/algorithms/projected-area-of-an-aabb
edit: it's just frustum culling algo against aabtree does anyway, so looking for optimized solution, is looking for optimized frustum culling things
https://fgiesen.wordpress.com/2010/10/17/view-frustum-culling/
http://www2.in.tu-clausthal.de/~zach/teaching/cg_literatur/vfc_bbox.pdf
As general approximation is possible I would try the point cloud. First create a list of points - either by every Nth mesh vertex or every Nth face centre. With N being for example 10. Once you have this point array all you do is check if any of points is in frustum while updating its orientation. If not then this means that user moved or rotated the camera too much and you need to restore last acceptable orientation.
I know that this may seem quite ridiculous but I think that it is fairly easy to implement and frustum checking of vertex is just couple of multiplications per plane. It will be not perfect though.
You can also make frustum a little smaller to ensure that there is some border around the object.

Resources