Files
NixOS-configs/modules/wallpaper-engine/shaders/HLSL/dx11playlisttransition.vert
2025-04-29 13:39:02 -05:00

125 lines
3.8 KiB
GLSL

struct VS_INPUT
{
float3 a_Position : POSITION;
float2 a_TexCoord : TEXCOORD0;
#if FADEEFFECT == 23
float3 a_Center : TEXCOORD1;
float3 a_Normal : NORMAL;
#endif
};
struct VS_OUTPUT
{
float4 v_Position : SV_POSITION;
float2 v_TexCoord : TEXCOORD0;
#if FADEEFFECT == 23
float2 v_TexCoordBase : TEXCOORD1;
float3 v_WorldPos : TEXCOORD2;
float3 v_WorldNormal : TEXCOORD3;
#endif
};
cbuffer g_bufDynamic:register(b0)
{
const float g_Progress;
const float g_Hash;
const float g_Hash2;
const float g_Random;
const float g_AspectRatio;
const float g_Width;
const float g_Height;
const float4x4 g_ViewProjection;
const float4x4 g_ViewProjectionInv;
}
float nrand(float2 uv)
{
return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453);
}
float2 rotateFloat2(float2 v, float r)
{
float2 cs = float2(cos(r), sin(r));
return float2(v.x * cs.x - v.y * cs.y, v.x * cs.y + v.y * cs.x);
}
float4x4 rotation3d(float3 axis, float angle)
{
axis = normalize(axis);
float s = sin(angle);
float c = cos(angle);
float oc = 1.0 - c;
return float4x4(
oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0,
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0,
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0,
0.0, 0.0, 0.0, 1.0
);
}
VS_OUTPUT main(VS_INPUT IN)
{
VS_OUTPUT OUT;
OUT.v_Position = float4(IN.a_Position, 1.0);
OUT.v_TexCoord = IN.a_TexCoord;
#if FADEEFFECT == 23
// Glass shatter
float3 axis = float3(nrand(IN.a_Center * 247.0), nrand(IN.a_Center * 115.0), nrand(IN.a_Center * 531.0));
axis -= (float3)0.5;
axis = normalize(axis);
float centerDistance = saturate(length(IN.a_Center));
float animProgress = centerDistance * 0.05;
animProgress = pow(smoothstep(0.4, 0.8, g_Progress - animProgress), 0.5);
float3 center = IN.a_Center;
float3 position = IN.a_Position - center;
// Move them out of the center
center = center * (1.0 + saturate((g_Progress - 0.4) * (1.0 / 0.6)) * 4.0);
// Move pieaces up and down linearly
center.y += pow(saturate((g_Progress - 0.4) * 2.5), 0.5) * 2.0 + saturate((g_Progress - 0.4)) * -5.0;
// Apply creak offset
float creakTimer = smoothstep(0.0, 0.06, g_Progress) * 0.05 +
smoothstep(0.1, 0.14, g_Progress) * 0.08 +
smoothstep(0.3, 0.36, g_Progress) * 0.15;
float creakAmt = max(abs(IN.a_TexCoord.x - 0.5), abs(IN.a_TexCoord.y - 0.5)) * 0.5;
float creakSmooth = 0.1;
creakAmt = smoothstep(creakAmt, creakAmt + creakSmooth, creakTimer);
float creakRand = nrand(position.xy * 100);
float2 creakOffset = float2(0.02 / g_AspectRatio, 0.02) * (0.5 + creakRand * 1.0);
position.xy *= lerp(1.0, max(step(IN.a_Position.z, -0.0001), 1.0 - creakOffset), creakAmt);
float4x4 anim = rotation3d(axis, animProgress * g_Progress * 10.0);
float4x4 animLight = rotation3d(axis, animProgress * g_Progress * 10.0 + creakAmt * 0.25);
position = mul(float4(position, 0.0), anim).xyz;
position += center;
float3 worldSpaceNormal = mul(float4(IN.a_Normal, 0.0), animLight).xyz;
float4 screenSpaceNormal = mul(float4(worldSpaceNormal, 0.0), g_ViewProjection);
screenSpaceNormal.xyz = normalize(screenSpaceNormal.xyz);
OUT.v_TexCoordBase = OUT.v_TexCoord;
OUT.v_TexCoord.x -= screenSpaceNormal.x * 0.1;
OUT.v_TexCoord.y -= screenSpaceNormal.y * 0.1;
OUT.v_TexCoordBase = lerp(OUT.v_TexCoord, OUT.v_TexCoordBase, 0.1);
OUT.v_Position = mul(float4(position, 1.0), g_ViewProjection);
OUT.v_WorldPos = position;
OUT.v_WorldNormal = worldSpaceNormal;
#endif
return OUT;
}