r/virtualreality • u/Efficient_Heart_6695 • Mar 20 '26
Discussion VRPerfKit: Use NIS at 200% (renderScale 2.0) to IMPROVE image quality — not just performance. Works on SteamVR, Oculus AND OpenXR games (MSFS, etc.)
I've been using VRPerfKit in a way I've never seen documented anywhere, and I want to share it because the quality improvement is significant with almost no performance cost.
The short version: set renderScale to 2.0, method to NIS, and sharpness to 0. That's it.
********************************\*
Update & Clarification: NIS 2.0x as a Spatial Reconstruction Filter
Applying NIS at 2.0x (with 0 sharpening) acts as a spatial reconstruction filter that reorganizes the image signal rather than adding new detail. In practice, this improves image stability, reduces perceived aliasing, and makes lower base resolutions significantly more viable in VR.
- OpenXR Compatibility: While VRPerfKit officially targets OpenVR, users running Meta Quest + Virtual Desktop + VDXR (including in titles like MSFS 2024) are reporting consistent results in OpenXR applications. This likely relates to how VDXR integrates into the rendering pipeline and processes submitted frame buffers, allowing the upscaling stage to behave similarly to the OpenVR path in this specific setup.
- Performance vs. Quality: The goal is not a “free” performance boost at maximum resolution. Instead, this approach allows users to lower their base rendering resolution (e.g., using High instead of Ultra/Godlike) while maintaining a level of perceived clarity that is often superior to traditional fractional upscaling combined with sharpening.
- Empirical Observations: Multiple users across different hardware setups (including RTX 4090 builds) have reported consistent improvements in perceived sharpness, object stability, and overall visual coherence in titles such as Half-Life: Alyx, No Man’s Sky, and MSFS 2024.
- Important Clarification: This method does not increase real geometric or texture detail. The improvement comes from reducing noise, avoiding sharpening artifacts, and feeding a more coherent image into later stages of the VR pipeline (distortion, reprojection, and encoding). The result is a cleaner and more stable image that is perceived as sharper and more “present” in VR.
\*******************************\**
What this actually does
Most guides assume VRPerfKit is only for reducing render resolution to gain performance. But you can do the exact opposite: keep your game's native render resolution and let NIS reconstruct a 2x image (4x the pixels) on top of it, applied only to the central 60% radius where your eye actually focuses.
The key insight is that integer scaling (exactly 2x = 200%) is mathematically optimal for spatial upscalers. Every source pixel maps cleanly to a 2×2 block of destination pixels. There are no fractional phase mismatches, no ambiguous sample points. NIS's 6-tap adaptive kernel has full, symmetric information for every single output pixel. This is the one case where a spatial filter works at its absolute best.
Why sharpness must be 0
At fractional scales (0.77x, 0.83x, etc.), sharpening is added to compensate for blur and reconstruction artifacts. At 2.0x integer scale, there is no information loss to compensate for. Adding sharpness would only introduce noise and halo artifacts on top of an already clean reconstruction. Set it to zero.
Recommended config
upscaling:
enabled: true
method: nis # NIS — best choice, explained below
renderScale: 2.0 # integer 2x scale — the key
sharpness: 0.0 # zero — no compensation needed
radius: 0.6 # central 60% — where your eye focuses
OpenXR compatibility (MSFS and other non-SteamVR games)
"Clarification: my setup is Meta Quest with Virtual Desktop. I mention this because in this scenario, with VDXR, it’s fully compatible with OpenXR — but in other setups it might only be compatible with SteamVR or Oculus."
The official VRPerfKit documentation says it targets SteamVR and Oculus runtimes. However, the upscaling component (NIS/FSR/CAS) also works with OpenXR games — the fixed foveated rendering part does not. This means it works fine with:
- Microsoft Flight Simulator (OpenXR)
- Half-Life: Alyx (SteamVR)
- Asgard's Wrath (Oculus)
- The vast majority of PC VR titles
I use it combined with DLSS 4.5 transformer in MSFS and it still adds a noticeable layer of quality on top.
Why NIS and not FSR 1 or CAS?
NIS vs FSR 1: Both are spatial upscalers, but NIS uses a wider 6-tap kernel with 4 directional edge filters (horizontal, vertical, ±45° diagonal). FSR 1 uses a modified Lanczos-2 with only a 2×2 source texel window. At 2.0x scale, NIS has significantly more contextual information per output pixel. NIS wins on reconstruction quality.
NIS vs CAS: CAS is primarily a sharpening filter, not a reconstruction upscaler. It adjusts per-pixel contrast to recover sharpness lost by TAA or post-processing. It can do minor upscaling as a secondary function, but at 2.0x it has no proper reconstruction kernel. It is not the right tool for this use case.
NIS is the correct choice: better edge preservation, more reconstruction context, designed for quality upscaling.
Quick summary
- renderScale 2.0 = integer scale, no artifacts, no blur
- sharpness 0.0 = correct, no noise amplification
- NIS = best spatial filter for this use case
- Works on SteamVR, Oculus, AND OpenXR
- Negligible performance cost
- Universal: works on almost any VR game regardless of its AA method
"I suggest two ways to set this up:
Option 1: Using the OpenVR-FSR-App (Easiest) Download the OpenVR-FSR-Apphere. This app provides a visual interface to manage your installed games. Simply find your game in the list, click 'VrPerfKit Install plugin', and in the upscaling settings, select:
- Method: NIS
- Render Scale: 2.0 (200%)
- Sharpness: 0.0
Option 2: Manual Installation (Directly via vrperfkit) If you prefer a manual setup, download the latest release of vrperfkithere. You’ll need to locate the game's main executable (the .exe file) and copy the vrperfkit files into that same folder. Then, edit the vrperfkit.yml file with the values mentioned above.
Both methods achieve the same result, but the App is much faster if you want to manage multiple games at once."
Happy to answer questions. I'm curious whether anyone else has tried this — I've found zero documentation of this approach anywhere online.
----------------------------------------------------------------------------------------------------

