3 answers · asked · Lesson: Creating Image Effect Shaders · Course: Shader School

After watching the video there were a few points I wanted to clarify if that was ok.

Why are we using the COLOR binding semantic instead of SV_Target for the frag function? From a search I did online I read that SV_Target would work for more target frameworks so I'm slightly confused. Link to the forum post I read : 

What does changing the #pragma vertex vert statement's specified function to vert_img do exactly? From my research, vert_img is a function specified in UnityCG.cginc, but I'm not entirely sure why we are using it.

Thank you for doing this series by the way. I tried getting into shaders a while back but found it a bit difficult.

  • I was just going through this series, and I saw your question and decided to take a shot at answering.

    COLOR versus SV_Target

    COLOR and SV_Target are roughly the same thing, though with a noteable difference.

    COLOR is a Semantic that represents a float4 with color information. Semantics are just a fancy way of saying data type. For a fragment shader, specifing a return type of COLOR means you're returning a pixel to the screen.

    SV_Target is a System-Value Semantic, which means it is a semantic like COLOR, but with a slightly different usage. It indicates that the type is a render target. Render targets can either be a draw buffer(aka, the screen), or a texture. Like color, you're still returning a pixel, it's just you may not be returning a pixel directly to the screen. This concept was introduced in DirectX 10.

    Where things get confusing: a semantic like SV_Target is now interchangeable with COLOR. If you are writing specifically for DX9, you have to use COLOR. If you are writing for DX10 or DX11, you can use either COLOR or SV_Target. The shader compiler will intrinsicly know what to do based on your target platform and your shader type. Another example of this interchange-ability would be POSITION and SV_Position.

    As far as I can tell, with respect to Unity, it doesn't really matter. Best practices would be to use SV_Target exclusively, as it's newer. COLOR shouldn't hurt you though, unless doing something legacy platform dependent.

  • #pragma, vert_img

    # is a Directive, a way of talking directly to the compiler.

    pragma states you wish to use implementation-dependent features specific to the current language.

    In laymans terms, #pragma vertex vert tells the HLSL compiler that you want to access a specific feature of HLSL shaders, and assign the "vertex" output function to be your own custom "vert" function.

    Unity has done a ton of work that we can reuse, and one such case is with UnityCG.cginc. The UnityCG.cginc is a shader snippet, filled with TONS of code and values you can use in your own shaders. By using the #include directive, you're telling HLSL to reference from that snippet in your own shader file.

    With UnityCG.cginc included, you now have access to vert_img, one of the many premade functions Unity has already provided. Instead of writing your own vertex function for your image effects shader every time, you can just use theirs instead.

    In conclusion: #pragma vertex vert_img is telling your shader to use Unity's premade image effects vertex function as your own, and therefore skipping the need to rewrite something that's routinely the same for each image effects shader.

    For the record, you can view the UnityGC.cginc file by checking your "Unity\Editor\Data\CGIncludes" folder and dragging and dropping the file into your code editor. There is a massive amount of shader code in that folder for you to poke around in. You can check out what makes vert_img tick from there.

    You can also create your own code snippets by simply creating an empty text file with .cginc as the extension, and then using the #include "MyCustomSnippet.cginc" into your shader.

  • crew

    I believe I answered a similar question to this earlier in the course. Nonetheless astute covered basically everything and then some. I don't remember exactly why I chose to use COLOR over SV_Target but SV_Target would indeed cover just about everything we'd need. I believe I was just used to using COLOR for a lot of these shaders so I stuck with it.

    As far as the vert_img, this is a built in function like already mentioned above so I used that. Since we weren't doing anything out of the ordinary in terms of those functions I just utilized all the premade shader code Unity provides. 

    Also thanks astute for providing a detailed reply. Sometimes it's easy to forget all the shader syntax and logic involved.