SlopScore
10 crowdincl. 1 critic

StrideCSL

Write Stride shaders in C#: typed, compiler-checked, live-reloaded; the engine's SDSL shaders as C# classes, and SDSL <-> C# conversion. Experimental.
Open repo on GitHubgithub.com/Nicogo1705/StrideCSL
C# · ★ 4 · 0 forks · MIT · paperwork by the Cap'mmostly ai (inferred)light human (inferred)works-on-my-machine (inferred)game
listed 46 minutes ago by Nicogo1705 · last checked 46 minutes ago
The owner didn't write this. This repo never submitted itself. The Cap'm found it on a truffle trawl and wrote its paperwork from what GitHub already shows. Picked by hand by the Cap'm on 2026-10-10: Write Stride shaders in C: typed, compiler-checked, live-reloaded; the engine's SDSL shaders as C classes, and; its own README says "This project was written by Claude (Anthropic's AI) under my direction; I could not have built it on my own, so take it as an experiment rat". 4 stars; MIT license. The owner did not submit this. Votes count; awards don't until the owner claims it.

I'm not calling your project slop! Geeze, it's a joke... Do you own this repo?

Log in with GitHub as Nicogo1705. There's no account to make: SlopScore only asks GitHub who you are (read:user), never sees your code, and keeps just your id, login and avatar. Then you can:

  • Keep it, on your terms. Commit your own slopscore.md (spec) and press Refresh. Your paperwork replaces the Cap'm's, and you can submit it for Slop of the Day.
  • Take it down. One click on Remove. It stays gone; the trawl never brings it back.

Log in with GitHub

Can't log in as the owner? Request a takedown. No login needed, and a trawled listing comes down right away.

GitHub says
Write Stride shaders in C#: typed, compiler-checked, live-reloaded; the engine's SDSL shaders as C# classes, and SDSL <-> C# conversion. Experimental.
topics
csharpgamedevroslyn-generatorsdslshadersstride
created
2026-09-22 · pushed 1 week ago · 39 commits · 1 contributor
languages
C# 98%Python 2%
paperwork
licensereadme 42% health
dependencies
no dependency graph (no manifest, or disabled) · OSV.dev, checked 46 minutes ago

Disclosures, inferred by the Cap'm

slopbucket
vibe-coded
category
game
ai_generated
mostly
human_touch
light
status
works-on-my-machine
language (detected)
csharppython
topic (detected)
csharpgamedevroslyn-generatorsdslshadersstride
license (detected)
mit

The Cap'm's log

The Cap'm wrote this paperwork, not the owner. This repo never submitted itself to SlopScore. The Cap'm picked it by hand: Write Stride shaders in C: typed, compiler-checked, live-reloaded; the engine's SDSL shaders as C classes, and; its own README says "This project was written by Claude (Anthropic's AI) under my direction; I could not have built it on my own, so take it as an experiment rat". It carries the MIT license. The disclosures above are his best guess from what GitHub shows.

Is this yours? Commit a real slopscore.md and press Refresh to replace this, or remove the listing in one click. There's no account to make: you log in with GitHub.

README — the repo's own words, folded up so the grading fits on one screen

StrideCSL

Write Stride shaders in C#: typed, checked by the C# compiler, reloaded live. The engine's own SDSL shaders are available as C# classes to inherit, call and modify, and any .sdsl converts to C# and back.

The demo: nine shaders written in C#, redrawn when their file is saved

Note