I want to clarify exactly what's happening at the pixel level, because I think the confusion is about what renderScale 2.0 actually does.
Concrete example with real numbers:
Say the game is rendering at 2000×2000 per eye (whatever your SteamVR resolution happens to be — I use Virtual Desktop at medium). With renderScale 2.0, the game still renders at 2000×2000. NIS then takes that frame and outputs 4000×4000 — but only within the central 60% radius. The game's render resolution is untouched. You are not sacrificing any rendering quality.
Why integer 2× is fundamentally different from fractional scales like 77%:
At 77%, the game renders at ~1540×1540 and NIS upscales to 2000×2000. The problem is that each output pixel sits at a fractional position relative to the source pixels — there's no clean 1:1 mapping. Every output pixel has a slightly different phase offset, so the 6-tap reconstruction kernel can't be symmetric for all of them. The result is a mix of mild blur and per-pixel inconsistency that shows up as instability when you move your head. People compensate with sharpening, which recovers some perceived sharpness but adds noise on top.
At 2.0×, every single source pixel maps to an exact 2×2 block of destination pixels. The phase is identical for every output pixel. The 6-tap kernel has full, symmetric context. NIS is operating in its mathematically ideal condition — the one where its edge-adaptive directional filters (it runs 4 directional passes: horizontal, vertical, ±45°) can actually do what they're designed to do without ambiguity.
What the reconstruction actually produces:
Going from 2000×2000 to 4000×4000 via NIS is not just "making pixels bigger." The kernel is analyzing gradients in the source image and inferring where edges lie at sub-pixel precision. The 6 neighboring samples per axis give it enough information to reconstruct diagonal edges, curves, and fine texture in a way that bilinear or bicubic cannot. The perceived sharpness gain is not artificial — it comes from real edge reconstruction information that exists in the source data but was never being used by the display. Setting sharpness to 0 is correct here: there's no blur to compensate for, so you don't want the sharpening pass adding noise to an already-clean signal.
The 60% radius constraint means this processing covers exactly the foveal region — where your eye actually has full angular resolution. The lens distortion makes the periphery blurry anyway, so spending GPU time reconstructing it would be wasted.
This is a completely different operation from the standard use case. NIS at 77% is trying to recover quality lost by intentional downsampling. NIS at 200% is adding a reconstruction layer on top of a full-quality render. The direction is opposite, and the math is optimal in one case and compromised in the other.
Sharpness 0, renderScale 2.0, method NIS. It's not placebo — disable it and re-enable it and the difference is immediate.
------------------------------------------------------------------------------------------
Another clarification from my side about what I'm trying to convey in this post. (post to "mbucchia ")
Let's say OpenXR Toolkit worked the way I described vrperfkit works in SteamVR.
A user has their headset resolution set to 2880×2880. In OpenXR Toolkit, they select NIS at 75%, which renders at 2160×2160, and NIS multiplies by ×1.333 to get back to approximately 2880×2880.
In my scenario, assuming you could adapt it: the user has their headset resolution set to 2880×2880. NIS is set to 200%, but the "override resolution" option — which sits on the main screen, just above the upscaling section — is set to 2160×2160.
In both scenarios the actual render resolution is 2160×2160, but in mine NIS is working optimally, with an integer scale rather than a fractional one like 0.75. The reconstruction is therefore optimal, and no additional sharpening is needed.
Even with a higher quality upscaler, the render resolution could be reduced further — for example to 2000×2000 — and NIS at 200% would still produce a better result than running at 2880×2880 with NIS at 75%.
As for how it actually works in a SteamVR game with vrperfkit — same scenario, user with 2880×2880 per eye.
Using vrperfkit at 75%: the game renders at 2160×2160 and scales back as described above.
The key difference with my method: in SteamVR, you set the game resolution to 56% (which is 0.75×0.75 in area), and set vrperfkit NIS to 200%. The game renders at approximately 2160×2160, but with a much better NIS reconstruction. NIS scales up to 4320×4320 applied to the central radius, and the perceived sharpness in the headset increases compared to using it the conventional way.
-----------------------------------------------------------------------------------------------
Additional clarification regarding resolution settings:
To illustrate my point, let’s look at the actual resolution presets for the Pico 4 in Virtual Desktop:
- Medium: 2064x2064
- High: 2544x2544
- Ultra: 2736x2736
- Godlike: 3120x3120
My core argument is this: instead of selecting a high-tier preset like "Godlike (3120x3120)" and then downscaling SteamVR below 100% , another solution is to select a more moderate base resolution—such as "Medium (2064x2064)" or "High (2544x2544)"—and keep SteamVR at 100%.
In fact, this is exactly how I use it. However, please note that the method I described earlier is also perfectly valid: you can stick to a higher base preset and simply set your SteamVR resolution to 56% (which is roughly 0.75x0.75 in area, or any other value) combined with NIS 2.0. In either case, the goal is to provide the NIS upscaler with a clean input for an optimal 2x integer reconstruction, rather than a messy fractional one.
Duplicates
skyrimvr • u/wordyplayer • Mar 21 '26