Convert Shader code to Shader Graph

Hi, I got the following Shader code a while ago from this thread Antialiasing circle shader and it works perfectly in my case (thanks @bgolus ). However, I wanted to convert it to Shader graph because that’s the direction I’m heading into since I’m not very good (actually, not good at all) with Shaders.

Shader "Unlit/Circle"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
        Blend SrcAlpha OneMinusSrcAlpha
        ColorMask RGB
        ZWrite Off
        Cull Off
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
        
            #include "UnityCG.cginc"
            // Quality level
            // 2 == high quality
            // 1 == medium quality
            // 0 == low quality
            #define QUALITY_LEVEL 1
            struct appdata
            {
                float4 vertex : POSITION;
                float2 texcoord : TEXCOORD0;
            };
            struct v2f
            {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
            };
        
            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = v.texcoord - 0.5;
                return o;
            }
            fixed4 _Color;
            fixed4 frag (v2f i) : SV_Target
            {
                float dist = length(i.uv);
            #if QUALITY_LEVEL == 2
                // length derivative, 1.5 pixel smoothstep edge
                float pwidth = length(float2(ddx(dist), ddy(dist)));
                float alpha = smoothstep(0.5, 0.5 - pwidth * 1.5, dist);
            #elif QUALITY_LEVEL == 1
                // fwidth, 1.5 pixel smoothstep edge
                float pwidth = fwidth(dist);
                float alpha = smoothstep(0.5, 0.5 - pwidth * 1.5, dist);
            #else // Low
                // fwidth, 1 pixel linear edge
                float pwidth = fwidth(dist);
                float alpha = saturate((0.5 - dist) / pwidth);
            #endif
                return fixed4(_Color.rgb, _Color.a * alpha);
            }
            ENDCG
        }
    }
}

I’m having trouble trying to figure out how to convert the code to Shader graph. @bgolus Perhaps you could help me out since you wrote this Shader.

Thanks in advance.

The built in Ellipse node is equivalent to the “low quality” option.

If you want to implement the “high quality” version, all of the functions used have direct Shader Graph node equivalents with the same name.

Ok I’ve seen the functions being used in the code in Shader graph such as (DDX, DDY & smoothstep etc.) and I also tried the Ellipse Node but how do I implement the following in Shader graph?

v2f vert (appdata v)
{
     v2f o;
     o.pos = UnityObjectToClipPos(v.vertex);
     o.uv = v.texcoord - 0.5;
     return o;
}

How do I get the v.texcoord value

or calculate the following?

float dist = length(i.uv);

Where do I retrieve i.uv from above?

Thanks.

You use the UV node, a subtract node, and a length node. Do the same math, don’t worry about where it’s coming from.

1 Like

Ok I will try that out tomorrow. Will let you know if it works or if I got stuck.

Thanks :slight_smile:

Hey @bgolus , so I’ve been trying to replicate the code in Shader Graph for the past few hours and I’m kind of lost. This is what I have so far.

From your answer in the thread What is the equivalent of UnityObjectToClipPos inside Shader Graph?? , the nodes in the top try to replicate the UnityObjectToClipPos method (I don’t know if its completely correct here).

But I can’t figure out how to link its output to the nodes below starting from the UV node on the left. I’ve tried to replicate the math from the Shader code in the nodes below (not sure if it has been correctly implemented).

Can you please have a look?
Thanks.

There’s no reason to do that. That’s basic vertex fragment shader stuff that’s unnecessary for Shader Graph. It’s already doing that. I noticed you’re also subtracting 0.5 from that, which isn’t what the original shader is doing.

A texcoord, aka “texture coordinate” is another name for a UV coordinate. That bit of code in the vertex shader is just passing along the mesh’s texture coordinates to the fragment shader. I just happen to also be doing the subtraction there because I can. In Shader Graph you don’t really have any options for doing stuff in the vertex shader (ignoring vertex manipulation).

The other thing that’s going to be messing with you is Shader Graph’s UV node outputs a Vector4 value. Very few people are going to want that. Almost everyone is only ever going to want a Vector2, but for some reasons they didn’t bother to include that as an option. In this case, that’s going to screw things up because the length of a Vector4 is not the same thing as the length of a Vector2. You need to split the Vector4 output and combine it back into a Vector2, subtract 0.5 from that, and then use the first Length node.

Or just plug a UV node into an Ellipse node and be done.

Cool. Will definitely give it another go.

Thanks for your help.

@bgolus plz help me in converting this shader code to shader graph:

Shader “WorldBend/Bend_Unlit”
{
Properties
{
_Color (“Main Color”, Color) = (1,1,1,1)
_Emission (“Emissive Color”, Color) = (0,0,0,0)
_MainTex (“Base (RGB)”, 2D) = “white” { }
}

SubShader
{
Tags { “RenderType”=“Opaque” }
LOD 100

Pass {
Name “BASE”
CGPROGRAM
#pragma vertex vert
#pragma fragment frag

#include “UnityCG.cginc”
#include “BendEffect.cginc”

struct appdata_t {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;

};

struct v2f {
float4 vertex : SV_POSITION;
half2 texcoord : TEXCOORD0;
};

sampler2D _MainTex;
float4 _MainTex_ST;
float4 _Emission;
float4 _Color;

v2f vert (appdata_t v)
{
v2f o;
o.vertex = UnityObjectToClipPos(BendEffect(v.vertex));
o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}

fixed4 frag (v2f i) : COLOR
{
fixed4 col = tex2D(_MainTex, i.texcoord) * _Color;
return col + _Emission;
}
ENDCG
}
}
}

Bend Effect function defination:
#ifndef BENDEFFECT_INCLUDED
#define BENDEFFECT_INCLUDED

uniform float _BEND_Y = 0.0f;
uniform float _BEND_X = 0.0f;
uniform float _HORIZON = 0.0f;
uniform float _SPREAD = 0.0f;

float4x4 _Camera2World;
float4x4 _World2Camera;

float4 BendEffect (float4 v)
{
float4 t = mul (unity_ObjectToWorld, v);
float dist = max(0, abs(_HORIZON - t.z) - _SPREAD);
t.y -= dist * dist * _BEND_Y;
t.x -= dist * dist * _BEND_X;
t.xyz = mul(unity_WorldToObject, t).xyz;
return t;
}

#endif

No.

Make an attempt yourself, and post in a new thread.

5 Likes