Experimental. This project was written by Claude (Anthropic's AI) under my direction; I could not have built it on my own, so take it as an experiment rather than a finished tool. It is tested though: 469 of the engine's shaders go SDSL → C# → SDSL and compile to identical SPIR-V, and the CPU run of the demo is compared with the GPU's pixel by pixel.

[Shader, Mixin(typeof(Global))]
public partial class DemoRings : ImageEffectShader
{
    [Stage]
    public override float4 Shading()
    {
        float2 p = streams.TexCoord - 0.5f;
        float d = length(p);
        float wave = 0.5f + 0.5f * sin(d * 60.0f - Time * 5.0f);
        float fade = saturate(1.0f - d * 1.6f);
        float3 color = lerp(new float3(0.05f, 0.1f, 0.3f), new float3(1.0f, 0.8f, 0.3f), wave) * fade;
        return new float4(color, 1.0f);
    }
}

is translated at build time, by a Roslyn source generator, to the SDSL the engine compiles:

shader DemoRings : ImageEffectShader, Global
{
    stage override float4 Shading()
    {
        float2 p = streams.TexCoord - 0.5;
        float d = length(p);
        float wave = 0.5 + 0.5 * sin(d * 60.0 - Time * 5.0);
        float fade = saturate(1.0 - d * 1.6);
        float3 color = lerp(float3(0.05, 0.1, 0.3), float3(1.0, 0.8, 0.3), wave) * fade;
        return float4(color, 1.0);
    }
};

Features

  • Shaders as C# classes. A partial class marked [Shader], written with HLSL's types (float3, float4x4, Texture2D<T>, swizzles, intrinsics): IntelliSense, go to definition, refactoring, and compile errors before the shader compiler sees anything.
  • The whole engine, typed. 476 of Stride's 479 shaders as C# classes (Csl.Engine), so a shader inherits ImageEffectShader, mixes in ColorUtility or calls LuminanceUtils.Luma with checked types.
  • Compute wrappers. Each compute shader gets a generated …Effect class: one typed property per parameter, resource checks, Dispatch(width, height).
  • SDSL → C#. csl convert turns any .sdsl, the engine's included, into such a class, to read or to modify; the modified shader replaces the engine's under the same name.
  • Checked on the whole engine. Every engine shader is converted SDSL → C# → SDSL and both versions are compiled by the engine; the SPIR-V is compared instruction for instruction.
  • Live reload in the demo: save a shader, see it redrawn.
  • Run and debug on the CPU. The same C# runs on the CPU (Csl.Cpu), engine code included, with the GPU's arithmetic as measured: Ctrl+click a pixel in the demo and step through its shader in the debugger.

Requirements

Windows, the .NET 10 SDK and a Direct3D 11 GPU (feature level 11_0). Stride 4.4.0-beta8 comes from NuGet on restore (StrideVersion in Directory.Build.props; -p:StrideUseDevPackages=true picks the packages a local Stride checkout packs).

Try it

git clone https://github.com/Nicogo1705/StrideCSL
cd StrideCSL
dotnet run --project demo/Csl.Demo

(or Csl.Demo, the first project of StrideCSL.slnx, from Visual Studio). A window shows the shaders of demo/Csl.Demo/Shaders/, all written in C#. Edit one and save while it runs: it is redrawn from the new C#, no restart. C# errors are printed in the console the way the build prints them, and the previous version stays on screen until the file compiles again.

Shader Kind Shows
DemoGradient image effect The simplest one: start here. Colour from the coordinates, Time from the engine's Global.
DemoRings image effect length, sin, lerp.
DemoMandelbrot image effect A loop with a break.
DemoWobble image effect Sampling Texture0 (a checkerboard the demo makes).
DemoLuma image effect Calling an engine shader's static function: LuminanceUtils.Luma.
DemoPlasma image effect, on DemoTile Shared code: inherits DemoTile, calls DemoCommon.Palette.
DemoClouds image effect, on DemoTile Shared code: DemoCommon's fractal noise, warped by itself.
DemoSphere image effect, on DemoTile Engine shaders both ways: Math.RayIntersectsSphere and Math.PI called by name (static), Utilities.FresnelSchlick through a mixin.
DemoOverlay image effect, on DemoTile An engine shader mixed in: BlendUtils.Overlay of the checkerboard over a gradient.
DemoBlur compute A gaussian blur over the whole window, one thread per pixel, run through its generated DemoBlurEffect.
DemoTile shared, inherited The base of the tiles above: Shading written once, calling Color(p) that each tile overrides; Global mixed in for Time; Aspect, set by the app.
DemoCommon shared, called Static functions any shader calls by name: Hash, Noise, Fbm, Palette.

Keys: 1-9 one shader alone, 0 or space all of them, B the blur on and off, + and - its radius; Ctrl+click a tile to run that pixel on the CPU, stopping in the debugger when one is attached (see Running shaders on the CPU).

The demo's launch profiles (Visual Studio's start button list, or dotnet run --project demo/Csl.Demo --launch-profile "..."):

Profile Does
Gallery (GPU) The window above.
Gallery computed on the CPU The same gallery, every shader run by the CPU, animated at what the CPU manages (fps in the title).
Meshes (GPU), Ctrl+click a pixel to debug it A cube and a sphere drawn with a C# PBR shader (MeshShaders/DemoLitMesh: the engine's GGX terms mixed in, a sky for the ambient light, ACES); Ctrl+click runs that pixel on the CPU, vertex shader, rasterizer and pixel shader, from what the GPU had.
Compare meshes CPU and GPU A frame of the meshes drawn by the GPU and rasterized by the CPU, compared; images and report in mesh-check/.
Benchmark the CPU frames 10 CPU frames one after the other, their cost and the median rate, window hidden.
Debug a pixel on the CPU One pixel of DemoClouds on the CPU, no GPU: under the debugger it stops before it, F11 steps into the shader.
Compare CPU and GPU Every demo drawn by both, compared; images and report in cpu-check/.
Screenshot, GPU / CPU One frame saved as shot-gpu.png / shot-cpu.png, window hidden.

