Create Unity shaders using Shader Graph, HLSL, or ShaderLab for Universal Render Pipeline (URP). Use when implementing custom rendering effects, materials, or visual styles.
🏠 HaroFramework Project | 📂 Skill | ⬆️ Skill
Expert skill for creating shaders in Unity's Universal Render Pipeline (URP).
Activate this skill when the user requests:
Create via: Right-click > Create > Shader Graph > URP > Lit Shader Graph
Common Node Setup:
Texture2D (Base Map) → Sample Texture 2D → Base Color (Output)
Texture2D (Normal Map) → Sample Texture 2D (Normal) → Normal (Output)
Float (Metallic) → Metallic (Output)
Float (Smoothness) → Smoothness (Output)
Create via: Right-click > Create > Shader Graph > URP > Unlit Shader Graph
Simple Color Shader:
Color → Base Color (Output)
Float (Alpha) → Alpha (Output)
// Custom dissolve function
void Dissolve_float(float Progress, float NoiseValue, float EdgeWidth, out float Result)
{
float threshold = Progress;
float edge = EdgeWidth;
if (NoiseValue < threshold - edge)
{
Result = 0.0; // Fully dissolved
}
else if (NoiseValue < threshold)
{
Result = (NoiseValue - (threshold - edge)) / edge; // Edge
}
else
{
Result = 1.0; // Solid
}
}
Shader "HaroFramework/CustomLit"
{
Properties
{
_BaseMap("Base Map", 2D) = "white" {}
_BaseColor("Base Color", Color) = (1, 1, 1, 1)
_Smoothness("Smoothness", Range(0, 1)) = 0.5
_Metallic("Metallic", Range(0, 1)) = 0
}
SubShader
{
Tags
{
"RenderType" = "Opaque"
"RenderPipeline" = "UniversalPipeline"
"Queue" = "Geometry"
}
Pass
{
Name "ForwardLit"
Tags { "LightMode" = "UniversalForward" }
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
// URP required keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS
#pragma multi_compile _ _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
float3 positionWS : TEXCOORD0;
float3 normalWS : TEXCOORD1;
float2 uv : TEXCOORD2;
};
TEXTURE2D(_BaseMap);
SAMPLER(sampler_BaseMap);
CBUFFER_START(UnityPerMaterial)
float4 _BaseMap_ST;
float4 _BaseColor;
float _Smoothness;
float _Metallic;
CBUFFER_END
Varyings vert(Attributes input)
{
Varyings output;
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS);
output.positionHCS = vertexInput.positionCS;
output.positionWS = vertexInput.positionWS;
output.normalWS = normalInput.normalWS;
output.uv = TRANSFORM_TEX(input.uv, _BaseMap);
return output;
}
float4 frag(Varyings input) : SV_Target
{
// Sample textures
float4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv);
float3 albedo = baseMap.rgb * _BaseColor.rgb;
// Lighting
InputData lightingInput = (InputData)0;
lightingInput.positionWS = input.positionWS;
lightingInput.normalWS = normalize(input.normalWS);
lightingInput.viewDirectionWS = GetWorldSpaceNormalizeViewDir(input.positionWS);
lightingInput.shadowCoord = TransformWorldToShadowCoord(input.positionWS);
SurfaceData surfaceData = (SurfaceData)0;
surfaceData.albedo = albedo;
surfaceData.metallic = _Metallic;
surfaceData.smoothness = _Smoothness;
surfaceData.alpha = _BaseColor.a;
return UniversalFragmentPBR(lightingInput, surfaceData);
}
ENDHLSL
}
Pass
{
Name "ShadowCaster"
Tags { "LightMode" = "ShadowCaster" }
HLSLPROGRAM
#pragma vertex ShadowPassVertex
#pragma fragment ShadowPassFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"
ENDHLSL
}
}
FallBack "Hidden/Universal Render Pipeline/FallbackError"
}
Shader "HaroFramework/CustomUnlit"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_Color("Color", Color) = (1, 1, 1, 1)
[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend("Src Blend", Float) = 1
[Enum(UnityEngine.Rendering.BlendMode)] _DstBlend("Dst Blend", Float) = 0
[Enum(Off, 0, On, 1)] _ZWrite("Z Write", Float) = 1
}
SubShader
{
Tags
{
"RenderType" = "Opaque"
"RenderPipeline" = "UniversalPipeline"
"Queue" = "Geometry"
}
Pass
{
Blend [_SrcBlend] [_DstBlend]
ZWrite [_ZWrite]
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
float4 color : COLOR;
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
float2 uv : TEXCOORD0;
float4 color : COLOR;
};
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST;
float4 _Color;
CBUFFER_END
Varyings vert(Attributes input)
{
Varyings output;
output.positionHCS = TransformObjectToHClip(input.positionOS.xyz);
output.uv = TRANSFORM_TEX(input.uv, _MainTex);
output.color = input.color;
return output;
}
float4 frag(Varyings input) : SV_Target
{
float4 texColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv);
return texColor * _Color * input.color;
}
ENDHLSL
}
}
}
// In Shader Graph: Custom Function Node
void DissolveEffect_float(
float Progress,
float NoiseValue,
float EdgeWidth,
float4 EdgeColor,
out float Alpha,
out float4 Emission)
{
float threshold = Progress;
float edge = EdgeWidth;
if (NoiseValue < threshold - edge)
{
Alpha = 0.0;
Emission = float4(0, 0, 0, 0);
}
else if (NoiseValue < threshold)
{
float t = (NoiseValue - (threshold - edge)) / edge;
Alpha = t;
Emission = EdgeColor * (1.0 - t);
}
else
{
Alpha = 1.0;
Emission = float4(0, 0, 0, 0);
}
}
float3 ApplyWind_float(float3 positionOS, float3 normal, float time, float strength)
{
float wave = sin(time + positionOS.x * 2.0) * cos(time * 0.5 + positionOS.z);
float3 offset = normal * wave * strength * positionOS.y; // Affect based on height
return positionOS + offset;
}
float FresnelEffect_float(float3 Normal, float3 ViewDir, float Power)
{
return pow(1.0 - saturate(dot(normalize(Normal), normalize(ViewDir))), Power);
}
float ToonShading_float(float NdotL, int steps)
{
float toonValue = floor(NdotL * steps) / steps;
return toonValue;
}
// Transform spaces
float3 TransformObjectToWorld(float3 positionOS);
float3 TransformWorldToObject(float3 positionWS);
float4 TransformObjectToHClip(float3 positionOS);
// Normals
float3 TransformObjectToWorldNormal(float3 normalOS);
float3 TransformWorldToObjectNormal(float3 normalWS);
// View direction
float3 GetWorldSpaceViewDir(float3 positionWS);
float3 GetWorldSpaceNormalizeViewDir(float3 positionWS);
// Lighting
Light GetMainLight();
Light GetMainLight(float4 shadowCoord);
Light GetAdditionalLight(uint index, float3 positionWS);
// Shadows
float4 TransformWorldToShadowCoord(float3 positionWS);
half MainLightRealtimeShadow(float4 shadowCoord);
// In Properties
[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend("Src Blend", Float) = 5 // SrcAlpha
[Enum(UnityEngine.Rendering.BlendMode)] _DstBlend("Dst Blend", Float) = 10 // OneMinusSrcAlpha
_ZWrite("Z Write", Float) = 0
// In SubShader Tags
Tags { "Queue" = "Transparent" "RenderType" = "Transparent" }
// In Pass
Blend [_SrcBlend] [_DstBlend]
ZWrite [_ZWrite]
HaroFramework/Category/ShaderName namingAssets/
Art/
Shaders/
ShaderGraphs/
*.shadergraph
CustomShaders/
*.shader
SubGraphs/
*.shadersubgraph
Materials/
*.mat
Before creating a shader: