AgiqRenderBudget 1.0.1

dotnet add package AgiqRenderBudget --version 1.0.1
                    
NuGet\Install-Package AgiqRenderBudget -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AgiqRenderBudget" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AgiqRenderBudget" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="AgiqRenderBudget" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add AgiqRenderBudget --version 1.0.1
                    
#r "nuget: AgiqRenderBudget, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package AgiqRenderBudget@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=AgiqRenderBudget&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=AgiqRenderBudget&version=1.0.1
                    
Install as a Cake Tool

AgiqRenderBudget

Smart real-time rendering budget allocation for games:stable FPS + better visuals where it matters.

Key idea: instead of local heuristics (distance-only LOD),allocate frame budget globally across thousands of objects using a fast budget optimizer with:

importance-aware scoring (gameplay > background)

group budgets (shadows / VFX / enemies / UI,etc.)

smoothing & hysteresis (no flicker / no level thrashing)

zero allocations per frame (after warm-up)

This library is a practical “global optimization” brick designed for per-frame or every-N-frames use.


The Problem

Every game hits the same wall:

You have 16.67 ms per frame (60 FPS)

You have 10,000+ renderables

You have limited budgets:polygons,shading,textures,shadows,post FX…

Question: How do you spend the budget so the player sees the most important content at the highest quality?

Typical solutions:

Distance-based LOD (ignores gameplay importance)

Global quality presets (all-or-nothing)

Manual tuning (doesn’t scale)

Static rules (break on dynamic camera/gameplay)

Result:unstable FPS,visual “mush”,and endless performance firefighting.


What AgiqRenderBudget Does

AgiqRenderBudget selects a quality level for each object (LOD / shadow quality / texture mip / shader variant) under:

a global time budget (ms)

optional group budgets (e.g. shadows ⇐ 0.45ms)

per-item constraints (min level,pinned level)

smoothing across frames (penalty for changing levels + hold frames)

It runs fast enough to be used frequently (per-frame or every few frames) without GC spikes.


Benchmarks

CPU: Intel Core i5-11400F

Runtime: .NET 8,BenchmarkDotNet (InProcess)

Allocator: 0 B per call (after warm-up)

| Objects | Time (Mean) | Allocations |

|--------:|------------:|------------:|

| 1,000 | ~6.37 µs | 0 B |

| 5,000 | ~31.87 µs | 0 B |

| 10,000 | ~83.62 µs | 0 B |

10,000 objects in ~0.083 ms is roughly 0.5% of a 60 FPS frame.


Install

NuGet


dotnet add package AgiqRenderBudget


Quick Start

1) Create optimizer + state (once)


using AgiqRenderBudget;



var optimizer = new AgiqRenderBudgetOptimizer(seed:123);

var state = new RenderBudgetState();

2) Build items + prepare context (on scene load / when options change)


var items = new List<RenderItem>();



foreach (var obj in scene.Objects)

{

&nbsp;items.Add(new RenderItem

&nbsp;{

&nbsp;Id = obj.Id,

&nbsp;Importance = obj.Importance,// your metric:gameplay,distance,screen size,visibility...

&nbsp;GroupId = obj.GroupId,// e.g. 1=Shadows,2=VFX,3=Enemies

&nbsp;MinLevel = obj.MinLevel,// never go below

&nbsp;PinnedLevel = obj.IsBoss ? 3 :-1,// boss always high

&nbsp;Options = new\[]

&nbsp;{

&nbsp;new QualityOption(0.005f,0.20f),

&nbsp;new QualityOption(0.012f,0.45f),

&nbsp;new QualityOption(0.025f,0.75f),

&nbsp;new QualityOption(0.045f,1.00f),

&nbsp;}

&nbsp;});

}



var groups = new\[]

{

&nbsp;new GroupBudget(1,0.45f),// shadows budget (ms)

&nbsp;new GroupBudget(2,0.35f),// vfx budget

&nbsp;new GroupBudget(3,0.55f),// enemies budget

};



var ctx = optimizer.Prepare(items,groups);

3) Optimize each frame (or every N frames)


var settings = PlatformProfile.PC60.ToSettings(

&nbsp;seed:123,

&nbsp;improveCap:2500,

&nbsp;randomMoves:2

);



var allocation = optimizer.OptimizeFrame(ctx,settings,state);



for (int i = 0; i < allocation.Levels.Length; i++)

{

&nbsp;scene.Objects\[i].SetQualityLevel(allocation.Levels\[i]);

}


API Overview

RenderItem

Importance:how valuable quality is for this item (gameplay first)

Options[]:discrete quality options (cost,quality)

GroupId:optional group id for group budgets

MinLevel:hard minimum level

PinnedLevel:fixed level (e.g. boss/UI)

PlatformProfile

Presets:

PlatformProfile.PC60

PlatformProfile.Console60

PlatformProfile.Mobile60

BudgetSettings

BudgetMs:total global budget

TimeLimitMs:optional CPU time budget for improvement loop

ImproveIterationsCap:improvement iterations

ChangePenalty,MaxStepPerFrame,MinHoldFrames:smoothing


Licensing & Pricing (Commercial)

This is commercial software.

Individual (1 developer):$100 / year

Studio / Large developer:$500 / year

Contact:vipvodu@yandex.u

See LICENSE.txt for terms.


FAQ

Q:Is this “optimal”?

A:It’s a fast global budget optimizer designed for real-time use. It aims for high-quality allocations under hard budgets and constraints,and typically outperforms simple local heuristics.

Q:Does it allocate memory each frame?

A:No. After warm-up,per-frame calls are designed to be zero-allocation.


Support

Email:vipvodu@yandex.ru

Telegram: @vivpodu

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 121 3/3/2026
1.0.0 110 3/3/2026