-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Conversation
Why take this approach? Just curious. |
We could take this approach with webgl too. mapbox/mapbox-gl-js#229 The main possible advantages I'm seeing are
but @kkaefer might be thinking something else Side question: Theoretically, we could draw fills + antialiasing in one draw call, right? |
Nice, this is helpful. I'm still pretty fresh to performance considerations but this makes sense. |
I just want to add that its completely a guess, I have no idea whether it is actually significant. |
@ansis While we could probably get this to work, the major drawback of that approach is that we couldn't share vertices across triangles because they have the fade distance encoded. It's probably easier to use two draw calls: One to render the triangle strips (and stencil buffer if needed), and one to render the outline (using the stencil buffer to knock out if needed). We're still going to need a stencil buffer, for (a) clipping to tile boundary and (b) clipping outline to only render outside of the polygon. The benefit we're going to get is that we have fewer fragments to shade when drawing the initial stencil buffer because we have no overlapping triangles fans anymore. |
Yeah, that makes sense. |
Triangulation works, but is pretty slow. Typical tessellation times for a tile with many buildings is 1-2 seconds, which makes the app feel slow because tiles take more time to load. |
My conclusion is that tessellating smaller batches could be a lot faster, but it currently is a lot slower because of memory allocation overhead. libtess2 provides a memory allocation interface, so we could use a memory pool to handle the many small allocations. |
I'm not too sure about the performance wins here. On iPhone 4, I'm seeing a speed increase of about 30-40% (from 22 to 30 fps), but on iPad 2, we're already at 60 fps. Might be interesting to try this on iPad 3/4 where we have a lot more fragments to shade. |
3843bf1 changes the allocator defaults and gives much better tessellation performance, but loading tiles feels still a little slower than before. |
I can benchmark this today. |
Also, this might benefit from another allocator like tcmalloc. |
https://code.google.com/p/poly2tri/ might also be interesting, but this project uses delaunay triangulation which inserts additional (steiner) points, which we don't need for rendering. |
We should revisit putting tessellation into vector tiles. |
Currently, we're tessellating twice: Once to obtain the outlines with positive winding, then we use that output an feed it back into the tessellation library to get the list of triangles that we need to render the fill. Then we're doing a reverse mapping of indices and use the previous indices (from the outline). Since tessellation might introduce new indices, this can fail (see 004ff9e). It'd be better if we generated this in one go because it'd reduce the tessellation calls by half. |
There are still seam issues: http://i.kkaefer.com/h7696.png |
The seams seem to be in the data, so nothing related to this PR. |
Conflicts: include/llmr/renderer/fill_bucket.hpp src/renderer/fill_bucket.cpp src/renderer/painter.cpp
Curious as to why you use libtess2 vs poly2tri? Poly2tri generates larger triangles so is more efficient due to less vertices. Also prevents lots of tiny triangles that slow down rendering. Poly2tri uses constrained delaunay triangulation which does not insert steiner points. It only uses the existing polygon vertices. Poly2tri is fast and stable. I have personally tested it with massive (1000s vertices) polygons with 100s of nested holes. Never had it crash or produce incorrect rendering. |
@ljbade I tried poly2tri, but I got a few crashes from it. They recommend using ClipperLib with it, which I'm not sure I did back then. We may move to poly2tri eventually, but the current focus is on getting the library more stable. |
Interesting you found some crashes in poly2tri. Makes sense to keep it stable for the moment, but GLU tessellation ain't pretty. |
We should try out tessellating polygons with e.g. https://github.com/memononen/libtess2 rather than using the stencil buffer approach. Note that this is a big deviation from the way we're drawing polygons with WebGL and that this might introduce differences in rendering.