Skip to content

Instantly share code, notes, and snippets.

@phi16
Last active January 21, 2024 15:32
Show Gist options
  • Save phi16/1f57eaeb317481b1500ff46dd618e2f4 to your computer and use it in GitHub Desktop.
Save phi16/1f57eaeb317481b1500ff46dd618e2f4 to your computer and use it in GitHub Desktop.
Wire
Shader "phi16/Wire"
{
Properties
{
}
SubShader
{
Tags { "RenderType"="Transparent" "Queue"="Transparent" }
LOD 100
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
// InputMesh: Cylinder (Y axis), radius = 0.5 (or any), y in [-0.5, 0.5]
void spline(float4 a, float4 b, float4 c, float4 d, float t, out float3 position, out float3 tangent, out float3 normal) {
float4x4 m = float4x4(a, b, c, d);
// Catmull-Rom Spline
float4x4 spline = float4x4(
-1, 3, -3, 1,
2, -5, 4, -1,
-1, 0, 1, 0,
0, 2, 0, 0
) / 2.0;
m = mul(spline, m);
float t2 = t * t;
position = mul(float4(t2*t, t2, t, 1), m);
// Frenet frame
tangent = normalize(mul(float4(3*t2, 2*t, 1, 0), m));
normal = mul(float4(6*t, 2, 0, 0), m);
normal = normalize(normal - dot(normal, tangent) * tangent);
}
void vertexTransform(inout float3 pos, inout float3 normal, out float3 tangent) {
float y = pos.y;
pos.y = 0;
pos.xz *= 0.1;
float3 p, t, n, b;
spline(float4(-5,0,0,0), float4(0,0,0,0), float4(0,1,0,0), float4(0,0,5,0), y+0.5, p, t, n);
b = cross(t, n);
float3x3 m = transpose(float3x3(b, t, n));
pos = p + mul(m, pos);
normal = mul(m, normal);
tangent = t;
}
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
float4 vertex : SV_POSITION;
float3 worldPos : TEXCOORD1;
float3 worldNormal : TEXCOORD2;
float3 worldTangent : TEXCOORD3;
};
v2f vert (appdata v)
{
float3 tangent;
vertexTransform(v.vertex.xyz, v.normal.xyz, tangent);
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.worldPos = mul(UNITY_MATRIX_M, v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldTangent = UnityObjectToWorldNormal(tangent);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
float3 viewDir = normalize(i.worldPos - _WorldSpaceCameraPos);
float3 proj = normalize(viewDir - dot(viewDir, i.worldTangent) * i.worldTangent);
float h = saturate(- dot(proj, i.worldNormal));
return float4(1,1,1,lerp(0.1, 1, smoothstep(0.8, 0.2, h)));
}
ENDCG
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment