Files
ichni_Creator_Studio/Assets/ThemeBundles/DepartureToMultiverse/Shaders/DTM_RandomGridTube.shader
SoulliesOfficial c727ebbd71 Bug fixes
2026-04-02 08:58:00 -04:00

240 lines
9.4 KiB
GLSL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Shader "Soullies/DTM_RandomGridTube"
{
Properties
{
[HDR]_Color0("Color0", Color) = (1, 1, 1, 0)
[Header(Pattern Settings)]
_PatternSize("Pattern Size (X, Y)", Vector) = (2.0, 2.0, 0, 0)
_GridDensity("Grid Density (Quantity Multiplier)", Float) = 1.0
_TimeAngle("Time Angle (Speed)", Float) = 1.0
[Header(Edge Settings)]
_StepA("Step A", Range(0, 1)) = 0.293
_StepB("Step B", Range(0, 1)) = 0.345
[Header(Seam Hiding)]
_SeamRotation("Seam Angle Offset", Range(-180, 180)) = -90.0
_SeamFadeWidth("Seam Cut Width", Range(0.0, 1.0)) = 0.2
_SeamFadeSmoothness("Seam Softness", Range(0.0, 1.0)) = 1.0
[Header(Tube Specific Settings)]
_FadeFar("Fade Far (Fully Transparent)", Float) = 100.0
_FadeNear("Fade Near (Fully Opaque)", Float) = 20.0
_TubeRadius("Virtual Tube Radius", Float) = 10.0
[Header(Render State)]
[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend("Src Blend", Float) = 5 // SrcAlpha
[Enum(UnityEngine.Rendering.BlendMode)] _DstBlend("Dst Blend", Float) = 10 // OneMinusSrcAlpha
[Enum(Off, 0, On, 1)] _ZWrite("Z Write", Float) = 0
[Enum(Front, 0, Back, 1, Off, 2)] _CullMode("Cull Mode", Float) = 1 // Front (Inside)
}
SubShader
{
Tags
{
"RenderPipeline" = "UniversalPipeline"
"RenderType" = "Transparent"
"Queue" = "Transparent-300"
"UniversalMaterialType" = "Unlit"
"IgnoreProjector" = "True"
}
Blend [_SrcBlend] [_DstBlend]
ZWrite [_ZWrite]
Cull [_CullMode] // Default Cull Front to see inside the tube
Pass
{
Name "ForwardOnly"
Tags { "LightMode" = "UniversalForwardOnly" }
HLSLPROGRAM
#pragma target 4.5
#pragma prefer_hlslcc gles
#pragma multi_compile_instancing
#pragma multi_compile_fog
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float3 positionWS : TEXCOORD0;
float3 positionOS : TEXCOORD1;
half fogFactor : TEXCOORD3;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
CBUFFER_START(UnityPerMaterial)
half4 _Color0;
float4 _PatternSize;
float _GridDensity;
float _TimeAngle;
float _StepA;
float _StepB;
float _SeamRotation;
float _SeamFadeWidth;
float _SeamFadeSmoothness;
float _FadeFar;
float _FadeNear;
float _TubeRadius;
CBUFFER_END
// -------------------------------------
// Custom Helper Functions
float2 VoronoiHash(float2 p)
{
p = float2(dot(p, float2(127.1, 311.7)), dot(p, float2(269.5, 183.3)));
return frac(sin(p) * 43758.5453);
}
// Manhattan-based Voronoi optimized for Mobile URP
float VoronoiDistance(float2 v, float t)
{
float2 n = floor(v);
float2 f = frac(v);
float minDist = 8.0;
UNITY_UNROLL
for (int j = -1; j <= 1; j++)
{
UNITY_UNROLL
for (int i = -1; i <= 1; i++)
{
float2 g = float2((float)i, (float)j);
float2 o = VoronoiHash(n + g);
// Oscillating movement
o = sin(t + o * 6.2831853) * 0.5 + 0.5;
float2 r = f - g - o;
// Manhattan distance for rectangular frames
float d = 0.5 * (abs(r.x) + abs(r.y));
minDist = min(minDist, d);
}
}
return minDist;
}
// -------------------------------------
// Vertex Shader
Varyings vert(Attributes input)
{
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
output.positionCS = vertexInput.positionCS;
output.positionWS = vertexInput.positionWS;
output.positionOS = input.positionOS.xyz;
output.fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
return output;
}
// -------------------------------------
// Fragment Shader
half4 frag(Varyings input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
// ==========================================
// 1. Cylindrical Mapping & Seam Control
// ==========================================
// Calculate angle around the Z-axis in object space. atan2 returns [-PI, PI].
float rawAngle = atan2(input.positionOS.y, input.positionOS.x);
// Rotate the seam mechanically
float angleOffset = _SeamRotation * (3.14159265 / 180.0);
float angle = rawAngle + angleOffset;
// Wrap angle to [-PI, PI] to keep math bounded
if(angle > 3.14159265) angle -= 6.2831853;
if(angle < -3.14159265) angle += 6.2831853;
// Derive distance to the seam (seam is at absolute PI or -PI)
float distToSeam = 3.14159265 - abs(angle);
// Seam alpha fading calculation
float endFade = _SeamFadeWidth * 3.14159265;
float startFade = endFade * (1.0 - _SeamFadeSmoothness);
float seamFadeMask = smoothstep(startFade, endFade + 0.0001, distToSeam);
// Convert adjusted angle to U coordinate
float u = angle * _TubeRadius;
// V is driven by World Z to maintain seamless tiling
// 1. 获取管道局部Z轴在世界空间中的单位方向向量
float3 tubeForwardWS = TransformObjectToWorldDir(float3(0, 0, 1));
// 2. 将世界坐标投影到管道的正前方,替代原本写死的 World Z
// 这样无论管道怎么旋转V轴永远沿着管道的长度方向进行世界坐标级别的无缝平铺
float v = dot(input.positionWS, tubeForwardWS);
float2 cylindricalUV = float2(u, v);
// Density Multiplier
float density = max(_GridDensity, 0.0001);
float2 sizeDivisor = max(_PatternSize.xy, float2(0.0001, 0.0001)) / density;
float2 scaledUV = cylindricalUV / sizeDivisor;
// Rotate 45 degrees
float c = 0.707106;
float s = 0.707106;
float2 rotatedUV = mul(scaledUV, float2x2(c, -s, s, c));
// Time driven animation
float t = _TimeAngle * _TimeParameters.x;
// Voronoi mathematical noise
float voronoiV = VoronoiDistance(rotatedUV, t);
// Anti-aliased border mask computation
float fw = fwidth(voronoiV);
float edge1 = smoothstep(_StepA - fw, _StepA + fw, voronoiV);
float edge2 = smoothstep(_StepB - fw, _StepB + fw, voronoiV);
float gridAlphaMask = edge2 - edge1;
half3 gridColor = _Color0.rgb;
half gridAlpha = gridAlphaMask * _Color0.a;
// ==========================================
// 2. Distance Fade (Far = Transparent, Near = Opaque)
// ==========================================
float distToCam = distance(GetCameraPositionWS(), input.positionWS);
// If distToCam is between _FadeFar and _FadeNear, smoothly transition
// When dist = _FadeFar, fadeMask = 0 (Transparent)
// When dist = _FadeNear, fadeMask = 1 (Opaque)
float rawFade = (distToCam - _FadeFar) / (_FadeNear - _FadeFar + 0.0001);
float fadeMask = saturate(rawFade);
// Multiply the alpha by our camera distance fade AND seam smooth fade
gridAlpha *= fadeMask * seamFadeMask;
// Apply URP Fog
gridColor = MixFog(gridColor, input.fogFactor);
return half4(gridColor, gridAlpha);
}
ENDHLSL
}
}
FallBack "Hidden/Universal Render Pipeline/FallbackError"
}