Skip to content

Instantly share code, notes, and snippets.

@JLChnToZ
Created October 27, 2024 16:57
Show Gist options
  • Save JLChnToZ/b6decb95afd57f3574c59bdc61f7a427 to your computer and use it in GitHub Desktop.
Save JLChnToZ/b6decb95afd57f3574c59bdc61f7a427 to your computer and use it in GitHub Desktop.
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Debuggers/AudioLinkLocator" {
Properties {
_Scale ("Distance", Range(0.0001, 10)) = 1
}
SubShader {
Tags {
"RenderType" = "Opaque"
"Queue" = "Overlay"
"IgnoreProjector" = "True"
}
LOD 100
Blend SrcAlpha OneMinusSrcAlpha
ZTest Always
Cull Off
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Packages/com.llealloo.audiolink/Runtime/Shaders/AudioLink.cginc"
#include "Packages/com.llealloo.audiolink/Runtime/Shaders/SmoothPixelFont.cginc"
struct appdata {
float4 vertex : POSITION;
float4 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f {
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
float _Scale;
int _VRChatMirrorMode;
float4x4 Object2Billboard(float4 origin, float distance) {
float3 z = normalize(origin - _WorldSpaceCameraPos);
float3 x = normalize(cross(float3(0, 1, 0), z));
float3 y = cross(z, x);
float4x4 m;
m._11_21_31 = x;
m._12_22_32 = y;
m._13_23_33 = z;
m._14_24_34 = _WorldSpaceCameraPos + z * distance;
m._41_42_43_44 = float4(0, 0, 0, 1);
return m;
}
float2 ddxy(float2 uv) {
return float2(ddx(uv.x), ddy(uv.y));
}
float printInfo(float2 uv) {
uv.y = 1 - uv.y;
const uint text[4 * 2] = {
'A', 'L', ' ', 'V',
'D', 'I', 'S', 'T',
};
float2 pos = uv * 32 + float2(-10, -18);
int2 index = (int2)floor(pos);
float2 softness = 2 / sqrt(length(ddxy(pos)));
float2 charUV = float2(4, 6) - (frac(pos) * float2(4, 6));
float result = 0;
if (index.x >= 0 && index.y >= 0 && index.y < 2) {
if (index.x < 4)
result = PrintChar(text[4 * index.y + index.x], charUV, softness, 0);
else
switch (index.y) {
case 0:
if (index.x < 7)
result += PrintNumberOnLine(AudioLinkGetVersionMajor(), charUV, softness, index.x - 4, 1, 2, false, 0);
else if (index.x < 11)
result += PrintNumberOnLine(AudioLinkGetVersionMinor(), charUV, softness, index.x - 5, 3, 2, true, 0);
break;
case 1:
float distance = length(AudioLinkGetAudioSourcePosition().xyz - _WorldSpaceCameraPos);
if (index.x < 12)
result += PrintNumberOnLine(distance, charUV, softness, index.x - 5, uint(floor(log(distance) / log(10)) + 2), 6, false, 0);
break;
}
}
return result;
}
v2f vert(appdata v) {
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
if (_VRChatMirrorMode == 0 && AudioLinkIsAvailable() && v.uv.z < 1) {
float4 worldPos = AudioLinkGetAudioSourcePosition();
o.vertex = mul(Object2Billboard(worldPos, 1 / _Scale), float4(v.uv.xy - 0.5, 0, 1));
o.vertex = mul(UNITY_MATRIX_VP, o.vertex);
#if UNITY_REVERSED_Z
o.vertex.z = max(o.vertex.z, 0.00001);
#else
o.vertex.z = min(o.vertex.z, 0.99999);
#endif
o.uv = v.uv.xy;
} else {
o.vertex = 0;
o.uv = 0;
}
return o;
}
half4 frag(v2f i) : SV_Target {
UNITY_SETUP_INSTANCE_ID(i);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
half4 col = 0;
float2 uv2 = i.uv * 2 - 1;
float distance = length(uv2);
if (distance < 1) {
float alDistance = distance * AUDIOLINK_WIDTH;
col += float4(1, 0, 0, 0) * AudioLinkLerp(ALPASS_AUDIOBASS + float2(alDistance, 0)).r;
col += float4(1, 1, 0, 0) * AudioLinkLerp(ALPASS_AUDIOLOWMIDS + float2(alDistance, 0)).r;
col += float4(0, 1, 1, 0) * AudioLinkLerp(ALPASS_AUDIOHIGHMIDS + float2(alDistance, 0)).r;
col += float4(0, 0, 1, 0) * AudioLinkLerp(ALPASS_AUDIOTREBLE + float2(alDistance, 0)).r;
col.rgb *= 2 * (1 - sqrt(distance));
col.a = saturate(length(col.rgb));
}
col = lerp(col, float4(0, 0, 0, 1), printInfo(i.uv + float2(-0.005, 0.005)) * 0.5);
col = lerp(col, 1, printInfo(i.uv));
clip(col.a - 0.01);
return col;
}
ENDCG
}
}
}
Shader "Debuggers/LTCGIDebugger" {
Properties { }
SubShader {
Tags {
"RenderType" = "Opaque"
"Queue" = "Overlay"
"IgnoreProjector" = "True"
}
LOD 100
Blend SrcAlpha OneMinusSrcAlpha
ZTest Always
Cull Off
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#define LTCGI_STATIC_TEXTURES
#define LTCGI_FAST_SAMPLING
#include "UnityCG.cginc"
#include "Packages/com.llealloo.audiolink/Runtime/Shaders/AudioLink.cginc"
#include "Packages/com.llealloo.audiolink/Runtime/Shaders/SmoothPixelFont.cginc"
#include "Packages/at.pimaker.ltcgi/Shaders/LTCGI.cginc"
struct appdata {
float4 vertex : POSITION;
float4 uv : TEXCOORD0; // XY: UV, Z: Screen Index, W: Quad Index
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f {
float4 vertex : SV_POSITION;
float2 ouv : TEXCOORD0;
float3 uv : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
int _VRChatMirrorMode;
#define lerp2d(lb, rb, lt, rt, uv) lerp(lerp(lb, rb, uv.x), lerp(lt, rt, uv.x), uv.y)
float blurstep(float t, float s, float e) {
return smoothstep(s - e, s + e, t);
}
float3 hue2rgb(float hue) {
return saturate(abs(frac(hue) * 6 - float3(3, 2, 4)) * float3(1, -1, -1) + float3(-1, 2, 2));
}
float trianglewave(float t) {
return abs(frac(t) * 2 - 1);
}
float2 ddxy(float2 uv) {
return float2(ddx(uv.x), ddy(uv.y));
}
float printInfo(float2 uv, ltcgi_flags flags) {
uv.y = 1 - uv.y;
const uint text[5 * 4] = {
'C', 'O', 'L', 'O', 'R',
'T', 'E', 'X', ' ', ' ',
'S', 'U', 'V', ' ', ' ',
'A', 'L', ' ', ' ', ' ',
};
float2 pos = uv * float2(16, 16);
uint2 index = (uint2)floor(pos);
float2 softness = 2 / sqrt(length(ddxy(pos)));
[branch] if (index.y > 0 || index.x >= 5) return 0;
float2 charUV = float2(4, 6) - (frac(pos) * float2(4, 6));
float result = PrintChar(text[5 * flags.colormode + index.x], charUV, softness, 0);
if (index.x >= 3)
switch (flags.colormode) {
case LTCGI_COLORMODE_TEXTURE:
if (index.x < 5) return result + PrintNumberOnLine(flags.texindex, charUV, softness, index.x - 3, 2, 0, true, 0);
break;
case LTCGI_COLORMODE_AUDIOLINK:
if (index.x < 4) return result + PrintNumberOnLine(flags.alBand, charUV, softness, index.x - 3, 1, 0, true, 0);
break;
}
return result;
}
v2f vert(appdata v) {
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
uint i = uint(v.uv.z);
[branch] if (i >= _Udon_LTCGI_ScreenCount || _Udon_LTCGI_Mask[i] || _VRChatMirrorMode != 0) {
o.vertex = 0;
o.ouv = 0;
o.uv = 0;
} else {
float4 extra = _Udon_LTCGI_ExtraData[i];
ltcgi_flags flags = ltcgi_parse_flags(asuint(extra.w), false);
bool isTri = false;
float3 Lw[4];
float4 uvStart = 0, uvEnd = 0;
LTCGI_GetLw(i, flags, _WorldSpaceCameraPos, Lw, uvStart, uvEnd, isTri);
o.ouv = v.uv.xy;
float4 worldPos = float4(lerp2d(Lw[0], Lw[1], Lw[2], Lw[3], o.ouv) + _WorldSpaceCameraPos, 1);
o.vertex = mul(UNITY_MATRIX_VP, worldPos);
#if UNITY_REVERSED_Z
o.vertex.z = max(o.vertex.z, 0.00001);
#else
o.vertex.z = min(o.vertex.z, 0.99999);
#endif
o.uv = float3(0, 0, v.uv.z);
switch (flags.colormode) {
case LTCGI_COLORMODE_TEXTURE: o.uv.xy = lerp2d(uvStart.xy, uvStart.zw, uvEnd.xy, uvEnd.zw, o.ouv); break;
case LTCGI_COLORMODE_SINGLEUV: o.uv.xy = uvStart.xy; break;
case LTCGI_COLORMODE_AUDIOLINK: o.uv.y = flags.alBand; break;
}
}
return o;
}
half4 frag(v2f i, bool isFrontFace : SV_IsFrontFace) : SV_Target {
UNITY_SETUP_INSTANCE_ID(i);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
float index = round(i.uv.z);
if (index < 0) discard;
float4 extra = _Udon_LTCGI_ExtraData[uint(index)];
ltcgi_flags flags = ltcgi_parse_flags(asuint(extra.w), false);
float4 col = 0;
float borders = step(frac(i.ouv.x + 0.015), 0.03) + step(frac(i.ouv.y + 0.015), 0.03);
[branch] if (flags.doublesided || !isFrontFace) {
switch (flags.colormode) {
case LTCGI_COLORMODE_STATIC: col.rgb = 1; break;
case LTCGI_COLORMODE_AUDIOLINK: col.rgb = AudioLinkData(round(i.uv.xy)).rrr; break;
default: LTCGI_sample(i.uv.xy, 0, flags.texindex, 0, col.rgb); break;
}
col.rgb *= extra.rgb;
col.rgb /= max(1, max(col.r, max(col.g, col.b))); // Prevent overbright
col.a = length(col.rgb);
borders += step(frac((i.ouv.x - i.ouv.y - _Time.x * 2) * 10), 0.3); // Diagonal lines
}
col = lerp(col, float4(hue2rgb(index * 0.3125), 1), saturate(borders) * lerp(0.25, 1, trianglewave(_Time.y * 0.75 + index * 0.1)));
col.a = saturate(col.a * 0.5);
// Print info
float2 uv2 = i.ouv.xy;
col = lerp(col, float4(0, 0, 0, 1), printInfo(uv2 + float2(-0.005, 0.005), flags) * 0.5);
col = lerp(col, 1, printInfo(uv2, flags));
clip(col.a - 0.01);
return col;
}
ENDCG
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment