Shader Graph UI Image Shader

Is it possible to make a shader for an Image(sprite) that does not need a scene light? My shader is black without a light?

1 Like

Figured it out. At least what I figured out works.

Could you post what you did that worked?

https://www.youtube.com/watch?v=7M4UmN54hk0
. Haven’t worked it any more than this though .

3 Likes

I had issues using Shader graph for a UI Image, finally fixed all the issues and decided to make a tutorial about it.
besides of the Canvas render mode issues I also had the “Material doesn’t have texture property ‘_MainTex’” error.

hope you will find it useful

4 Likes

For me, Screen Space - Camera was not an option. Setting the canvas distance close to the near clipping plane introduced pixel jitter. Setting it farther made the UI clip with scene geometry.

There are two solutions I have found:

  1. Use Screen Space - Camera with custom UI shaders with ZTest set to Always
  2. Edit your custom shader Blend properties

First, hop on over to Download Archive and use the drop-downs to grab copies of the built-in shaders. If you look in DefaultResourcesExtra\UI\UI-Default.shader, you can see how the shaders are usually set up for UI.

Solution 1:
Once you have a copy of UI-Default.shader, go ahead and change ZTest [unity_GUIZTestMode] to ZTest Always. It should be around line 44. You will then need to create a material using this shader and use it for every UI element on the Screen Space-Camera Canvas to prevent clipping. Then you can set the canvas far enough out to prevent jitter. You will also have to set ZTest Always on your Shader Graph shader.

Solution 2:
To create a code version of your Shader Graph, right-click the master node and select, Copy Shader. Then paste it into a new shader file.

In order to make your Shader Graph render correctly in Screen Space-Overlay mode, you will need to set the blend settings as they are in the Default UI shader. As of this writing, Unlit Shader Graphs set Blend at the Pass level: Blend One Zero, One Zero. We need it at the SubShader level: Blend SrcAlpha OneMinusSrcAlpha. (See line 49 in the code below.)

If you want Image tinting to work correctly, keep in mind that the Image component leverages vertex colors. You will have to do the blending in your graph, like so:4999583--488516--upload_2019-9-25_11-13-48.png

Your can also add in some of the features from the default UI shader. Below is the code I am using up until the point where the HLSL starts.

Shader "UI/Pulse"
{
    Properties
    {
        [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
        _Color("Tint", Color) = (1,1,1,1)
       
        [ToggleUI] _Pulse("Pulse", Float) = 1
        _HighlightColor("Highlight Color", Color) = (1,0.6412213,0,1)
        _HighlightFrequency("Frequency ", Float) = 1
        _HighlightStrength("Strength ", Range(0, 1)) = 1

        _StencilComp("Stencil Comparison", Float) = 8
        _Stencil("Stencil ID", Float) = 0
        _StencilOp("Stencil Operation", Float) = 0
        _StencilWriteMask("Stencil Write Mask", Float) = 255
        _StencilReadMask("Stencil Read Mask", Float) = 255

        _ColorMask("Color Mask", Float) = 15

        [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip("Use Alpha Clip", Float) = 0

    }
    SubShader
    {
        Tags
        {
            "RenderPipeline" = "LightweightPipeline"
            "Queue" = "Transparent"
            "IgnoreProjector" = "True"
            "RenderType" = "Transparent"
            "PreviewType" = "Plane"
            "CanUseSpriteAtlas" = "True"
        }
       
        Stencil
        {
            Ref[_Stencil]
            Comp[_StencilComp]
            Pass[_StencilOp]
            ReadMask[_StencilReadMask]
            WriteMask[_StencilWriteMask]
        }

        Cull Off
        Lighting Off
        ZWrite Off
        ZTest[unity_GUIZTestMode]
        Blend SrcAlpha OneMinusSrcAlpha
        ColorMask[_ColorMask]
           
        Pass
        {
            HLSLPROGRAM
12 Likes

Thank you! I followed your second route and I updated the ZTest to “ZTest[unity_GUIZTestMode]” and the Blend to “Blend SrcAlpha OneMinusSrcAlpha”.

This worked for an Unlit shader in Unity 2019.3.15f1

Thank you, noahabannister, for the explanation!
I also used the second solution and it works correctly for an Unlit shader in Unity 2020.1.17f1.

Now it’s much easier - just select one of Sprite options here

4 Likes

is there anything for HDRP that works?

You can make it work with amplify shader when using a legacy UI / Sprite shader and using a sprite input
Keep in mind the alpha channel

It would be good if HDRP supported Sprite Unlit, if it means that I can get my Shadergraph UI shaders to work with HDRP and Screen Space Overlay Canvas. Feel this should just work out of the Box.

Hi, how to keep it masked by Rect Mask 2D?

Before using custom shader:
7532183--929966--upload_2021-9-29_17-11-32.png
After using custom shader:
7532183--929969--upload_2021-9-29_17-12-23.png

My shader graph:

Thank you for helping!

I did it.
Don’t use Rect Mask 2D.
Add Mask and Image to the parent gameobject > set image material using your custom material
7532258--929981--upload_2021-9-29_17-49-56.png

1 Like

Can you please describe in more detail how you did it? I repeat everything one to one, nothing works for me, the mask still does not work.

I think I found a solution: set the Z position of your shadergraph UI image to 1000.
The image is no longer blocked by the world, but it’s still visible and works as intended

(Mics info: canvas is screen space overlay, scales with screen sizel, match width or height, 3d topdown game, unlit opaque shadergraph with alpha-clip, uses the UV to render a noise, unity version: 2022.2.1f1)

2 Likes

If you’re following the solutions posted here but still running into problems it’s because Unity Shader Graph does not support the creation of shaders for rendering with the canvas renderer(UI). Confirmed here by Unity.

If you’re like me and desperately want this feature added then please vote on it here.

4 Likes

Why do you want to combine a shader with rect mask 2D?
Rect mask 2D is a shortcut for not making a shader
Just add a texture mask to your shader. It looks better and is likely even less expensive

This thread ranks highly and desperately needs this update:

** You can now target the Canvas in Shader Graph in Unity 6+. **

Unity - Manual: Canvas Shader Graph

To create a Canvas material in Shader Graph, here’s how for URP:

or

Official how-to:

https://docs.unity3d.com/Packages/com.unity.ugui@2.0/manual/HOWTO-ShaderGraph.html

Also technically earliest release was 2023.2.0a18