NeutrinoParticles.V1_2.MonoGame.Bloom.DX
1.0.6
dotnet add package NeutrinoParticles.V1_2.MonoGame.Bloom.DX --version 1.0.6
NuGet\Install-Package NeutrinoParticles.V1_2.MonoGame.Bloom.DX -Version 1.0.6
<PackageReference Include="NeutrinoParticles.V1_2.MonoGame.Bloom.DX" Version="1.0.6" />
<PackageVersion Include="NeutrinoParticles.V1_2.MonoGame.Bloom.DX" Version="1.0.6" />
<PackageReference Include="NeutrinoParticles.V1_2.MonoGame.Bloom.DX" />
paket add NeutrinoParticles.V1_2.MonoGame.Bloom.DX --version 1.0.6
#r "nuget: NeutrinoParticles.V1_2.MonoGame.Bloom.DX, 1.0.6"
#:package NeutrinoParticles.V1_2.MonoGame.Bloom.DX@1.0.6
#addin nuget:?package=NeutrinoParticles.V1_2.MonoGame.Bloom.DX&version=1.0.6
#tool nuget:?package=NeutrinoParticles.V1_2.MonoGame.Bloom.DX&version=1.0.6
NeutrinoParticles bloom add-on for MonoGame
HDR-glow bloom post-process for the NeutrinoParticles
CS 1.2 MonoGame runtime (NeutrinoParticles.V1_2.MonoGame, C# export format v1.2).
Particles whose colour exceeds 1.0 glow with true HDR energy — the exact algorithm the editor
preview shows: only content above luminance 1.0 glows, the scene ≤ 1 is preserved untouched,
and the hottest cores desaturate to white while the surrounding glow keeps its hue.
Installation
Pick the package that matches your MonoGame backend:
DirectX (Windows/Xbox desktop):
dotnet add package NeutrinoParticles.V1_2.MonoGame.Bloom.DX
OpenGL (cross-platform):
dotnet add package NeutrinoParticles.V1_2.MonoGame.Bloom.GL
Match the bloom backend to the runtime backend your project already uses
(NeutrinoParticles.V1_2.MonoGame.DX / .GL). Both expose the same MonoGameBloom API —
your game code is identical either way.
Requirements
GraphicsProfile.HiDef (the runtime already requires it). Bloom renders into an HDR
(RGBA16F, SurfaceFormat.HalfVector4) render target, so a renderable float colour buffer
must be available; the add-on probes for it and throws a clear message if the device/driver
lacks it.
Export Target in Editor
Set the export target to C# v1.2 (same as the base runtime). Bloom only affects rendering. For particles to glow, the effect must produce colour above 1.0 (HDR colour in the editor); colour ≤ 1 is preserved untouched.
Quick Start
Render your effect into the add-on's HDR scene target, then let bloom compose scene + glow into the backbuffer. The renderer knows nothing about bloom — it is entirely host-side.
using Microsoft.Xna.Framework;
using NeutrinoParticles.MonoGame.Bloom;
public class Game1 : Game
{
private NeutrinoParticles.MonoGame.Context neutrinoContext_;
private NeutrinoParticles.MonoGame.ParticleEffect effect_;
private RenderTarget2D sceneRt_;
private MonoGameBloom bloom_;
protected override void LoadContent()
{
neutrinoContext_ = new NeutrinoParticles.MonoGame.Context(
GraphicsDevice, texturesBasePath: "particles/", generateNoise: true);
var effectModel = new NeutrinoParticles.MonoGame.ParticleEffectModel(
neutrinoContext_, new NeutrinoParticles.Effect_MyCoolEffect(), Content);
effect_ = new NeutrinoParticles.MonoGame.ParticleEffect(
effectModel, position: new Vector3(400, 300, 0));
sceneRt_ = MonoGameBloom.CreateSceneTarget(GraphicsDevice,
GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height);
bloom_ = new MonoGameBloom(GraphicsDevice, new BloomOptions());
}
protected override void Update(GameTime gameTime) => effect_.Update(gameTime);
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.SetRenderTarget(sceneRt_); // render the effect into the HDR target
GraphicsDevice.Clear(Color.Black);
effect_.Draw();
bloom_.ProcessBloom(sceneRt_); // build the bloom pyramid
bloom_.RenderResult(sceneRt_, null); // scene + glow -> backbuffer (null)
}
protected override void UnloadContent()
{
bloom_?.Dispose();
sceneRt_?.Dispose();
neutrinoContext_?.Shutdown();
}
}
Turn bloom off by drawing effect_.Draw() straight to the backbuffer (no sceneRt_,
no bloom calls).
Options
BloomOptions accepts:
new BloomOptions {
Intensity = 1.0f, // additive glow strength (default 1.0, editor value)
Iterations = 3, // blur-pyramid depth: how far the glow spreads (1..6)
};
Intensity— additive glow strength applied over the scene before the present curve.Iterations— blur-pyramid depth, i.e. how far the glow spreads. Default 3, range 1..6 (clamped).
The glow threshold is fixed at luminance 1.0 (scene ≤ 1 preserved) and the white-core present tuning is baked into the shader to match the editor exactly.
Iterations — how far the glow spreads
The glow's radius is set by the depth of the blur pyramid, not by how bright the
content is: the blur kernels' offsets scale with each pyramid level's size, and the
present normalizes by the max channel, so a brighter core saturates (denser, whiter)
rather than spreading wider. Raise Iterations for a wide, soft halo; lower it for a
tight glow. Each extra iteration roughly doubles the reach.
This mirrors the editor's Bloom iterations preview setting (Project Settings → Preview, NeutrinoParticles engine), so a value you tune in the editor transfers here unchanged. The default 3 is what the runtime used before the option existed.
Unlike Intensity (a shader uniform), this sizes the render targets, so it is applied
at Resize. Cost scales with depth, but cheaply — each level is a quarter of the
previous one's pixels. On a small back buffer the depth is capped to what fits: levels
below 4 px are not built, since a 1 px level is a single averaged colour smeared over
the frame.
API
| Member | Description |
|---|---|
MonoGameBloom.CreateSceneTarget(device, width, height) |
Create the HDR (HalfVector4) RenderTarget2D to render the effect into. |
new MonoGameBloom(device, options) |
Create the bloom. Requires GraphicsProfile.HiDef; throws if float targets are unsupported. |
ProcessBloom(sceneTexture) |
Build the bloom pyramid from the scene target. |
RenderResult(sceneTexture, dest) |
Composite scene + bloom into dest (null = backbuffer). |
Dispose() |
Release the pyramid, composite, quad, and effect. |
The per-frame path is pure GPU→GPU (no CPU readback) and allocation-free after the first frame (the pyramid + composite are cached and reallocated only when the scene size changes).
Algorithm
Soft-knee prefilter (only luminance > 1 glows) → 4-tap downsample down a 4-level pyramid →
dual-Kawase 8-tap upsample → composite scene + additive bloom into a full-res HDR target →
hue-preserving + white-core present. A MonoGame port of the editor's BloomNeutrino, one
bloom.fx source compiled for both DX (SM4) and GL (SM3) backends.
Common Issues
- Crash on
MonoGameBloom/CreateSceneTarget(HiDef required): setGraphicsDeviceManager.GraphicsProfile = GraphicsProfile.HiDefbeforeApplyChanges(). renderable RGBA16F ... not supported: the device/driver lacks renderable float targets; disable bloom on that hardware.- No glow: the effect's colour never exceeds 1.0, or you rendered the effect straight to
the backbuffer instead of into
sceneRt_. Bloom is scene-preserving — only HDR colour > 1 glows. - Upside-down / mirrored glow:
RenderResultcomposites the glow right-side-up over the scene on both backends automatically. If the glow appears vertically flipped, you fed it a hand-made scene target instead of the one fromCreateSceneTarget— render the effect into that target, then pass the same target toProcessBloom/RenderResult.
Documentation
Full documentation at neutrinoparticles.com.
License
Copyright (c) Yurii Miroshnyk. All rights reserved.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. 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. net8.0-windows7.0 is compatible. 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. |
| .NET Core | netcoreapp3.1 is compatible. |
| .NET Framework | net452 is compatible. net46 was computed. net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
-
.NETCoreApp 3.1
- MonoGame.Framework.WindowsDX (>= 3.8.0.1641)
-
.NETFramework 4.5.2
- MonoGame.Framework.WindowsDX (>= 3.8.0.1641)
-
net8.0-windows7.0
- MonoGame.Framework.WindowsDX (>= 3.8.0.1641)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.