I'm working on game and game engine and want a way to prototype shaders. I'm not skilled with C++ or GLSL or HLSL or something, but I can code in C#.
My question is: How can I code shaders in C#, without using the other mentioned languages?
This is not wholly impossible. There's a type of compiler called a transpiler that will take source code written in one language and compile it, not to bytecode or machine instructions, but to equivalent source code in another language.
Unity for instance uses this technique to transpile its hlsl-like Shaderlab code to glsl for platforms that don't use DirectX. (As well as a variant on the idea in IL2CPP to transform CIL bytecode to C++)
So, in theory, you could write a C# library with an API equivalent to an hlsl/glsl shader environment, write your shader in C#, and either run it on the CPU to emulate a GPU, or transpile it to equivalent hlsl/glsl to send to a real graphics card.
In the comments below, Theraot has provided a link to a project that does something like this.
But I don't think you gain anything by doing that.
C#, hlsl, and glsl syntax all descend from the same C-like conventions, so your code would look almost identical. You wouldn't really gain any particular ease of use this way.
Some idioms that are easy to express in shader languages, like annotating semantics, swizzling to swap the order of components of a vector, or constructing temporary vectors without new
, can be more cumbersome to express in C# — so your code could even end up a bit more complicated in this form.
Worse, there are a lot of things that would be valid C# that are not valid in a shader, like side effects that mutate global state in the middle of a fragment shader. Shader languages are deliberately constructed to ensure you can't break the rules like this. Your C# version would need good error reporting from your transpiler to catch these errors, because the C# compiler thinks they're OK.
So really, the biggest hurdle in writing shaders is wrapping your head around the massively parallel paradigm they use. Just swapping the language won't make that easier.
So, I'd argue you're much better off just picking up hlsl or glsl — there's very little new syntax to learn, and you won't need a complicated emulation environment. Or, if you want to work your way up slowly, consider using a nodegraph based shader editor to get a feel for the operations in a shader, without writing code at all. Once you understand the data flows, replacing nodes with familiar C-like code should be no big obstacle.
As of 2023, you may look at the ComputeSharp library
It seems to be mostly targeted at computing stuff (as opposed to creating visual effects), i.e. using the GPU to calculate things really really fast and in parallel. But after seeing their demo it seems that you can just use it for anything.
A good point is that they claim to be production ready (i.e. it's not a small, short-lived, unfinished, unmaintained library).
I don't know if C# has an API that can compile and load up a shader, and communicate with it wrt sending it data. I bet it does with DirectX. OpenGL might be a different story in C#. Or, perhaps try to link to the opengl lib directly:
[DllImport("opengl32")] public static extern void glVertex3f(float x, float y, float z);
You might want to code it all up in a C/C++ lib, and then make your C# code call into it. You need to be able to compile and link GLSL code, then be able to communicate with it, at least with uniform variables. I think C# has bindings for DirectX. But, I am not familiar with it.
glsl
and other similar languages are meant to be compiled on the run when you run your game. So not only is it not possible now, but it will most likely never be.glsl
is very close to the C-family, so if you know C#, you wouldn't have much trouble learningglsl
. \$\endgroup\$glsl
, but others might know more than me about this subject, and may be able to provide more help :) \$\endgroup\$