6
\$\begingroup\$

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?

\$\endgroup\$
8
  • \$\begingroup\$ I'm not 100% confident to post this as an answer as my experience isn't that good, but from what I know that's impossible. C# is meant to be compiled once, and you can distribute the executables to other systems, but 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 learning glsl. \$\endgroup\$ Commented Feb 7, 2020 at 14:04
  • \$\begingroup\$ I never wrote a shader that's why i'm asking \$\endgroup\$
    – grzesiekmq
    Commented Feb 7, 2020 at 14:06
  • 3
    \$\begingroup\$ if you've never written a shader, then the language doesn't matter a lot. Usually the challenge is learning how shaders behave, and not their syntax. Assuming you work with OpenGL, I would advice to learn glsl, but others might know more than me about this subject, and may be able to provide more help :) \$\endgroup\$ Commented Feb 7, 2020 at 14:12
  • 2
    \$\begingroup\$ @grzesiekmq I reworded your question in an attempt to make it less of a "how to get started" question in the hopes that it will get reopened. If you feel my edits changed the nature of the question too much, feel free to rollback / modify my edits. \$\endgroup\$
    – Pikalek
    Commented Feb 7, 2020 at 15:09
  • 2
    \$\begingroup\$ If you want to prototype shaders, perhaps shadertoy or shederific could help. They did it for me. Well, plus some OpenGL tutorials, I guess. \$\endgroup\$
    – Theraot
    Commented Feb 7, 2020 at 15:26

3 Answers 3

11
\$\begingroup\$

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.

\$\endgroup\$
6
  • \$\begingroup\$ I'm thinking about the transpiler from c# \$\endgroup\$
    – grzesiekmq
    Commented Feb 7, 2020 at 14:33
  • 2
    \$\begingroup\$ I think that is a bad plan for the reasons I stated above, but you're welcome to try it. \$\endgroup\$
    – DMGregory
    Commented Feb 7, 2020 at 14:49
  • 5
    \$\begingroup\$ @grzesiekmq I think that after you've written version 0.1 of your transpiler, you will likely notice that you now understand shader programming well enough to write shaders without it and throw it away. So it would be one way to learn shader programming which will eventually succeed. Just not as fast as just learning shader programming directly. \$\endgroup\$
    – Philipp
    Commented Feb 7, 2020 at 15:16
  • 2
    \$\begingroup\$ @grzesiekmq are you thinking about writing a transpiler as Philipp implies? Such transpilers already exist. I would like to point you to: mellinoe/ShaderGen. However, this is limiting you. You won't be able take advantage of all the possibilities of the shader language, nor of C#. I would like to encourage to learn to write shaders. You are going to learn to use something anyway, be it the trasnpiler or the shader language. \$\endgroup\$
    – Theraot
    Commented Feb 7, 2020 at 15:24
  • \$\begingroup\$ I thought one could write a GLSL string in C#, send it to the compiler and linker, then send the resulting machine code to the GPU? I can imagine using non-C#-scripts for shaders. Of course I'm not an expert on shaders here. \$\endgroup\$
    – Bitterblue
    Commented Nov 17, 2021 at 15:23
1
\$\begingroup\$

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).

\$\endgroup\$
-1
\$\begingroup\$

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);

OpenGL example

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.

\$\endgroup\$
7
  • 1
    \$\begingroup\$ The code you've shared shows how to construct an OpenGL-compatible 3-dimensional vector. it does not demonstrate how to code shaders in C#. I strongly recommend, if you do not have an answer to how to code shaders in C#, that you delete this answer. There is no shame in not knowing the solution - if you stick around, I'm sure you'll find other questions that you can answer accurately. \$\endgroup\$
    – DMGregory
    Commented Jul 15, 2021 at 3:32
  • \$\begingroup\$ You cannot code a shader in C#. You have to use GLSL, or whatever directx uses. For OpenGL, you put your code into some memory and have OpenGL compile and link it. Perhaps try to link to the opengl lib directly in C#: [DllImport("opengl32")] public static extern void glVertex3f(float x, float y, float z); OpenGL example You might want to code it all up in a C/C++ lib, and then make the 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. \$\endgroup\$ Commented Jul 15, 2021 at 3:40
  • \$\begingroup\$ My webgl does load up some shaders. \$\endgroup\$ Commented Jul 15, 2021 at 3:50
  • \$\begingroup\$ "You cannot code a shader in C#" is not correct, as demonstrated by the other answer. \$\endgroup\$
    – DMGregory
    Commented Jul 15, 2021 at 10:41
  • \$\begingroup\$ If you can use another tool to convert C# code into GLSL code, then yes, but I would advise just learning GLSL. \$\endgroup\$ Commented Jul 15, 2021 at 17:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .