Shader "Oculus Sample/Alpha Hand Outline URP"
_ColorPrimary ("Color Primary", Color) = (0.396078, 0.725490, 1, 1)
_ColorTop ("Color Top", Color) = (0.031896, 0.0343398, 0.0368894, 1)
_ColorBottom ("Color Bottom", Color) = (0.0137021, 0.0144438, 0.0152085, 1)
_RimFactor ("Rim Factor", Range(0.01, 1.0)) = 0.65
_FresnelPower ("Fresnel Power", Range(0.01,1.0)) = 0.16
_HandAlpha ("Hand Alpha", Range(0, 1)) = 1.0
_MinVisibleAlpha ("Minimum Visible Alpha", Range(0,1)) = 0.15
// Matches original tags for transparency
"RenderType"="Transparent"
// --- Pass 1: Depth-only (no color) ---
Tags { "LightMode" = "DepthOnly" }
ColorMask 0 // Don’t write color, only depth
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
float4 positionOS : POSITION;
float4 positionHCS : SV_POSITION;
Varyings vert (Attributes IN)
OUT.positionHCS = TransformObjectToHClip(IN.positionOS);
float4 frag (Varyings IN) : SV_Target
// We only care about writing depth, so color is unused.
return float4(0, 0, 0, 0);
// --- Pass 2: Forward-lit pass with rim/fresnel effect ---
Tags { "LightMode" = "UniversalForward" }
// Typical blend for transparency
Blend SrcAlpha OneMinusSrcAlpha
// Matching original code that writes depth on transparent
#pragma prefer_hlslcc gles
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float4 positionHCS : SV_POSITION;
float3 normalWS : TEXCOORD0;
float3 viewDirWS : TEXCOORD1;
UNITY_DECLARE_COLOR(_ColorPrimary);
UNITY_DECLARE_COLOR(_ColorTop);
UNITY_DECLARE_COLOR(_ColorBottom);
// ---------------------------------------------------
// VERTEX: transform positions/normals to world space
// ---------------------------------------------------
Varyings vert (Attributes IN)
float3 worldPos = TransformObjectToWorld(IN.positionOS.xyz);
OUT.positionHCS = TransformWorldToHClip(worldPos);
OUT.normalWS = normalize(TransformObjectToWorldNormal(IN.normalOS));
// Calculate view direction in world space
float3 viewDirWS = GetCameraPositionWS() - worldPos;
OUT.viewDirWS = normalize(viewDirWS);
// ---------------------------------------------------
// FRAGMENT: apply rim/fresnel effect & alpha
// ---------------------------------------------------
half4 frag (Varyings IN) : SV_Target
float3 normalDirection = normalize(IN.normalWS);
float3 viewDir = normalize(IN.viewDirWS);
// Dot of view direction vs. normal
float viewDotNormal = saturate(dot(viewDir, normalDirection));
// Rim factor logic from original
float rim = pow(1.0 - viewDotNormal, 0.5) * (1.0 - _RimFactor) + _RimFactor;
// "Emission" color near edges
float3 emission = lerp(float3(0,0,0), _ColorPrimary.rgb, rim);
emission += rim * 0.5; // brightens near edges
emission *= 0.95; // original "EmissionFactor"
// Fresnel-based color fade from top to bottom
float fresnel = saturate(pow(1.0 - viewDotNormal, _FresnelPower));
float3 color = lerp(_ColorTop.rgb, _ColorBottom.rgb, fresnel);
float alphaValue = step(_MinVisibleAlpha, _HandAlpha) * _HandAlpha;
// Final unlit color = "color * emission"
float3 finalColor = color * emission;
return float4(finalColor, alphaValue);