urp-hlsl-templates — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited urp-hlsl-templates (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Use this skill when the user wants to write a Unity shader in HLSL/ShaderLab code (not Shader Graph) for Universal Render Pipeline. Triggers include: "URP shader", "HLSL", "ShaderLab", "write a shader", "custom shader", "vertex fragment shader", "SRP Batcher", "CBUFFER", "custom lit shader", "unlit shader", or any code-based shader authoring in URP. Also trigger when converting Built-in pipeline shaders to URP, or when the user references Cyanilux templates, phi-lira gists, or NedMakesGames tutorials.
// CORRECT (URP)
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
// WRONG (Built-in / legacy)
#include "UnityCG.cginc"
#include "Lighting.cginc" // URP // Legacy equivalent
TransformObjectToHClip(posOS) // UnityObjectToClipPos(v.vertex)
TransformObjectToWorld(posOS) // mul(unity_ObjectToWorld, v.vertex)
TransformObjectToWorldNormal(nOS) // UnityObjectToWorldNormal(v.normal)
TransformWorldToHClip(posWS) // mul(UNITY_MATRIX_VP, float4(posWS, 1))
GetVertexPositionInputs(posOS) // (convenience struct)
GetVertexNormalInputs(nOS, tanOS) // (convenience struct)sampler2D: TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
// Sample with:
half4 col = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv);Minimal unlit shader with SRP Batcher compatibility. Use as starting point for mobile shaders:
Shader "Custom/URP_Unlit_Mobile"
{
Properties
{
_BaseMap ("Base Map", 2D) = "white" {}
_BaseColor ("Base Color", Color) = (1, 1, 1, 1)
}
SubShader
{
Tags
{
"RenderType" = "Opaque"
"RenderPipeline" = "UniversalPipeline"
"Queue" = "Geometry"
}
Pass
{
Name "ForwardLit"
Tags { "LightMode" = "UniversalForward" }
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
// SRP Batcher compatible: all properties in CBUFFER
CBUFFER_START(UnityPerMaterial)
float4 _BaseMap_ST;
half4 _BaseColor;
CBUFFER_END
TEXTURE2D(_BaseMap);
SAMPLER(sampler_BaseMap);
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
half fogFactor : TEXCOORD1;
};
Varyings vert(Attributes input)
{
Varyings output;
VertexPositionInputs posInputs = GetVertexPositionInputs(input.positionOS.xyz);
output.positionCS = posInputs.positionCS;
output.uv = TRANSFORM_TEX(input.uv, _BaseMap);
output.fogFactor = ComputeFogFactor(posInputs.positionCS.z);
return output;
}
half4 frag(Varyings input) : SV_Target
{
half4 color = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv) * _BaseColor;
color.rgb = MixFog(color.rgb, input.fogFactor);
return color;
}
ENDHLSL
}
// Shadow caster pass (required for objects to cast shadows)
Pass
{
Name "ShadowCaster"
Tags { "LightMode" = "ShadowCaster" }
ZWrite On ZTest LEqual ColorMask 0
HLSLPROGRAM
#pragma vertex ShadowPassVertex
#pragma fragment ShadowPassFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"
ENDHLSL
}
// Depth pass (required for depth-based effects)
Pass
{
Name "DepthOnly"
Tags { "LightMode" = "DepthOnly" }
ZWrite On ColorMask R
HLSLPROGRAM
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
ENDHLSL
}
}
Fallback "Universal Render Pipeline/Unlit"
}Adds Lambert diffuse lighting from the main directional light:
Shader "Custom/URP_SimpleLit_Mobile"
{
Properties
{
_BaseMap ("Base Map", 2D) = "white" {}
_BaseColor ("Base Color", Color) = (1, 1, 1, 1)
}
SubShader
{
Tags
{
"RenderType" = "Opaque"
"RenderPipeline" = "UniversalPipeline"
"Queue" = "Geometry"
}
Pass
{
Name "ForwardLit"
Tags { "LightMode" = "UniversalForward" }
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE
#pragma multi_compile _ _SHADOWS_SOFT
#pragma multi_compile_fog
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
CBUFFER_START(UnityPerMaterial)
float4 _BaseMap_ST;
half4 _BaseColor;
CBUFFER_END
TEXTURE2D(_BaseMap);
SAMPLER(sampler_BaseMap);
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
float3 normalWS : TEXCOORD1;
float3 positionWS : TEXCOORD2;
half fogFactor : TEXCOORD3;
};
Varyings vert(Attributes input)
{
Varyings output;
VertexPositionInputs posInputs = GetVertexPositionInputs(input.positionOS.xyz);
VertexNormalInputs normInputs = GetVertexNormalInputs(input.normalOS);
output.positionCS = posInputs.positionCS;
output.positionWS = posInputs.positionWS;
output.normalWS = normInputs.normalWS;
output.uv = TRANSFORM_TEX(input.uv, _BaseMap);
output.fogFactor = ComputeFogFactor(posInputs.positionCS.z);
return output;
}
half4 frag(Varyings input) : SV_Target
{
half4 baseColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv) * _BaseColor;
// Main light (directional)
float4 shadowCoord = TransformWorldToShadowCoord(input.positionWS);
Light mainLight = GetMainLight(shadowCoord);
half3 normal = normalize(input.normalWS);
half NdotL = saturate(dot(normal, mainLight.direction));
half3 diffuse = baseColor.rgb * mainLight.color * NdotL * mainLight.shadowAttenuation;
// Ambient
half3 ambient = SampleSH(normal) * baseColor.rgb;
half3 finalColor = diffuse + ambient;
finalColor = MixFog(finalColor, input.fogFactor);
return half4(finalColor, baseColor.a);
}
ENDHLSL
}
// Include ShadowCaster and DepthOnly passes (same as unlit template above)
UsePass "Custom/URP_Unlit_Mobile/ShadowCaster"
UsePass "Custom/URP_Unlit_Mobile/DepthOnly"
}
Fallback "Universal Render Pipeline/Simple Lit"
}| Built-in | URP Equivalent |
|---|---|
#include "UnityCG.cginc" | #include ".../Core.hlsl" |
#include "Lighting.cginc" | #include ".../Lighting.hlsl" |
UnityObjectToClipPos(v) | TransformObjectToHClip(v.xyz) |
UnityObjectToWorldNormal(n) | TransformObjectToWorldNormal(n) |
_WorldSpaceLightPos0 | GetMainLight().direction |
_LightColor0 | GetMainLight().color |
UNITY_LIGHTMODEL_AMBIENT | SampleSH(normal) |
SHADOW_COORDS / TRANSFER_SHADOW | TransformWorldToShadowCoord(posWS) |
SHADOW_ATTENUATION(i) | GetMainLight(shadowCoord).shadowAttenuation |
tex2D(_Tex, uv) | SAMPLE_TEXTURE2D(_Tex, sampler_Tex, uv) |
sampler2D _Tex | TEXTURE2D(_Tex); SAMPLER(sampler_Tex); |
UNITY_FOG_COORDS / APPLY_FOG | ComputeFogFactor() / MixFog() |
v2f struct convention | Varyings struct convention |
appdata struct convention | Attributes struct convention |
Tags { "LightMode" = "ForwardBase" } | Tags { "LightMode" = "UniversalForward" } |
Surface shader #pragma surface | No equivalent — write vertex/fragment manually |
URP requires explicit pass names for the renderer to recognize them:
| LightMode Tag | Purpose |
|---|---|
UniversalForward | Main rendering pass |
ShadowCaster | Shadow map generation |
DepthOnly | Depth prepass |
DepthNormals | Depth + normals prepass (for SSAO, depth-normals effects) |
Meta | Lightmap baking |
Universal2D | 2D renderer pass |
SRPDefaultUnlit | Fallback when no LightMode matches |
UsePass/Fallback.multi_compile compiles ALL keyword variants. shader_feature only compiles variants used by materials in the build. For material-specific toggles, always use shader_feature.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.