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.
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 :
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 :
IMultipleDragCube
moduleIMultipleDragCube
module is present :Camera.Render()
call from doing useless things on unused renderers)Camera.Render()
callsDragCubeSystem.CalculateAerodynamics()
)As of now, the KSPCF implementation has a few differences with the stock one, resulting in different drag cube values :
DragCubeSystem.CalculateAerodynamics()
re-implementation is more precise when computing the drag coefficient, so the final value will always be slightly different.The patch also fix two stock issues :
As a bonus feature, the patch also implements a visual "drag cube debugger" available from the "physics" tab of the stock debug window.