Jump to content

Developer Insights #9 – Orbit Tessellation


Intercept Games

Recommended Posts

15 hours ago, Incarnation of Chaos said:

Is this done on the CPU or GPU? If the latter, what's the implications for AMD GPU which generally struggle with tessellation in games? 

Also, does this also mean that it might be possible to use a "tiled" approach to rendering KSP2 in the far future? 

Between this and the way your team is handling extrasolar systems with their own floating origins, there's a lot of potential for very interesting things to increase performance.  

Amazing writeup though, this is the stuff that I want to see!

The kind of tessellation you are referring to is GPU-accelerated mesh tessellation that is a part of the rendering pipeline on modern GPUs:

Introduction - Vulkan Tutorial

(image source)

GPU tessellation is specifically designed to take a mesh and subdivide its triangles, which are then used in subsequent shader steps and ultimately rendered as a texture. The key takeaway is that the mesh generated by this tessellation operation is intended to be used for rendering, and otherwise cannot really be accessed directly anymore by code running on the CPU. It also requires a sufficiently detailed input mesh that you pass to the GPU first.

The kind of "tessellation" discussed in my article is fairly different. We use the CPU to generate a relatively small set of points (rarely more than 100 per orbit) and their bounding volumes which we need to be able to access later for more than just rendering. This is also before any triangle mesh has been generated. If you want to render the path that is defined by these points you still need to generate a mesh first to pass to the GPU. For example in my sample code that would be performed in the implementation of the Draw.Line call itself. GPU tessellation is generally better suited for large complex geometry that you want to look smoother up close, such as terrain.

While a more generalized compute shader could be used to perform some calculations, there is always overhead when passing data to and from the GPU and so it generally makes more sense in cases where you have a large enough amount of simple calculations to perform to really benefit from the GPU's parallelization. We do use compute shaders for some systems where there are clear performance benefits, but not for generating the points of our orbits.

Edited by Johannes
Link to comment
Share on other sites

 

On 4/22/2021 at 5:56 AM, OutInSpace said:

So this is why the orbits in KSP1 look funky and inaccurate. I feel like I've just had some great cosmic truth revealed to me...

One thing I did not address in the original post is that this is less of an issue in KSP1 since it fades out orbits based on context: When you zoom in close enough on a celestial body its orbit fades away, for example when looking at Kerbin close enough to see its Moons as I do in my mockup. This is absolutely a valid approach which makes the issue far less noticeable in most cases.

Edited by Johannes
Link to comment
Share on other sites

20 hours ago, Johannes said:

The kind of tessellation you are referring to is GPU-accelerated mesh tessellation that is a part of the rendering pipeline on modern GPUs:

Introduction - Vulkan Tutorial

(image source)

GPU tessellation is specifically designed to take a mesh and subdivide its triangles, which are then used in subsequent shader steps and ultimately rendered as a texture. The key takeaway is that the mesh generated by this tessellation operation is intended to be used for rendering, and otherwise cannot really be accessed directly anymore by code running on the CPU. It also requires a sufficiently detailed input mesh that you pass to the GPU first.

The kind of "tessellation" discussed in my article is fairly different. We use the CPU to generate a relatively small set of points (rarely more than 100 per orbit) and their bounding volumes which we need to be able to access later for more than just rendering. This is also before any triangle mesh has been generated. If you want to render the path that is defined by these points you still need to generate a mesh first to pass to the GPU. For example in my sample code that would be performed in the implementation of the Draw.Line call itself. GPU tessellation is generally better suited for large complex geometry that you want to look smoother up close, such as terrain.

While a more generalized compute shader could be used to perform some calculations, there is always overhead when passing data to and from the GPU and so it generally makes more sense in cases where you have a large enough amount of simple calculations to perform to really benefit from the GPU's parallelization. We do use compute shaders for some systems where there are clear performance benefits, but not for generating the points of our orbits.

Awesome, that's what I was hoping for. 

One more question about this though, since you already have multiple points and are using vectors is there anything spun off to additional cores/threads? That would be a potential game changer for higher conic settings and just increase performance in general. (I feel like it would be a pain to program that though)

Or is it just good enough on a single thread? Especially since you could probably use some instruction sets like SSE or AVX to accelerate. 

 

Link to comment
Share on other sites

On 4/28/2021 at 10:23 AM, Incarnation of Chaos said:

Awesome, that's what I was hoping for. 

One more question about this though, since you already have multiple points and are using vectors is there anything spun off to additional cores/threads? That would be a potential game changer for higher conic settings and just increase performance in general. (I feel like it would be a pain to program that though)

