بنقرة واحدة
urp-hlsl-templates
Production-ready URP HLSL/ShaderLab code templates with SRP Batcher compatibility for Unity
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Production-ready URP HLSL/ShaderLab code templates with SRP Batcher compatibility for Unity
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Single-pass post-processing, URP Renderer Features, and mobile-safe screen effects for Unity
GPU architecture, precision types, fillrate, overdraw, baked lighting, and LOD optimization for Unity mobile/WebGL shaders
Node budgets, custom lighting, sub-graphs, precision control, and mobile workflows for Unity Shader Graph
Channel packing, variant reduction, shader_feature vs multi_compile, and build size optimization for Unity
Mobile-optimized water shaders with depth coloring, foam, Gerstner waves, refraction, and caustics for Unity URP
WebGL 1.0/2.0 shader restrictions, variant stripping, loop/indexing rules, and browser deployment workarounds for Unity
| name | urp-hlsl-templates |
| description | Production-ready URP HLSL/ShaderLab code templates with SRP Batcher compatibility for Unity |
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.
Always use HLSLPROGRAM / ENDHLSL, never CGPROGRAM / ENDCG. URP uses HLSL, not CG. CG blocks will compile but miss URP-specific includes and macros.
All material properties must be in a CBUFFER_START(UnityPerMaterial) / CBUFFER_END block for SRP Batcher compatibility. Without this, each material breaks batching and gets its own draw call.
Include URP Core, not legacy Unity includes.
// 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"
Use URP transform macros, not legacy ones:
// 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)
Tags must include "RenderPipeline" = "UniversalPipeline" or the shader won't be recognized by URP.
Use TEXTURE2D and SAMPLER macros instead of 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 |
Forgetting CBUFFER → Breaks SRP Batcher. Every draw call becomes unique. Check with Frame Debugger > SRP Batcher column.
Using sampler2D instead of TEXTURE2D macro → Works but loses cross-platform sampler control and may break on some platforms.
Missing ShadowCaster pass → Object won't cast shadows. Always include it or use UsePass/Fallback.
Missing DepthOnly pass → Depth-based effects (fog, post-processing, water depth) won't see this object.
Using multi_compile instead of shader_feature → 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.