Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New patch : DragCubeGeneration #139

Merged
merged 6 commits into from
May 6, 2023
Merged

New patch : DragCubeGeneration #139

merged 6 commits into from
May 6, 2023

Conversation

gotmachine
Copy link
Contributor

@gotmachine gotmachine commented Apr 6, 2023

So after much fiddling around, I got a prototype re-implementation working.
This is intended to address issue #137

Here is a preview release :
KSPCommunityFixes_DragCubeGeneration_RC3.zip

Some profiling stats, for loading a stock + DLCs install :

  • Baseline : 2.97s (part compilation with partdatabase.cfg already generated, KSPCF FastLoader active)
  • Stock drag cube generation : 12.91s (part compilation with partdatabase.cfg creation, KSPCF FastLoader active)
  • KSPCF drag cube generation : 5.51s (part compilation with partdatabase.cfg creation, KSPCF FastLoader active)

So KSPCF drag cube generation is taking ~2.5s instead of ~10s. This was tested with a 6700XT GPU, it's probable the gains won't be as good with a low end GPU where the bulk of the time is spent doing the render and texture readback.

Aside from loading time (which are only relevant when the part database is regenerated), this also provide a significant in-game speedup for everything that generate drag cubes on the fly. In stock, this only affect fairings, but there are many mods making heavy use of runtime drag cube generation (either manually, or by using the stock "procedural" drag cubes system). Popular examples include B9PartSwitch, SimpleAdjustableFairings, SSTU, Procedural Parts, ProceduralWings, DecouplerShroud...

All optimizations are done by avoiding some pointless CPU overhead, and massively reducing GC allocations :

  • Directly render the drag cube on the original part using a command buffer (instead of instantiating a copy, which results in all child parts being instantiated and immediately destroyed in the editor) unless the part has a IMultipleDragCube module
  • In case a IMultipleDragCube module is present :
    • Avoid instantiating attached childs of the part (especially relevant in the editor, but also in flight for physicless childs)
    • Various optimizations to the copy setup
  • Use of a command buffer instead of a culling mask on the camera (avoid the Camera.Render() call from doing useless things on unused renderers)
  • Prevent canvas/UI update on Camera.Render() calls
  • Using a single shared material for all renderers
  • Massively optimized method for analyzing the texture and extracting area/drag/depth (DragCubeSystem.CalculateAerodynamics())

As of now, the KSPCF implementation has a few differences with the stock one, resulting in different drag cube values :

  • The DragCubeSystem.CalculateAerodynamics() re-implementation is more precise when computing the drag coefficient, so the final value will always be slightly different.
  • The KSPCF system generate a the part bounding box by relying on the mesh local bounds, instead of the bounds computed by the mesh renderer. This is necessary to allow rendering drag cubes on arbitrarily rotated parts (instead of a world axis aligned copy), and is more reliable in the specific case of skinned meshes (see issue comment ). This also fix a specific stock issue where the light meshes are included in the bounds (notably causing totally wrong depth/bounds for the stock landing gears). But specifically in the case of skinned meshes, the center/size values of the drag cube will differ from the stock values, and might be an overestimation in some cases (for example, the stock inflatable heat shield size while retracted will be vastly overestimated, but this is the case too in the stock drag cube). In any case, the values will always be more reliable than the stock ones, so while this does induce a behavior change regarding buoyancy and thermodynamics, it arguably will always be beneficial.
  • If the part uses a shader that allow transparency (ie, with "alpha" in the name), the stock drag cube system will treat fully transparent areas of the texture as hollow. I can't think of a single use case, in stock or mods, and even if that was used, I don't think this would provide reliable results as far as the drag cube is concerned.
  • If the part uses a bump map, stock will try to account for it in the red channel / drag coefficient. Going to such a high level of precision when the whole drag cube aerodynamics system has much larger sources of imprecision down the line feels totally silly. Moreover, this create a discrepancy depending on part size, because the drag texture is always 256x256 no matter the part size, so the bump map details will be very significant on small parts, and have zero impact on large parts. Overall, I don't see any significant difference in the generated drag cube drag coefficient when not using the bump map. Additionally, the bumped shader doesn't work correctly in some cases, so getting ride of it also get ride of the issues (see issue comment )

The patch also fix two stock issues :

  • If the drag cube generation fails mid-course for any reason (for example an exception in AssumeDragCubePosition()), the instantiated part copy will just stay around until the next scene switch. This mean that all further drag cube renders will have the failed part in the view, basically producing garbage results for all remaining parts.
  • "Detached" parts in the editor will have all their gameobjects set to layer 2 (TransparentFX). The stock drag cube system ignore all renderers on that layer, so generating a drag cube on a detached part will fail completely. The workaround is to use the underlying logic that stock is using to determine if a GameObject should be on layer 2, which is : if any material on the renderer uses a shader whose name contains the "Translucent" substring.

As a bonus feature, the patch also implements a visual "drag cube debugger" available from the "physics" tab of the stock debug window.

Faster and more reliable implementation of drag cube generation. Improves overall loading times (both game load and scene/vessel/ship load times), prevent occasional lag spikes (in the editor mostly) and fix some issues causing incorrect drag cubes to be generated (notable examples are the stock inflatable heat shield, the 1.25m and 2.5m nose cones and the Mainsail shroud). Note that by design, this patch results in a small deviation from the stock behavior for buyoancy, aerodynamics and thermodynamics, as the generated drag cubes will be slightly different.
…while the generation for the previous part isn't finished during part compilation due to missing integration with the "framerate unlocked" part compilation of the FastLoader patch.
… when called on a part set to translucent (ie, detached part in the editor)
@gotmachine gotmachine merged commit 5d85327 into dev May 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

1 participant