Or is it just good enough on a single thread? Especially since you could probably use some instruction sets like SSE or AVX to accelerate. 

Without going into too many details, we are using Unity Jobs in conjunction with the Burst Compiler and Unity.Mathematics to speed up some of the more expensive calculations. 

Edited by Johannes
Link to comment
Share on other sites

2 hours ago, Johannes said:

Without going into too many details, we are using Unity Jobs in conjunction with the Burst Compiler and Unity.Mathematics to speed up some of the more expensive calculations. 

 

2 hours ago, prestja said:

I'm impressed. Those are some excellent design decisions. I hope to hear more about KSP2's optimizations in the future!

I concur, while i wasn't too cynical about KSP2's potential from a performance standpoint even a year ago. Just knowing the developers are tackling issues like this head-on and squeezing every last bit of performance possible from their implementations makes me very, very happy.

@Johannes

Thank you so much for your time btw. I really do appreciate you (and other KSP2 developers) taking the time to answer my questions.

10 minutes ago, Grimmas said:

It's certainly bold. I'm not too familiar with Unity yet but isn't this DOTS stuff still in early preview state? Though Unity is pushing it everywhere they can, and have done so for the last few years. 

I've been hearing about DOTS for almost 2 years at this point, but as far as how far along it is from a production/usability standpoint you'd have to ask someone far more familiar with Unity specifically than me.

Link to comment
Share on other sites

24 minutes ago, Incarnation of Chaos said:

I've been hearing about DOTS for almost 2 years at this point, but as far as how far along it is from a production/usability standpoint you'd have to ask someone far more familiar with Unity specifically than me.

DOTS is far from production-ready. It's still a preview package and there are occasional game-breaking API changes, and I believe custom serialization is still a pain.

Link to comment
Share on other sites

16 hours ago, Grimmas said:

It's certainly bold. I'm not too familiar with Unity yet but isn't this DOTS stuff still in early preview state? Though Unity is pushing it everywhere they can, and have done so for the last few years. 

 

15 hours ago, prestja said:

DOTS is far from production-ready. It's still a preview package and there are occasional game-breaking API changes, and I believe custom serialization is still a pain.

We are not using the full DOTS stack. We specifically use jobs to parallelize calculations in a few select systems where there are clear performance benefits. For example using jobs allows PQS+ to be considerably faster than the original system in KSP1 and without which the quality of terrain that we are working on would not really be feasible. 

Your concerns are absolutely valid. We try to be very careful when evaluating any new technologies that we might use in this project. The Unity Jobs System has been a part of our codebase since fairly early in development, but its uses are also isolated enough that if it was really necessary it could be replaced with another multithreading mechanism. So far however it has suited our needs well.

Edited by Johannes
Link to comment
Share on other sites

1 hour ago, Johannes said:

 

We are not using the full DOTS stack. We specifically use jobs to parallelize calculations in a few select systems where there are clear performance benefits. For example using jobs allows PQS+ to be considerably faster than the original system in KSP1 and without which the quality of terrain that we are working on would not really be feasible. 

Your concerns are absolutely valid. We try to be very careful when evaluating any new technologies that we might use in this project. The Unity Jobs System has been a part of our codebase since fairly early in development, but its uses are also isolated enough that if it was really necessary it could be replaced with another multithreading mechanism. So far however it has suited our needs well.

Will you all be applying similar optimizations to part quality and physics?

