Primer : Shaders

edited in Tutorials
http://notes.underscorediscovery.com/shaders-a-primer/

Created by Sven Bergström who used to work at Luma Arcade and is now living in Canada

Comments

  • Thanks for this! (what happened to the shaders workshop, did I miss it?)

    I have just ONE QUESTION about Shaders right now.

    What language does one write shaders in, and where can I find help/reference/manual/something that I can learn it from? Is it different per platform? Or is it some kind of megalomaniac unified shader language?
  • Nope, you haven't missed it. Our lecturer got incredibly busy and couldn't run the workshop. It's still in the works
  • What language does one write shaders in, and where can I find help/reference/manual/something that I can learn it from? Is it different per platform? Or is it some kind of megalomaniac unified shader language?
    I'm no expert on this, but to my understanding, much like programming can be done in C++, shaders can be written in (or for?) DirectX or OpenGL, or whatever the language is that they use. Then, much like C# is an "easier" (but still really powerful), higher level sibling to C++, you get Cg and HLSL that are the higher level languages that get compiled into one of the others behind the scenes.

    I'd work with Cg or HLSL, as you can (with a bit of digging in Unity's documentation) get them working right in Unity. There's a pretty good reference on the NVidia website, with a decent tutorial too, and I believe there's someone on the Unify wiki who's done all of their tutorial examples in Unity so that you can see how it works. http://http.developer.nvidia.com/CgTutorial/cg_tutorial_chapter01.html

    Otherwise, you can also grab the UDK or Unreal4 or something, and play with their node-based shader editor, just to see what tools are available to you. I'm personally not a big fan of node-based stuff (because they become jumbled and messy quite quickly), but it may give you a better, quick-feedback, visual understanding of what's going on.
  • edited
    That's quite a cool primer!

    As @Elyaradine said, HLSL, Cg and GLSL are languages used for writing shaders. You generally use GLSL with OpenGL and HLSL with XNA and DirectX (I've never used Cg). Edit: As far as I know they get compiled down to assembly in the end.

    In my limited experience, the logic you use in the shaders are really similar, so porting between them isn't that hard.
  • edited
    @Tuism - if you're starting out in Unity you don't really need to care about HLSL, GLSL, Direct-X or OpenGL or anything lowlevel.

    What you do need to know is are different kinds of Shaders.
    - Fixed pipeline shaders
    - Programmable Pipeline
    - Surface shaders

    Fixed pipeline:
    The old school way of doing it, in that you have a bunch of fixed functions you can call and you graphic card will know what to do with them. Anything simple like the built in vertex-lit shader will use this.

    Programmable pipeline:
    Allow you to embed some Cg script which was created by nvidia as high level language. This resource is invaluable: en.wikibooks.org/wiki/Cg_Programming/Unity
    Unity actually uses shader lab (a unity invention), but the meat of the shader will be Cg. The great thing about the programmable pipeline is that it allows you to do whatever you want. This is where the awesome/optimization happens. But the learning curve is highest and syntax is a bitch. The vertex and fragment operations performed by the shader (as mentioned in the article) are defined here. If you're using the fixed function pipeline you don't have any of this control.

    Surface shaders:
    Programmable shaders on user friendly mode, in that surface shaders come with pre baked lighting models and such at the expense of optimization. Also if you use a node based editor like strumpy shader editor (free) it can be a great way to get to grips with shaders as you don't have to worry about syntax so much. This is probably the best place to start out.

    Reading unity documentation without realising there are these differences will confuse the bejesus out of you as they all have radically different arcane incantations you need to perform to get them working properly. From there it's a matter of learning some of the math of shaders and the cool things it can do for you. Once you start to get it you'll realise the math is often a lot more straightforward than you realised and it starts to become fun.

    As with all things game development I find it's good to have a goal in mind and then set about achieving that goal, rather than just "trying to learn" shaders.

    Thanked by 2Tuism Elyaradine
  • OH, yeah, that wikibook is great! It's also written using the programmable pipeline, so it's quite easily ported to other game engines.

    I wouldn't recommend learning any of the other types of Unity shaders. The fixed pipeline is pretty much worthless in my opinion (pretty much all smartphones released in the past couple of years can do better...? so it's not future-proof, it's a completely different format, and it's super limited). Surface shaders are kind of handy if you're working with realtime lighting and shadows, but while they might be useful for learning overall concepts, I've found them frustrating to work with. They try to do too much for me, and as a result some of the stuff I actually want to do ends up being impossible. Which is fine if you're basically trying to make small variations on the default Unity shaders, but as soon as you try to do anything really different (pretty much all fx work), it stops being useful. Also, the kind of games you've been working on (from what I've seen) seem to be cartoony, stylised, and generally unlit, so having all the lighting stuff happen automatically for you is kind of a moot point.
    Thanked by 1TheFuntastic
  • Thanks for posting the article, I figured I might as well jump in here because there are some things that are useful to make note of.

    It should be said that cg is legacy since around 2012 and nvidia don't update it any more. CG was created to mainly solve the very old problem of shaders being assembly-like, which next versions of the api languages addressed, making CG a convenient way to use the same shader code on multiple platforms (which was great for a while). Except for platforms where CG doesn't exist (like, playstation vita/ps4, or any new platform since 2012 really), and given that CG was a native solution, it doesn't cross boundaries to WebGL or anywhere else that doesn't run native code easily, like flash with stage3D.

    Currently it fits together like this :
    Shader languages for a rendering API
    > hlsl(dx)/glsl(gl)/essl(glES)/AGSL(flash)/per platform specific shader types (consoles etc)
    Wrappers that try and make it easier to share across platforms
    > cg(legacy)/FX(legacy)/etc
    Tools to generate shader code from UI
    > shaderlab/mental mill/substance/node based UDK/ etc

    When you "learn shaders" you should focus on understanding the landscape, the underlying flow (like the primer) and the concepts and fundamentals rather than trying to master any specific language. With the knowledge of what a shader is, does, how it fits into the rendering at the end of an update loop and how you can effectively use it, what language you type letters in, is only a matter of preference or practical platform specifics and shouldn't be the thing to get snagged on early in the learning process. Anything you learn in one language is likely similar in another, if not exactly the same.

    Outside of Unity :
    If an opportunity came up to move a game to a new platform and you had done all your shaders in GLSL, unless you were generating thousands of shaders like a AAA engine with material libraries do (in which case they built tools to do that so the tool can port the shaders) you would probably only have a handful of shaders to port, and those would be really quick to port due to the languages having parallels - this is why understanding the concepts is more useful than the specific languages. Plus, you will likely have a language/syntax sheet on hand whenever writing shaders because you will want to leverage the platform specifics for performance gains, if you are doing anything above basics. If an opportunity came up to port to a NEW new platform chances are you will have to do the work anyway to use their API specific shader stuff and there is no magic button.

    With Unity,
    I am pretty sure Unity will continue to do the work with regards to sharing the shaders on platforms they target, so don't worry about CG being deprecated by Nvidia, Unity control their platform output anyway and have huge amounts of manpower to make things happen (so you can cross fingers, and hope for the best).

    Other notes:
    - Fixed pipeline is deprecated long ago in all API's, it only survives for fallback, but even the oldest shader card (horrible Intel GMA's) are 10+ years old already. If you are writing anything from scratch go shader only, fixed function is long dead.
    - Surface shaders in Unity are a nightmare as Jonathan points out which is to say:
    - I find wrappers that obscure control over important required features for anything above basics, will hurt workflow badly, unless you can control them (unlike Unity, where you are shoehorned)
    -
    As with all things game development I find it's good to have a goal in mind and then set about achieving that goal, rather than just "trying to learn" shaders.
    -
    In my limited experience, the logic you use in the shaders are really similar, so porting between them isn't that hard.
  • OMG THAT IS THE BEST RESOURCE EVER! THANKS! <3

  • These haven't been mentioned so I thought I'd just add them here:

    FX Composer
    RenderMonkey
    HLSL2GLSL (Used internally in Unity)

Sign In or Register to comment.