Hi, I’m completely new to ShaderLab (some HLSL experience) and attempted to recreate a Shader Graph tutorial with ShaderLab (https://game-developers.org/unity-ribbon-spiral-shader-graph-tutorial/).
It pretty much works except for the last part (gradient color), but I have no idea about best practices and have commented questions I could not find a definitive answer to in the code below.
Thoughts?
Shader "Particles/Ribbon"
{
Properties
{
[Header(Color)]
_MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
// Declare vector properties without 4 values in editor?
[Header(Constants)]
_Up ("Up", Vector) = (0,1,0)
_Left ("Left", Vector) = (-1,0,0)
[Header(Streaks)]
_Width ("Width", Float) = 0.5
_Gap ("Gap", Float) = 0.5
// Can't specify integer?
_Count ("Count Multiplier", Int) = 3
[Header(Animation)]
_Speed ("Speed", Float) = 1
_Offset ("Offset", Float) = 0
// No easy way to define gradients in ShaderLab?
// _Gradient ("Gradient", Gradient) = ???
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"RenderType" = "Transparent"
// Any tag to enable _Time updates in preview?
}
// For transparency to work (?)
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
// Use CGPROGRAM or HLSLPROGRAM?
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
/** What we get to work with */
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 uv : TEXCOORD0;
};
/** Information from vertecies */
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
/** Object Space */
float4 os : POSITION1;
float2 uv : TEXCOORD0;
};
// Redeclare properties
sampler2D _MainTex;
fixed4 _Color;
float4 _MainTex_ST;
float3 _Up;
float3 _Left;
float _Width;
int _Count;
float _Speed;
float _Offset;
float _Gap;
/** Process vertecies */
v2f vert(appdata_t v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.color = v.color * _Color;
o.os = v.vertex;
return o;
}
/** Process pixels */
fixed4 frag(const v2f i) : SV_Target
{
half4 col = i.color;
const float3 val1 = normalize(_Left);
// Radial mask
const float val2 = acos(dot(val1, normalize(cross(i.os, _Up))));
// Normalize (?) spirals
const float val2_5 = val2 / (UNITY_PI * 2);
// Number of spirals
const float val3 = val2_5 * sign(dot(val1, i.os)) * _Count;
// Animate spirals
const float val4 = _Offset + _Time.y * _Speed + val3;
// Transparency gradient - fading out towards the top (positive Y)
col.a = 1 - step(_Width, frac(dot(_Up, i.os) / _Gap + val4));
return col;
}
ENDHLSL
}
}
}
Also, a question that comes to mind after doing this is, do people still write shaders with just ShaderLab or have people moved to Shader Graph? The documentation on ShaderLab is very lackluster, unlike what I have seen from Shader Graph, which actually has a complete library of all nodes.
As of now I feel like the way to go is to just use Shader Graph with the Custom Function Node (writing code is quicker, cleaner and more convenient than building a network of nodes in my opinion).
Thanks ^^