Installation

Prerequisites

  • .NET 8 SDK (≥ 8.0.100) or the .NET 10 SDK — the libraries ship both a net8.0 and a net10.0 assembly, so a project on either framework can reference them.

That's it. Everything else, including the native compiler pieces, comes from NuGet automatically when you dotnet restore. There is no separate native install.

The library (the product)

Add the ShadowDusk.Compiler package to your project:

dotnet add package ShadowDusk.Compiler

Then call it from code — see the In-Memory Quickstart:

var compiler = new ShadowDusk.Compiler.EffectCompiler();
var result = await compiler.CompileAsync(hlslSource,
    new ShadowDusk.Core.CompilerOptions { Target = ShadowDusk.Core.PlatformTarget.OpenGL });

The CLI tool (ShadowDuskCLI)

Install the drop-in mgfxc replacement as a global tool:

dotnet tool install --global ShadowDusk.Cli

This provides a ShadowDuskCLI command with the same flags and .mgfx output as MonoGame's tool. See the CLI Reference and the Drop-in mgfxc guide.

Default-target caveat: the CLI's default /Profile is DirectX_11, while the library's Target default is OpenGL. Always pass the target you want explicitly. This is called out again on the Quickstart and CLI Reference pages.

The content pipeline packages

For a .mgcb file (MGCB), add ShadowDusk.MgcbPlugin and /reference: it — see MGCB Content Pipeline. For MonoGame 3.8.5's code-centric Content Builder project, add ShadowDusk.ContentPipeline to the Builder project and pass new ShadowDuskEffectImporter(), new ShadowDuskEffectProcessor() — see MonoGame 3.8.5 Content Builder. Both compile the same importer/processor; only the packaging differs (the plugin is tools-only and cannot be referenced from C#).

The in-browser (WASM) library

For in-browser runtime compilation (KNI / Blazor WebAssembly), add the ShadowDusk.Wasm package. It self-registers as Blazor static web assets — see In-Browser (KNI/Blazor WASM).

Optional ShaderToy and GLSL front-end

ShadowDusk.ShaderToy is a standalone, pure-managed (zero-native) converter that turns a ShaderToy (mainImage) or plain-GLSL fragment shader into a self-contained HLSL .fx source. It is optional — it is not part of the faithful mgfxc-replacement pipeline, and ShadowDusk.Compiler does not depend on it. Install it when you want to convert ShaderToy/GLSL shaders in-process (a shader fiddle, an in-app importer):

dotnet add package ShadowDusk.ShaderToy
var converted = ShadowDusk.ShaderToy.ShaderToyConverter.Convert(glslSource);
// converted.Fx is .fx source — compile it with EffectCompiler.CompileAsync(...)

Unsupported constructs fail loudly with a located (line/column) diagnostic rather than producing a silently-wrong .fx. The CLI has this front-end built in: ShadowDuskCLI auto-detects .glsl/.frag/.fs input and converts it before compiling — see the CLI Reference.

Slang input — the free subset, and the optional full language

ShadowDusk accepts .slang source in two tiers. The free default, built into ShadowDusk.Compiler (no extra package, no native toolchain, works on every host including the browser), accepts the HLSL-compatible subset of Slang: entry points via [shader("vertex")]/[shader("fragment")], a synthesized technique, and a body compiled by the same faithful pipeline as any .fx. Slang-only features (import, generics, interfaces) are rejected with a named SD0600 rather than approximated — see the CLI Reference for --input-format.

For genuine Slang — import, generics, interface conformances, everything real Slang accepts — install the optional ShadowDusk.Slang package. It bundles the real slangc compiler (win-x64 today) and routes its HLSL emission to the same unchanged, faithful DXC pipeline:

dotnet add package ShadowDusk.Slang
var compiler = new ShadowDusk.Slang.SlangCompiler();
var result = compiler.Compile(slangSource, new CompilerOptions { Target = PlatformTarget.OpenGL });
// result.Value.Data is .mgfx bytes, same as EffectCompiler.CompileAsync's output

A consumer who only needs the free subset above pays zero extra size or dependency for this package. Same rejection discipline either way: a construct real slangc accepts but that has nowhere to land in an Effect (a compute entry point, an SM6-only wave/quad intrinsic on a target that can't represent it) is rejected loudly by name, never silently dropped. Neither tier is ever mgfxc-equivalent — mgfxc cannot read Slang at all.

Targeting FNA

FNA uses the same ShadowDusk.Compiler package — there is nothing FNA-specific to install on ShadowDusk's side:

dotnet add package ShadowDusk.Compiler

Two things differ from the MonoGame/KNI path, both on FNA's side, not ShadowDusk's:

  • FNA is not a NuGet package. Unlike MonoGame and KNI, FNA is consumed as a project reference — a git clone/submodule of FNA-XNA/FNA plus its native fnalibs (SDL3, FNA3D, FAudio) — per FNA's own setup docs. (Community/unofficial FNA NuGet builds exist, but the project reference is FNA's documented, supported path.) You add ShadowDusk.Compiler to that existing FNA project exactly as above.
  • Different output container. For PlatformTarget.Fna, ShadowDusk emits a D3D9 fx_2_0 .fxb (Shader Model ≤ 3), not the .mgfx MonoGame/KNI load. FNA reads it through MojoShader at runtime via new Effect(graphicsDevice, fxbBytes). See Compiling for FNA in the quickstart.

The FNA path is cross-platform and self-contained: it uses the same vkd3d-shader native as the DirectX backend, which ships inside the NuGet package, so there is nothing to restore or install.

DirectX backend & native tools

For DirectX 11, the default backend is the cross-platform vkd3d-shader. Its natives for all four desktop RIDs (win-x64, linux-x64, osx-x64, osx-arm64) ship inside the NuGet package, so DirectX compiles out of the box on Linux, macOS, and Windows, with the same bytes everywhere. On Windows you can opt into Microsoft's d3dcompiler_47 (a system DLL already present, the most fxc-faithful option) via CompilerOptions.DxbcBackend = DxbcBackend.D3DCompiler. See the DirectX DXBC (vkd3d) Path for details. (The restore script is only for building ShadowDusk itself from source.)

Building from source

git clone https://github.com/kaltinril/ShadowDusk.git
cd ShadowDusk
./tools/restore.sh        # Linux / macOS  (.\tools\restore.ps1 on Windows)
dotnet build ShadowDusk.slnx

See Restore Native Tools for what the restore script does.