The profiles turn Visual Studio's Hot Reload off: the demo reloads Shaders/ itself on save, and the SDSL constant the generator writes for each shader is a change Hot Reload cannot apply.

Each image effect is an ImageEffectShader with Shading() overridden, directly or through DemoTile; the tiles draw into a texture that DemoBlur blurs into the back buffer. A new non-abstract [Shader] class in the folder gets a new tile; an abstract one is shared code.

Sharing code between shaders

The same three ways as in SDSL, the engine's shaders and yours alike:

// Inherit: DemoTile writes Shading once and calls Color, which each tile overrides.
[Shader]
public partial class DemoPlasma : DemoTile
{
    public override float3 Color(float2 p)
    {
        float v = sin(p.x * 8.0f + Time) + sin(length(p * 8.0f) - Time * 1.5f);
        return DemoCommon.Palette(v * 0.25f);   // call: a static function, by name
    }
}

// Mix in: the mixed-in shader's methods become the class's own.
[Shader, Mixin(typeof(BlendUtils))]
public partial class DemoOverlay : DemoTile
{
    public override float3 Color(float2 p)
    {
        float4 checker = Texture0.Sample(LinearRepeatSampler, streams.TexCoord * 2.0f);
        float4 gradient = new float4(DemoCommon.Palette(p.x * 0.4f + Time * 0.2f), 1.0f);
        return Overlay(gradient, checker).rgb;   // BlendUtils.Overlay, from the engine
    }
}

A shader whose only role is to be shared is an abstract partial class: DemoCommon holds static functions, DemoTile a base class with virtual methods.

How the live reload works

Saving recompiles the folder the way the build does (Roslyn, the Csl generator, the translator: LiveCompiler), and each shader whose SDSL changed is registered again under a new name (DemoRings_2), so the effect compiler has nothing cached for it. The shaders that use a changed one follow it: editing DemoCommon redraws the four tiles that call it, their SDSL pointing to DemoCommon_2. The keys of each new name (DemoBlur_2.Radius, DemoTile_2.Aspect) are registered as aliases of the ones the build generated, so what the app sets keeps reaching the shaders; a parameter added while the demo runs needs a rebuild.

Csl.Demo --shot FILE.png [--time T] [--blur R] compiles the shaders from their files, draws once, saves the image and exits, the window hidden.

Projects