(similar in level of improvement, not necessarily in manner. I don't know a whole lot about this stuff :confused:)

Edited by Spaceman.Spiff
Link to comment
Share on other sites

2 hours ago, Johannes said:

For example using jobs allows PQS+ to be considerably faster than the original system in KSP1

I'm very excited for this. Terrain resolution changes in KSP1 were the number one cause of stutters.

2 hours ago, Johannes said:

The Unity Jobs System has been a part of our codebase since fairly early in development

Unity Jobs is fairly mature and enjoyable to work with. I wish the Entity Component System framework was more mature, there's a clear use case for PartModules where MonoBehaviour just doesn't cut it.

Link to comment
Share on other sites

  • 2 weeks later...
  • 3 weeks later...

Thanks for taking the time to write this up - I'm sure you, as a programmer, don't have a lot of time to devote to these extras to keep people interested in your work... BUT it pays off and I love hearing about it!!! 

Another nuance of the "flattened orbit" problem is shading.  We typically see things go off into the distance - and as that happens it becomes fainter and fainter until we can't see it.  In Kerbal, the orbit is shown at 100% brightness even though the line we see is millions of kilometers away - and that is why we see that sharp corner to begin with.   

My personal preference has been that the orbit should be shown in "relative distance".  When I'm  that close to the orbit line, my focus is really the objects that are on or near that orbit.  I really don't care if the orbit line curves to the left or right millions of kilometers away - I'm only concerned about orbit intersections and object interactions -- thus the reason I zoomed in to begin with.   So,  the "closer" I am to the orbit line, the more of this "fading" should happen -- I should just see the orbit line go off into the distance (perhaps showing the faintest of suggestions that it curves left or right.

That said, you guys are amazing and I can't wait to see what you've done with the place!!

Link to comment
Share on other sites

  • 3 weeks later...

HEY, HEY, HEY! I love it! I always disliked it when I would zoom in on Kerbin and I would see it be maybe 10 million meters from the orbit line, same with my interplanetary missions, it was just frustrating not knowing how close the maneuver was other than the time away from it.

Link to comment
Share on other sites

  • 2 weeks later...

I still can not believe that making an orbit was that hard. And simply making it looked nice needs so many points. It still boggles my mind. I mean, how, This is still informative and maybe this could be implemented into KSP like a mod. 

Link to comment
Share on other sites

On 6/22/2021 at 1:19 PM, Dr. Kerbal said:

I still can not believe that making an orbit was that hard. And simply making it looked nice needs so many points. It still boggles my mind. I mean, how, This is still informative and maybe this could be implemented into KSP like a mod. 

Yeah, computer graphics can often appear far simpler than their actual implementation needs to be. It's generally far easier/faster to draw a ton of straight lines that then appear like a curve, than to actually draw a completely accurate curve. And this is really only an issue in our specific use case because of the extreme camera perspectives these lines need to be viewed from.

Additionally, as I touched on at the end of the post, we use the generated point data for more than just rendering, such mouse interaction raycasting, so while doing it all on the GPU and just throwing an obscene number of points at it and not worry about efficiently spacing them would have been a possible solution, for our use case a smaller, but more carefully placed, set of points ended up being a solid compromise.

Edited by Johannes
Link to comment
Share on other sites

  • 2 weeks later...
On 6/24/2021 at 4:01 PM, Johannes said:

Yeah, computer graphics can often appear far simpler than their actual implementation needs to be. It's generally far easier/faster to draw a ton of straight lines that then appear like a curve, than to actually draw a completely accurate curve. And as touched on, this is really only an issue in our specific use case because of the extreme camera perspectives these lines need to be viewed from.

Additionally, as I touched on at the end of the post, we use the generated point data for more than just rendering, such mouse interaction raycasting, so while doing it all on the GPU and just throwing an obscene number of points at it and not worry about efficiently spacing them would have been a possible solution, for our use case a smaller, but more carefully placed, set of points ended up being a solid compromise.

Computer Games... like Space... is hard.

Link to comment
Share on other sites

On 4/27/2021 at 3:18 PM, Johannes said:

 

One thing I did not address in the original post is that this is less of an issue in KSP1 since it fades out orbits based on context: When you zoom in close enough on a celestial body its orbit fades away, for example when looking at Kerbin close enough to see its Moons as I do in my mockup. This is absolutely a valid approach which makes the issue far less noticeable in most cases.

 

Wish there was a mod like this. Far high eccentric orbits get really wonky. Espcialy when I have to go 10,000 Petameters. 

Link to comment
Share on other sites

On 6/24/2021 at 4:01 PM, Johannes said:

Yeah, computer graphics can often appear far simpler than their actual implementation needs to be. It's generally far easier/faster to draw a ton of straight lines that then appear like a curve, than to actually draw a completely accurate curve. And as touched on, this is really only an issue in our specific use case because of the extreme camera perspectives these lines need to be viewed from.

Yeah, when this topic went up, I immediately started thinking about a pixel-perfect conic section curves in a shader. And you can absolutely do this with a screen-space pixel shader, which would be a fairly platform-agnostic solution and you can reduce the overhead by having a single draw call handle an array of orbits, but it's still rather expensive. A better way is a geometry shader that effectively rasterizes a curve, but at that point, performance is comparable to simply segmenting the curve on the CPU side, visual difference exceptionally minor, and you certainly lose some flexibility in terms of supported platforms. Actually, I'm not sure what kind of support Unity even has for custom geometry shaders in the first place.

At any rate, yeah, turning these curves into linear splines on CPU and sending them to GPU as vertex buffers is the right call here. Even though the perfectionist in me really wants pixel-perfect conics.

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...