float pingPong(float x, float lengthValue)
{
	float safeLength = max(lengthValue, 0.0001);
	float period = safeLength * 2.0;
	float wrapped = x - floor(x / period) * period;
	return wrapped <= safeLength ? wrapped : (period - wrapped);
}

float3 hsvToRgb(float3 hsv)
{
	float3 p = abs(frac(hsv.x + float3(0.0, 0.6666667, 0.3333333)) * 6.0 - 3.0);
	float3 rgb = saturate(p - 1.0);
	return hsv.z * lerp(float3(1.0, 1.0, 1.0), rgb, hsv.y);
}

float4 shadeVideo(ShaderContext context)
{
	float2 resolution = max(context.outputResolution, float2(1.0, 1.0));
	float minDimension = min(resolution.x, resolution.y);
	float logoAspect = 2.0;

	float safeScale = max(logoScale, 0.05);
	float2 logoHalfSize = float2(minDimension * safeScale, minDimension * safeScale / logoAspect);
	float2 paddingPx = float2(minDimension * max(edgePadding, 0.0), minDimension * max(edgePadding, 0.0));
	float2 minCenterPx = logoHalfSize + paddingPx;
	float2 maxCenterPx = resolution - logoHalfSize - paddingPx;
	float2 travelPx = max(maxCenterPx - minCenterPx, float2(1.0, 1.0));

	float2 velocityPx = float2(
		max(20.0, bounceSpeed * minDimension * 1.00),
		max(24.0, bounceSpeed * minDimension * 0.77));
	float seed = context.startupRandom;
	float2 motionPx = (float2(context.time, context.time) + float2(seed * 32.7, seed * 40.3)) * velocityPx;
	float2 centerPx = minCenterPx + float2(
		pingPong(motionPx.x, travelPx.x),
		pingPong(motionPx.y, travelPx.y));

	int xHits = int(floor(motionPx.x / max(travelPx.x, 1.0)));
	int yHits = int(floor(motionPx.y / max(travelPx.y, 1.0)));
	int totalHits = max(0, xHits + yHits);

	float hue = frac(0.09 + seed * 0.71 + float(totalHits) * 0.173);
	float3 badgeColor = hsvToRgb(float3(hue, 0.86, 1.0));
	float3 glowColor = hsvToRgb(float3(frac(hue + 0.06), 0.72, 1.0));

	float2 fragPx = context.uv * resolution;
	float2 logoMin = centerPx - logoHalfSize;
	float2 logoSize = logoHalfSize * 2.0;
	float2 logoUv = (fragPx - logoMin) / max(logoSize, float2(1.0, 1.0));
	float insideX = step(0.0, logoUv.x) * step(logoUv.x, 1.0);
	float insideY = step(0.0, logoUv.y) * step(logoUv.y, 1.0);
	float inside = insideX * insideY;

	float4 logoSample = dvdLogoTexture.Sample(logoUv);
	logoSample *= inside;

	float logoAlpha = logoSample.a;
	float logoLuma = dot(logoSample.rgb, float3(0.299, 0.587, 0.114));
	float3 tintedLogo = lerp(logoSample.rgb, badgeColor * max(logoLuma, 0.35), 0.88);

	float2 edgeDistancePx = min(logoUv, 1.0 - logoUv) * logoSize;
	float innerEdgePx = min(edgeDistancePx.x, edgeDistancePx.y);
	float rim = (1.0 - smoothstep(0.0, 5.0, innerEdgePx)) * logoAlpha;
	float glow = (1.0 - smoothstep(0.0, minDimension * 0.06, innerEdgePx + minDimension * 0.025)) * glowAmount * logoAlpha;

	float3 color = tintedLogo;
	color += glowColor * glow * 0.6;
	color = lerp(color, float3(1.0, 1.0, 1.0), rim * 0.32);

	float alpha = saturate(max(logoAlpha, glow * 0.5) * baseAlpha);
	float3 premultipliedColor = saturate(color) * alpha;
	return float4(premultipliedColor, alpha);
}