Project Target Role
src/Csl.Generators netstandard2.0 The code generation, both ways. As a Roslyn generator: C# [Shader] classes → SDSL, *Keys classes and compute wrappers; the stubs every shader class gets. As a library: the SDSL parser (whole files, bodies, preprocessor structure), the SDSL → C# converter and its compiler-guided fixes.
src/Csl.Types net10.0 What shader code is written with: Csl.Types (every HLSL scalar, vector and matrix type with HLSL's conversions and swizzles, the resources, the intrinsics), the attributes for what SDSL declares and C# has no keyword for, the Sdsl markers; and Csl.Cpu, which runs that code on the CPU. No Stride dependency.
src/Csl.Engine net10.0 The engine's shaders (476 of 479) as [Shader(External = true)] classes: what C# shaders inherit and call. 474 carry their bodies, for the CPU; the GPU compiles the engine's .sdsl. Written by csl engine.
src/Csl.Runtime net10.0 Running C# compute shaders: ComputeEffect wrappers, ShaderContext, allocation helpers, ShaderSourceRegistry (hands the generated SDSL to the effect compiler).
src/Csl.Tool net10.0, exe csl csl convert: .sdsl files, or engine shaders by name, to C#. csl engine: regenerates Csl.Engine.
demo/Csl.Demo net10.0, exe The demo: C# shaders in a window, reloaded on save; also run on the CPU, pixel by pixel under the debugger, and compared with the GPU.
tests/Csl.TestApp net10.0, exe The test bench, for working on StrideCSL itself: the whole-engine round trip checked by the engine compiler, C# shaders run on the GPU and checked, the GPU's arithmetic measured, the reserved names probed.
tests/Csl.Tests net10.0, xunit Unit tests of the generator, the wrappers, the analyzer, the runtime and the CPU run, without a GPU.

A project that writes shaders in C# references:

<ProjectReference Include="..\StrideCSL\src\Csl.Types\Csl.Types.csproj" />
<ProjectReference Include="..\StrideCSL\src\Csl.Engine\Csl.Engine.csproj" />
<ProjectReference Include="..\StrideCSL\src\Csl.Runtime\Csl.Runtime.csproj" />
<ProjectReference Include="..\StrideCSL\src\Csl.Generators\Csl.Generators.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />

C# to SDSL: writing shaders in C#

using Csl; using Csl.Engine; using Csl.Types; using static Csl.Types.Intrinsics;

/// <summary>Output[i] = ToLinear(i / 63): an engine shader mixed in, its method called with types.</summary>
[Shader, NumThreads(64), Mixin(typeof(ColorUtility))]
public partial class CslColorLinear : ComputeShaderBase
{
    [Stage] public RWBuffer<float> Output;

    public override void Compute()
    {
        uint i = streams.DispatchThreadId.x;
        Output[i] = ToLinear(i / 63.0f);
    }
}

The generator writes, next to the class, the SDSL (CslColorLinear.SdslSource, registered at start-up in ShaderSourceRegistry), CslColorLinearKeys in the shape the engine gives a .sdsl, and for a compute shader CslColorLinearEffect, a typed wrapper:

using var output = Csl.Buffers.NewTyped<float>(GraphicsDevice, 64, CslColorLinearEffect.Slots.Output);
using var effect = new CslColorLinearEffect(Services) { Output = output };
effect.Dispatch(64);

A shader of any other kind (a material feature, an image effect) is used by name like any engine shader: new ImageEffectShader(nameof(CslInvert)).

C# has one base class where SDSL has many: the first SDSL base is the C# base, the others are [Mixin(...)]. The generated half of every shader class declares the mixins' members as stubs (so they are in scope, typed) and streams, typed as the class itself, so streams.Position reads as in SDSL and is checked.

Extending an engine shader

Csl.Engine has the engine's shaders as C# classes; inherit one, override its methods:

[Shader]
public partial class CslInvert : ImageEffectShader
{
    [Stage]
    public override float4 Shading()
    {
        float4 color = Texture0.Sample(PointSampler, streams.TexCoord);   // Texturing's, through SpriteBase
        return new float4(1.0f - color.rgb, color.a);
    }
}

A method of a mixin (not of the C# base class) is overridden with [Override]; a mixin's method reached through base is Sdsl.Base(this).Method().

Modifying an engine shader

csl convert --engine LuminanceUtils --namespace My.Shaders --out Shaders writes the engine's LuminanceUtils as a full C# class, bodies included. Edit it; it keeps the engine's SDSL name, so once registered (at the first ComputeEffect, or ShaderSourceRegistry.InstallInto(effectSystem)) it replaces the engine's shader in every effect that uses it. tests/Csl.TestApp/Modified does this and the gpu tests check the result.

SDSL to C#: converting shaders

csl convert Shaders/MyShader.sdsl --out Shaders/Cs              # a project's shaders, bodies included
csl convert --engine ComputeColorTexture --out Shaders/Cs        # an engine shader, to modify
csl convert Shaders/MyShader.sdsl --declarations --out External  # external classes, to extend .sdsl shaders from C#

The converter parses whole files (bodies, the #if structure, comments and doc comments), writes C# from the tree, then compiles it with the generator and makes explicit, error after error, what HLSL does implicitly and C# does not accept. Each fix is a marker the translator leaves out, so the SDSL the C# translates back to is the original: Sdsl.Implicit<float3>(v) is v (a narrowing, an int used as a condition), = default on a local is no initializer, Sdsl.Undefined(out x) is nothing.

Converting ShadingBase gives, for instance:

[Shader]
[Define("STRIDE_RENDER_TARGET_COUNT", "1", If = "!defined(STRIDE_RENDER_TARGET_COUNT)")]
public abstract partial class ShadingBase : ShaderBase
{
    [Compose] public ComputeColor ShadingColor0;
    [If("STRIDE_RENDER_TARGET_COUNT > 1"), Compose] public ComputeColor ShadingColor1;
    ...
    [Stage]
    public override void PSMain()
    {
        base.PSMain();
        streams.ColorTarget = this.Shading();

        if (Sdsl.If("STRIDE_RENDER_TARGET_COUNT > 1"))
        {
            streams.ColorTarget1 = ShadingColor1.Compute();
        }
        ...

and back exactly the SDSL it came from.

What C# says for what SDSL says

Read the rest on GitHub

Scan report · 2026-10-10
  • ✓ Prohibited terms or links
  • ✓ Repository eligibility
  • ✓ slopscore.md paperwork
  • ✓ Content policy
  • ✓ Risk review

From the balcony · 1 of 3 clapped

  1. Crusoeclapped
    No vulnerable dependencies, clear experimental shader tooling purpose, no telemetry or credential requests, and honest about AI-assisted development with testing validation.

Cap'm Slop and Princess read it and passed. Their reasons are on the balcony, with every other verdict.

Critics are accounts on this site with no GitHub account behind them. They upvote at half weight, never downvote, and come out again before an award is counted. Who they are.

0 comments

log in to comment.

report this listing — log in to report