2
\$\begingroup\$

In my game I have a billiard table, and a floor below the table. In typical situation the table covers 80% of the screen, so only small amount of the floor is visible. And I render the table first, so invisible part of the floor is discarded by the depth buffer test.

But profiling with Nsight shows me drawing the floor takes significant amount of time, and it is spent in the rasterizer. It seems generating all those pixels of the floor and depth testing them takes a long time.

I'm wondering how to solve this problem and one thing I tried is to divide the floor (a rectangle with two triangles) to multiple rectangles, so some of them could be cancelled in an earlier stage. The problem is, this is still one model / mesh, just with more triangles and I don't know how to start.

What would be a way to achieve this in Monogame + HLSL? Somewhere in vertex shader? Or gemoetry shader (is it supported in monogame?)

Or is there any other way to optimize this?

UPDATE: the whole floor is needed and might be drawn depending on where the camera is, so I can't get rid of parts of it. In typical situations table top covers 80% of the screen because of perspective and looking down at an angle. The game is in 3D.

\$\endgroup\$
  • \$\begingroup\$ Consider breaking the table into sections and render only what is in the Frustum. \$\endgroup\$ – Krythic Nov 16 '16 at 14:40
2
\$\begingroup\$

Break the floor geometry such that invisible pieces are not there at all

\$\endgroup\$
  • \$\begingroup\$ How do I achieve this? Update: whole floor is needed sometimes, will update the question. \$\endgroup\$ – Arek Nov 16 '16 at 12:46
  • \$\begingroup\$ Use blender or any 3d program to edit the model \$\endgroup\$ – Yashwanth CB Nov 16 '16 at 12:48
  • \$\begingroup\$ I think you mean removing the floor which is always not visible - this is not possible. I updated the question to make it clear. \$\endgroup\$ – Arek Nov 16 '16 at 12:50
  • \$\begingroup\$ Then I think...ordering the objects is thy only way \$\endgroup\$ – Yashwanth CB Nov 16 '16 at 12:56
  • \$\begingroup\$ Or make the floor into 2 objects...one always visible..like a frame .and Inge hardly visible.Both of which you tried \$\endgroup\$ – Yashwanth CB Nov 16 '16 at 12:57
1
\$\begingroup\$

You have these options:

  • Render the table first, and the floor second and have depth testing on. This will cancel calling the pixel shader on the floor pixels where the table has already been drawn. (though the rasterizer will still do its work) (edit: Oh I see you are already doing that)
  • Frustum culling: don't render anything that is not in the view frustum. Usually visibility is determined by checking the object's bounding box against the view frustum.
  • Occlusion culling: Don't call the draw if it is occluded. I don't know if occlusion queries are available i XNA though. It is also doable by a software occlusion culling technique, but I doubt it would be fast enough if it is done in C#. This is a broad topic, I won't get into details here.
  • Culling primitives in the geometry shader. This is not available in XNA, but in monogame it is when using a DirectX 11 renderer. For each primitive you can test it against the view frustum, and decide if you want to send it to the pixel shader. I don't know if adding this extra shader stage will help you or not though, it's just an idea.
\$\endgroup\$
  • \$\begingroup\$ Frustrum culling and occlusion culling - if I understand correct - would be options to get rid of the whole object, not individual parts of it. And while I'm fine with splitting the floor to multiple triangles, I think it doesn't make sense to make it multiple objects and render in several batches - or does it? \$\endgroup\$ – Arek Nov 16 '16 at 15:58
  • \$\begingroup\$ The last option is interesting, but I thought Geometry Shading is not available in monogame. Can you point me into right direction? \$\endgroup\$ – Arek Nov 16 '16 at 15:59
  • \$\begingroup\$ I don't know for sure, but Monogame has a DX11 backend and that could be capable of running a geometry shader. Splitting big objects into smaller ones might help, if you use a CPU side culling technique, think about splitting a huge terrain into chunks, because you wouldn't want to render a million vertices. \$\endgroup\$ – János Turánszki Nov 16 '16 at 20:17
  • \$\begingroup\$ It seems Monogame doesn't support GS. It is on the wish list but implementation is probably complicated.. \$\endgroup\$ – Arek Nov 17 '16 at 13:47

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.