Files
Shopping_UnityVR/Assets/HighlightPlus/Runtime/Resources/HighlightPlus/HighlightOverlay.shader

280 lines
12 KiB
Plaintext

Shader "HighlightPlus/Geometry/Overlay" {
Properties {
_MainTex ("Texture", Any) = "white" {}
_Color ("Color", Color) = (1,1,1) // not used; dummy property to avoid inspector warning "material has no _Color property"
_OverlayColor ("Overlay Color", Color) = (1,1,1,1)
_OverlayBackColor ("Overlay Back Color", Color) = (1,1,1,1)
_OverlayData("Overlay Data", Vector) = (1,0.5,1,1)
_OverlayHitPosData("Overlay Hit Pos Data", Vector) = (0,0,0,0)
_OverlayHitStartTime("Overlay Hit Start Time", Float) = 0
_OverlayTexture("Overlay Texture", 2D) = "white" {}
_CutOff("CutOff", Float ) = 0.5
_Cull ("Cull Mode", Int) = 2
_OverlayZTest("ZTest", Int) = 4
_OverlayPatternScrolling("Pattern Scrolling", Vector) = (0,0,0,0)
_OverlayPatternData("Pattern Data", Vector) = (0,0,0,0)
_OverlayBlendDst("Overlay Blend Dst", Int) = 10
}
SubShader
{
Tags { "Queue"="Transparent+121" "RenderType"="Transparent" "DisableBatching"="True" }
// Overlay
Pass
{
Name "Overlay"
Stencil {
Ref 4
ReadMask 4
Comp NotEqual
Pass keep
}
Blend SrcAlpha [_OverlayBlendDst]
ZWrite Off
Cull [_Cull]
Offset -1, -1 // avoid issues on Quest 2 standalone when using with other render features (ie. Liquid Volume Pro 2 irregular topology)
ZTest [_OverlayZTest]
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_local _ HP_ALPHACLIP
#pragma multi_compile_local _ HP_TEXTURE_TRIPLANAR HP_TEXTURE_TRIPLANAR_LOCAL HP_TEXTURE_SCREENSPACE HP_TEXTURE_OBJECTSPACE
#pragma multi_compile_local _ HP_PATTERN_POLKADOTS HP_PATTERN_GRID HP_PATTERN_STAGGERED_LINES HP_PATTERN_ZIGZAG
#include "UnityCG.cginc"
#include "CustomVertexTransform.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 norm : NORMAL;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 wpos : TEXCOORD1;
#if HP_TEXTURE_TRIPLANAR
float3 wnorm : TEXCOORD2;
#elif HP_TEXTURE_TRIPLANAR_LOCAL
float3 lnorm : TEXCOORD2;
float3 lpos : TEXCOORD4;
#endif
#if HP_TEXTURE_SCREENSPACE
float4 scrPos : TEXCOORD3;
#endif
UNITY_VERTEX_OUTPUT_STEREO
};
fixed4 _OverlayColor;
sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _OverlayBackColor;
fixed4 _OverlayData; // x = speed, y = MinIntensity, z = blend, w = texture scale
float4 _OverlayHitPosData;
float _OverlayHitStartTime;
fixed _CutOff;
sampler2D _OverlayTexture;
float2 _OverlayTextureScrolling;
float2 _OverlayPatternScrolling;
float4 _OverlayPatternData;
#define PATTERN_SCALE (_OverlayPatternData.x)
#define PATTERN_SIZE (_OverlayPatternData.y)
#define PATTERN_SOFTNESS (_OverlayPatternData.z)
#define PATTERN_ROTATION (_OverlayPatternData.w)
v2f vert (appdata v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_OUTPUT(v2f, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.pos = ComputeVertexPosition(v.vertex);
#if HP_TEXTURE_SCREENSPACE
o.scrPos = ComputeScreenPos(o.pos);
o.scrPos.x *= _ScreenParams.x / _ScreenParams.y;
#endif
o.wpos = mul(unity_ObjectToWorld, v.vertex).xyz;
#if HP_TEXTURE_TRIPLANAR
o.wnorm = UnityObjectToWorldNormal(v.norm);
#elif HP_TEXTURE_TRIPLANAR_LOCAL
o.lpos = v.vertex.xyz;
o.lnorm = v.norm;
#endif
o.uv = TRANSFORM_TEX (v.uv, _MainTex);
return o;
}
// Helper to rotate UVs by angle in degrees
float2 rotateUV(float2 uv, float angleDeg) {
float angleRad = radians(angleDeg);
float s = sin(angleRad);
float c = cos(angleRad);
float2 center = float2(0.5, 0.5);
uv -= center;
float2 rotated = float2(
uv.x * c - uv.y * s,
uv.x * s + uv.y * c
);
return rotated + center;
}
// Function to create antialiased polka dot pattern
float polkaDotPattern(float2 uv) {
float2 scrolledUV = uv + _OverlayPatternScrolling * _Time.y;
float2 rotatedUV = rotateUV(scrolledUV, PATTERN_ROTATION);
float2 localUV = rotatedUV;
// Offset every other row
localUV.x += 0.5 / PATTERN_SCALE * (floor(rotatedUV.y * PATTERN_SCALE) % 2.0);
float2 scaledUV = localUV * PATTERN_SCALE;
float2 gridPos = frac(scaledUV) - 0.5;
float dist = length(gridPos);
float alpha = smoothstep(PATTERN_SIZE + PATTERN_SOFTNESS, PATTERN_SIZE - PATTERN_SOFTNESS, dist);
return saturate(alpha);
}
// Function to create antialiased grid pattern
float gridPattern(float2 uv) {
float2 scrolledUV = uv + _OverlayPatternScrolling * _Time.y;
float2 rotatedUV = rotateUV(scrolledUV, PATTERN_ROTATION);
float2 scaledUV = rotatedUV * PATTERN_SCALE;
float2 grid = abs(frac(scaledUV) - 0.5);
float lin = min(grid.x, grid.y);
float alpha = smoothstep(PATTERN_SIZE + PATTERN_SOFTNESS, PATTERN_SIZE - PATTERN_SOFTNESS, lin);
return saturate(alpha);
}
// Function to create antialiased staggered horizontal dashed lines
float staggeredLinePattern(float2 uv) {
float2 scrolledUV = uv + _OverlayPatternScrolling * _Time.y;
float2 rotatedUV = rotateUV(scrolledUV, PATTERN_ROTATION);
float2 scaledUV = rotatedUV * PATTERN_SCALE;
// Row index for staggering the dash pattern
float row = floor(scaledUV.y);
float dashOffset = (row % 2.0) * 0.5; // Stagger by half a pattern period along X
float staggeredX = scaledUV.x + dashOffset;
// Calculate visibility for the horizontal line itself.
// Thickness is controlled by PATTERN_SIZE.
// hline_alpha = 1 if on the line, 0 if in the gap between lines.
float hline_alpha = smoothstep(PATTERN_SIZE + PATTERN_SOFTNESS, PATTERN_SIZE - PATTERN_SOFTNESS, abs(frac(scaledUV.y) - 0.5));
// Calculate visibility for the dash segments along the X-axis.
// Let's use a fixed 50% duty cycle for dashes (dash length = gap length).
// For a 50% duty cycle, the effective "size" parameter for the dash segment is 0.25.
// (because abs(frac(X)-0.5) goes from 0 to 0.5; visible for 0 to 0.25 means 0.25*2=0.5 of the period).
float dash_segment_parameter = 0.25;
float dash_alpha = smoothstep(dash_segment_parameter + PATTERN_SOFTNESS, dash_segment_parameter - PATTERN_SOFTNESS, abs(frac(staggeredX) - 0.5));
// Final alpha: The pixel is visible if it's on a horizontal line AND on a dash segment of that line.
float final_alpha = hline_alpha * dash_alpha;
return saturate(final_alpha);
}
// Function to create antialiased zigzag pattern
float zigZagPattern(float2 uv) {
float2 scrolledUV = uv + _OverlayPatternScrolling * _Time.y;
float2 rotatedUV = rotateUV(scrolledUV, PATTERN_ROTATION);
float2 scaledUV = rotatedUV * PATTERN_SCALE;
// y_center_norm is a triangle wave ^ shape, ranging from 0 to 1, based on scaledUV.x
// It represents the normalized y-coordinate of the zigzag centerline within a vertical cell.
float y_center_norm = abs(frac(scaledUV.x) - 0.5) * 2.0;
// y_pixel_norm is the normalized y-coordinate of the current pixel within a vertical cell.
float y_pixel_norm = frac(scaledUV.y);
// dist is the vertical distance from the pixel's normalized y to the zigzag centerline's normalized y.
float dist = abs(y_pixel_norm - y_center_norm);
// PATTERN_SIZE defines half the thickness of the line in normalized cell coordinates.
// Alpha is 1 if dist is small (within PATTERN_SIZE), 0 if dist is large.
float alpha = smoothstep(PATTERN_SIZE + PATTERN_SOFTNESS, PATTERN_SIZE - PATTERN_SOFTNESS, dist);
return saturate(alpha);
}
fixed4 SampleOverlayTexture(float2 uv) {
float2 uvOffset = _OverlayTextureScrolling * _Time.y;
fixed4 tex = tex2D(_OverlayTexture, uv * _OverlayData.w + uvOffset);
#if HP_PATTERN_POLKADOTS
tex.a *= polkaDotPattern(uv);
#endif
#if HP_PATTERN_GRID
tex.a *= gridPattern(uv);
#endif
#if HP_PATTERN_STAGGERED_LINES
tex.a *= staggeredLinePattern(uv);
#endif
#if HP_PATTERN_ZIGZAG
tex.a *= zigZagPattern(uv);
#endif
return tex;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 color = tex2D(_MainTex, i.uv);
#if HP_ALPHACLIP
clip(color.a - _CutOff);
#endif
float time = _Time.y % 1000;
fixed t = _OverlayData.y + (1.0 - _OverlayData.y) * 2.0 * abs(0.5 - frac(time * _OverlayData.x));
fixed4 col = lerp(_OverlayColor, color * _OverlayBackColor * _OverlayColor, _OverlayData.z);
col.a *= t;
if (_OverlayHitPosData.w>0) {
float elapsed = _Time.y - _OverlayHitStartTime;
float hitDist = distance(i.wpos, _OverlayHitPosData.xyz);
float atten = saturate( min(elapsed, _OverlayHitPosData.w) / hitDist );
col.a *= atten;
}
#if HP_TEXTURE_TRIPLANAR
half3 triblend = saturate(pow(i.wnorm, 4));
triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);
// triplanar uvs
float3 tpos = i.wpos;
float2 uvX = tpos.zy;
float2 uvY = tpos.xz;
float2 uvZ = tpos.xy;
// albedo textures
fixed4 colX = SampleOverlayTexture(uvX);
fixed4 colY = SampleOverlayTexture(uvY);
fixed4 colZ = SampleOverlayTexture(uvZ);
fixed4 tex = colX * triblend.x + colY * triblend.y + colZ * triblend.z;
col *= tex;
#elif HP_TEXTURE_TRIPLANAR_LOCAL
half3 triblend = saturate(pow(i.lnorm, 4));
triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);
float3 tpos = i.lpos;
float2 uvX = tpos.zy;
float2 uvY = tpos.xz;
float2 uvZ = tpos.xy;
fixed4 colX = SampleOverlayTexture(uvX);
fixed4 colY = SampleOverlayTexture(uvY);
fixed4 colZ = SampleOverlayTexture(uvZ);
fixed4 tex = colX * triblend.x + colY * triblend.y + colZ * triblend.z;
col *= tex;
#elif HP_TEXTURE_SCREENSPACE
col *= SampleOverlayTexture(i.scrPos.xy / i.scrPos.w);
#elif HP_TEXTURE_OBJECTSPACE
col *= SampleOverlayTexture(i.uv);
#endif
return col;
}
ENDCG
}
}
}