Earlier this year, BeamNG drive quietly made DirectX 12 its default renderer, laying the groundwork for what many simulation fans had been requesting for years: support for NVIDIA's DLSS and AMD's FidelityFX Super Resolution. The confirmation came shortly after the graphics overhaul, and while the average player sees it as a long-overdue boost to frame rates, the integration tells a far more interesting story about how a soft-body physics engine is forced to rethink its rendering pipeline from the metal up. When a physics sandbox built on soft-body simulation moves to DirectX 12 and adopts temporal upscaling, the result is more than just higher frame rates-it's a testbed for real-time Graphics architecture.
BeamNG drive's world is governed by thousands of interconnected nodes that deform in real time, and every pixel on screen is haunted by that physics computation. Adding DLSS and FSR into that environment isn't a simple plug‑in; it demands that the engine supply accurate Motion vectors for objects that don't behave like rigid meshes. And it asks developers to rethink how they handle jitter, depth precision. And asynchronous compute across frames. From a software engineering standpoint, the move exposes the friction between simulation fidelity and modern upscaling technologies. And it gives us a rare, production‑scale case study in real‑time graphics architecture.
In this article, I'll unpack the technical implications of the DirectX 12 transition, the data plumbing required to feed a temporal upscaler in a soft‑body simulation and what this means for performance‑sensitive engineering beyond the gaming world. Expect deep dives into motion vector generation for deformable geometry, API integration strategies, profiling toolchains. And how an engine originally derived from Torque3D has evolved into a surprisingly modern graphics testbed.
Moving From an Age‑Old Renderer to DirectX 12
For most of its life, BeamNG drive relied on a heavily modified DirectX 11 renderer built atop a custom fork of the Torque Game Engine. The decision to make DirectX 12 the default wasn't cosmetic; it unlocked lower‑level command list management, explicit resource barriers. And the ability to overlap physics and rendering work without serializing on the GPU pipeline. Senior rendering engineers will recognize that DX12's ExecuteIndirect and bindless descriptor heaps are particularly valuable for a simulation that streams thousands of dynamic draw calls every frame-each representing a deformable part of a vehicle.
The team at BeamNG GmbH essentially rewrote the resource binding model to move away from traditional DX11‑style slot‑based binding. In production environments, this is the same kind of refactor we've executed when migrating an in‑house engine from OpenGL to Vulkan: the rewrite forces you to confront lifetime management of descriptor tables, root signatures and pipeline state objects (PSOs) that previously the driver handled opaquely. The payoff is a measurable reduction in CPU draw‑call overhead-often 30-50% in scenes with hundreds of dynamic objects-and the headroom needed to inject new passes like DLSS or FSR.
Documentation from Microsoft's Direct3D 12 graphics programming guide highlights the importance of pre‑compiled PSOs and resource state tracking, both of which become critical when a temporal upscaler expects consistent render target formats and UAV barriers across its motion‑vector and depth passes. BeamNG's engine now leverages these mechanisms to guarantee that the data handed to the upscaler is coherent and doesn't stall the GPU unnecessarily.
The Unsung Hero: Why DLSS and FSR Require a Modern Renderer
Temporal upscalers aren't just post‑processing filters; they're real‑time reconstruction algorithms that fuse samples from multiple frames using jitter offsets, sub‑pixel motion. And depth‑aware disocclusion logic. NVIDIA's DLSS programming guide and AMD's FidelityFX SDK both stipulate that the application must supply high‑quality motion vectors, a linear‑depth buffer. And a carefully controlled jitter pattern. In a DX11 binding model, capturing these mid‑pipeline resources without breaking the command stream was fragile and often relied on driver‑specific workarounds. DX12's explicit resource aliasing and UAV access across stages make it possible to expose these inputs reliably.
BeamNG drive's transition to DX12 as the default renderer enabled the engine to set up a dedicated "upscaling‑inputs" pass that runs before post‑processing. In this pass, the engine exports a motion‑vector texture (typically a 16‑bit per channel floating‑point buffer with NDC‑space velocities), a linearized depth buffer, and the raw jittered color frame. Because DX12 lets the developer schedule async compute queues, the physics thread can update node positions while the GPU resolves these buffers, reducing frame‑time variance compared with the old serialized pipeline.
For engineers evaluating whether to adopt FSR 2 or DLSS 3 in their own products, the prerequisites are instructive: you need a renderer that can produce per‑pixel motion vectors for every visible surface, not just rigid‑bodied camera movement. This requirement becomes uniquely challenging when geometry can't be assumed to transform according to a single matrix, which is exactly the problem BeamNG's soft‑body vehicles present.
When Physics and Pixels Collide: Deformable Bodies vs. Temporal Data
A conventional game engine ships motion vectors by saving the previous frame's clip‑space position of each vertex and comparing it with the current position. Those deltas are interpolated across the triangle and written to a render target. For rigid objects, a simple temporal reprojection matrix does the job. In BeamNG drive, a car chassis is composed of hundreds of individually simulated nodes connected by beams, and between two frames a door panel can crumple, a bumper can shear off, and a roof can bow inward there's no single matrix that describes the motion of that geometry.
The engine must compute per‑vertex motion vectors by explicitly tracking node positions from the previous simulation step and then rasterizing the deformed triangle mesh. This forces the vertex shader to read a previous‑frame position buffer alongside the current node grid, a bandwidth‑intensive operation that would have crushed performance on the old binding model. With DX12, the team can alias that previous‑frame position data as a read‑only structured buffer and bypass the CPU entirely, feeding it directly into the vertex shader via a descriptor table.
The result is that motion vectors can be generated for even the most violently deforming surfaces, provided the simulation produces temporally coherent node identifiers. In practice, node splits or spawns-common when parts detach-create discontinuities. Here the engine likely falls back to a "no‑motion" sentinel value, leaving the upscaler to treat that area as disoccluded and rely on new jittered samples. This fallback logic is invisible to players but a fascinating software design puzzle that mirrors challenges we've seen in cloth‑simulation pipelines using NVIDIA's PhysX FleX.
Generating Reliable Motion Vectors for Non‑Rigid Surfaces
In any temporal algorithm, the motion vector map is the single most important input after color data. DLSS in particular is sensitive to vector precision; NVIDIA recommends at least 16‑bit floating‑point per component and the vectors must be in NDC (normalized device coordinates) relative to the current jitter offset. In BeamNG drive. Because each deformable sub‑mesh can contain hundreds of vertices with independent displacements, the motion vector pass becomes a compute‑intensive operation on its own.
To keep the pass from becoming a bottleneck, the engineering team probably opted for a multi‑pass approach: first, a compute shader runs over the node grid to calculate per‑node screen‑space velocity, taking into account both the object's world‑space movement (rigid body position of the vehicle) and the local deformation delta. Then a vertex shader uses that velocity buffer during the main render pass to output per‑pixel motion vectors into a separate render target. This indirection is similar to the technique described in AMD's FidelityFX Super Resolution 2. 1 documentation. Where a "motion vector pass" can be decoupled from the main depth pass to allow better profiling and tuning.
One edge case worth noting is particle effects-smoke, dust, sparks-which in many engines don't contribute motion vectors. If DLSS or FSR receive pixels without valid vectors, ghosting artifacts appear. BeamNG likely masks those regions or uses a pre‑computed alpha coverage map so the upscaler can ignore them. But the cleaner solution would be to emit motion vectors for volumetric particles as well, an approach that Unreal Engine 5 has begun exploring with Niagara integration. The absence of visible ghosting in leaked footage suggests BeamNG's team has handled this carefully.
Balancing Two Integrations: NVIDIA Streamline vs. AMD FidelityFX
While the underlying data plumbing is identical, integrating DLSS and FSR simultaneously forces a strategic decision. NVIDIA offers the Streamline framework, an open‑source cross‑vendor plug‑in that abstracts both DLSS and FSR 2 behind a single interface, handling resource binding, jitter offset calculation. And UI exposure. AMD provides the FidelityFX SDK as a collection of header‑only libraries with explicit API calls for each pass.
For BeamNG drive, using Streamline could have been tempting because it reduces per‑vendor code paths and lets the engine defer to the framework for optimal upscaler selection at runtime. However, the soft‑body nature of the simulation might have pushed the team toward a more bespoke integration: directly calling FidelityFX's Fsr2Execute function after their custom motion‑vector and depth passes, and doing the same for DLSS via the NGX API. This hybrid approach gives more control over barrier placement and descriptor recycling-important when every microsecond of GPU time competes with the physics simulation that runs on the CPU.
One architectural nuance is the handling of exposure and color space. DLSS operates on HDR linear data. While FSR 2 can accept both LDR and HDR inputs after an internal tonal mapping step. In a simulation where lighting conditions change rapidly-bright sunlight, dark tunnels-engineers must ensure the upscaler doesn't amplify flicker or introduce luminance drift. The fix often involves running the upscaling pass in a normalized color space like scRGB and then tone‑mapping afterward, a trick we've used in automotive visualization projects to keep temporal stability under varying ambient light.
Performance Profiling and Debugging the Upscaled Pipeline
With DLSS and FSR becoming part of the main frame loop, profiling becomes a multi‑dimensional challenge. On NVIDIA hardware, tools like Nsight Graphics let you visualize the motion‑vector buffer, inspect disocclusion masks. And measure the tensor core utilization during DLSS inference. On AMD, the Radeon GPU Profiler (RGP) and RenderDoc can capture the FSR2 passes. Though the upscaling compute shaders are often bundled inside the AMD library and may appear as internal dispatches.
In our own rendering work, we've found that the quality of motion vectors can degrade with certain post‑effects like motion blur or film grain applied before the upscaler. BeamNG's team likely moved those effects after the upscaling step, ensuring the upscaler receives a cleaner signal. They may have also implemented a validation layer-similar to what we use in CI for shader compiler tests-that periodically dumps motion‑vector statistics to detect regions where vectors exceed a reasonable velocity threshold, flagging potential ghosting before it hits QA.
Another area of concern is memory bandwidth. A 4K depth buffer and a full‑resolution motion‑vector texture together can consume over 100 MB of VRAM. And in a simulation where the physics system
.Need a Custom App Built?
Let's discuss your project and bring your ideas to life.
Contact Me Today →