Why is the wireframe rendering so slow compared to solid?

Started by
37 comments, last by iGrfx 4 years, 10 months ago
1 minute ago, VanillaSnake21 said:

The blogs looks really interesting. Does this require tons of math? I'm working on terrain myself at the moment and even the basic things like getting heights of the terrain at the player position took me lots of time just to find the formulas etc. What kind of a background do you have, if you don't mind me asking? 

Actually I'm s**t at math, or at least I used to be.  Now I'm kind of mediocre. I have next to no education but I have been programming now for over 35 years. The trick is to find tutorials and resources that are understandable.  I used to buy programming books all the time. My shelves are full of them and I've learned 95% of everything on my own.

My assessment is the math here isn't that bad. I'm guessing you could do it easily, likely better than me. Almost everything I do seems like  dot products and cross products, ha ha.......however ..... the data structures and algorithms to make this thing work are another story entirely. I'm kind of a hard core old school blood and guts C++ programmer. I spent like 5 years writing assembly code at intel. This thing includes special heaps, thread pools and all sorts of custom algorithms that I'm always experimenting with. I woudn't call it simple..... but actually a lot of the issues have to do with generating voxels wrapped around sphere. Note my voxels all face out from the core. For terrain built on a flat plane it should be WAY easier.

if you just need the noise stuff, it's pretty simple. You can find simplex noise implementations all over the place. I can even post some code, but I've been too busy to optimize it so you can probably find faster stuff elsewhere.

Advertisement
8 hours ago, VanillaSnake21 said:

I'm looking for frustrum culling settings, where can I check if it's enabled? [snip]

Well, frustum culling must be programmed by comparing objects' bounding bodies against the camera frustum. Its effect is that drawing data isn't sent to the GPU at all. Which can result in a drastic performance gain.

Quote

That looks like a very dense mesh, what framerates is it running at? I'd gladly take the 50 % drop over what I have now (1300% drop). I think you mentioned it earlier, could it have something to do with frustrum culling? I've checked the setting and don't see myself explicitly enabling it aanywhere in the code, maybe I'm not using it and that's causing the issue? Also, that's a pretty nifty terrain, did you write all the code yourself and if you can share what tech/libraries you're using and just explain your project in general?

It is a little ... misleading. The actual height map has 1024 * 1024 posts, but the mesh used for rendering is 4 times that dense, so there is interpolation between 2 posts. Node size is 16*16, mesh size is 64/64 for each node (bounding boxes of each node shown below).

LOD algorithm after: https://github.com/fstrugar/CDLOD

Frustum culling from here: http://www.lighthouse3d.com/tutorials/view-frustum-culling/

Yep, frustum culling is a gain. And it must be programmed, it is not a switch in the api (at least not in OpenGL). When i introduced it i gained around 10 times frame rate increase. The LOD selection process does the culling, so drawing data outside of view isn't processed by the GPU at all. Framerate depends totally on the view perspective and how many levels are generated, how dense the meshed are, how deep the field of an lOD level is etc. "Usually" the rate i see can be as low as 1200/s, or over 3000/s. But that'll surely go down when nice shading is introduced ...

 

Thanks for saying ?, the code is on my github (click in my avatar). Let me say that all this has not grown on my own dung, it is a collection of routines and algorithm i found, and i am a beginner hobby programmer. So i'll quickly update the credits in the readme.md file to contain the links to the most important sauces.

And it is wip, of course ...

.. starts updating credits in readme.

 

Screenshot_2019-05-18_10-44-18.thumb.png.f64652cebd40d3f45e8c40377ff5227d.png

Boxes and surface don't fit perfectly because they are drawn separately with different offsets because wip

 

@Green_Baron That's some great work, I'll see if I can pull your project.

I'm still not entirely convinced it's about culling in general just because of how tiny the scene size is, the gfx should be able to easily render 100k tris even with no culling at all at more than 80fps, but I will try to get it working and see if it helps. 

Thanks, I've enjoyed looking over all of your projects if nothing else. ?

You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts

On 5/17/2019 at 8:14 PM, VanillaSnake21 said:

I just want to conclude with something definitive, so everyone agrees that it's normal for the performance to drop 1300% when switching to wireframe mode? 

 

Edit: Also what are some solutions to this? If I want to overlay wireframe over the models, or if I want to use wireframe at any point in the renderings, is there some kind of custom solution that I have to write, a shader or something like that? Is there anything available already?

Have you considered this Single-pass Wireframe Rendering approach? It works by rendering filled triangles and calculates the outlines of the triangles in a fragment shader. The algorithm is pretty efficient however the major drawback is that it requires you to add an additional per-vertex attribute that stores the Barycentric coordinate of the vertex. This Barycentric coordinate would then be an input to your vertex shader where you pass it through to the fragment shader to get the interpolated point on the triangle. Using this point you can derive the distance from the edge of the triangle. If the point is near an edge of the triangle, you color the fragment black (or whatever color you want your outlines to be).

You should be able to find some tutorials for implementing this algorithm online.

I had the same problem with slow wireframes once, and as @bartman3000 said, the solution was to do single pass wireframes in a shader. This is *much* faster than using wire-edge rendering, and it produces better looking (and more controllable) wireframes. You can also render wire-frames on top of solid triangles at the same performance as solid triangles, with fewer issues, compared to the old-school slow two-pass process where you render a solid pass and a wireframe pass. 

The extra per-vertex attribute can be computed in a geometry shader. 

http://strattonbrazil.blogspot.com/2011/09/single-pass-wireframe-rendering_10.html

http://strattonbrazil.blogspot.com/2011/09/single-pass-wireframe-rendering_11.html

https://github.com/mattdesl/webgl-wireframes

https://www.codeproject.com/Articles/798054/WebControls/WebControls/?fid=1864339&df=90&mpp=25&prof=True&sort=Position&view=Normal&spc=Relaxed&fr=6

https://github.com/jeske/SimpleScene/tree/master/Assets/Shaders

Not sure if i missed it did anyone profile the GPU side? Do a capture of the data?

Its possible line rendering turns a triangle into 6 triangles, so you could end up transforming 6x the verts even though you render fewer pixels.

I'm pretty sure graphics APIs these days still draw lines as billboarded polygons. Hence drawing a triangle effectively triples the primitive output while cutting down the fillrate. If you're not fillrate-limited, you're going to run into the sheer overhead of processing all these additional primitives. Moreover, culling and optimizations like early Z testing are a lot less effective for objects drawn in wireframe, further increasing the polygon count when two or more surfaces oriented in the same general direction are visible.

 

On 5/18/2019 at 1:14 AM, VanillaSnake21 said:

Yes, but shouldn't the gfx card be able to handle millions of tris/second? My scene has 100,000 at max, and even then they're never drawn all at once.

Millions of tris per second versus 100k tris per frame. That's potentially two or three orders of magnitude of difference. Look at your framerate.

The screen shot you gave told me that when you enable wireframe mode, no depth rejection anymore. Those lines behind primitive now will output to final buffer. which implicit every triangles in view will go though whole pipeline. That's why your frame rate drop.

This topic is closed to new replies.

Advertisement