Initial audio support
This commit is contained in:
76
shaders/audio-vu-meter/shader.json
Normal file
76
shaders/audio-vu-meter/shader.json
Normal file
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"id": "audio-vu-meter",
|
||||
"name": "Audio VU Meter",
|
||||
"description": "Draws stereo audio level meters from the runtime audio analysis data.",
|
||||
"category": "Utility",
|
||||
"entryPoint": "shadeVideo",
|
||||
"parameters": [
|
||||
{
|
||||
"id": "meterPosition",
|
||||
"label": "Position",
|
||||
"type": "vec2",
|
||||
"default": [0.08, 0.82],
|
||||
"min": [0.0, 0.0],
|
||||
"max": [1.0, 1.0],
|
||||
"step": [0.01, 0.01]
|
||||
},
|
||||
{
|
||||
"id": "meterScale",
|
||||
"label": "Scale",
|
||||
"type": "float",
|
||||
"default": 0.35,
|
||||
"min": 0.1,
|
||||
"max": 1.0,
|
||||
"step": 0.01
|
||||
},
|
||||
{
|
||||
"id": "meterOpacity",
|
||||
"label": "Opacity",
|
||||
"type": "float",
|
||||
"default": 0.9,
|
||||
"min": 0.0,
|
||||
"max": 1.0,
|
||||
"step": 0.01
|
||||
},
|
||||
{
|
||||
"id": "noiseGate",
|
||||
"label": "Noise Gate",
|
||||
"type": "float",
|
||||
"default": 0.03,
|
||||
"min": 0.0,
|
||||
"max": 0.5,
|
||||
"step": 0.01
|
||||
},
|
||||
{
|
||||
"id": "meterColor",
|
||||
"label": "Meter Color",
|
||||
"type": "color",
|
||||
"default": [0.2, 1.0, 0.55, 1.0]
|
||||
},
|
||||
{
|
||||
"id": "peakColor",
|
||||
"label": "Peak Color",
|
||||
"type": "color",
|
||||
"default": [1.0, 0.85, 0.2, 1.0]
|
||||
},
|
||||
{
|
||||
"id": "backgroundOpacity",
|
||||
"label": "Background",
|
||||
"type": "float",
|
||||
"default": 0.45,
|
||||
"min": 0.0,
|
||||
"max": 1.0,
|
||||
"step": 0.01
|
||||
},
|
||||
{
|
||||
"id": "orientation",
|
||||
"label": "Orientation",
|
||||
"type": "enum",
|
||||
"default": "horizontal",
|
||||
"options": [
|
||||
{ "value": "horizontal", "label": "Horizontal" },
|
||||
{ "value": "vertical", "label": "Vertical" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
59
shaders/audio-vu-meter/shader.slang
Normal file
59
shaders/audio-vu-meter/shader.slang
Normal file
@@ -0,0 +1,59 @@
|
||||
float rectMask(float2 uv, float2 minUv, float2 maxUv)
|
||||
{
|
||||
float2 insideMin = step(minUv, uv);
|
||||
float2 insideMax = step(uv, maxUv);
|
||||
return insideMin.x * insideMin.y * insideMax.x * insideMax.y;
|
||||
}
|
||||
|
||||
float denoiseLevel(float value)
|
||||
{
|
||||
float gate = saturate(noiseGate);
|
||||
float clean = saturate((value - gate) / max(1.0 - gate, 0.001));
|
||||
return smoothstep(0.0, 1.0, clean);
|
||||
}
|
||||
|
||||
float4 shadeVideo(ShaderContext context)
|
||||
{
|
||||
float4 color = context.sourceColor;
|
||||
float2 size = orientation == 0 ? float2(meterScale, meterScale * 0.18) : float2(meterScale * 0.18, meterScale);
|
||||
float2 minUv = clamp(meterPosition, 0.0, 1.0 - size);
|
||||
float2 local = (context.uv - minUv) / max(size, float2(0.001));
|
||||
float inside = rectMask(local, float2(0.0), float2(1.0));
|
||||
if (inside <= 0.0)
|
||||
return color;
|
||||
|
||||
float3 bg = lerp(color.rgb, float3(0.0), saturate(backgroundOpacity));
|
||||
float leftLevel = denoiseLevel(context.audioRms.x * 2.4);
|
||||
float rightLevel = denoiseLevel(context.audioRms.y * 2.4);
|
||||
float leftPeak = denoiseLevel(context.audioPeak.x);
|
||||
float rightPeak = denoiseLevel(context.audioPeak.y);
|
||||
|
||||
float bar = 0.0;
|
||||
float peak = 0.0;
|
||||
if (orientation == 0)
|
||||
{
|
||||
float leftRow = rectMask(local, float2(0.04, 0.58), float2(0.96, 0.86));
|
||||
float rightRow = rectMask(local, float2(0.04, 0.14), float2(0.96, 0.42));
|
||||
float leftFill = rectMask(local, float2(0.04, 0.58), float2(0.04 + 0.92 * leftLevel, 0.86));
|
||||
float rightFill = rectMask(local, float2(0.04, 0.14), float2(0.04 + 0.92 * rightLevel, 0.42));
|
||||
float leftPeakLine = rectMask(local, float2(0.04 + 0.92 * leftPeak - 0.006, 0.55), float2(0.04 + 0.92 * leftPeak + 0.006, 0.89));
|
||||
float rightPeakLine = rectMask(local, float2(0.04 + 0.92 * rightPeak - 0.006, 0.11), float2(0.04 + 0.92 * rightPeak + 0.006, 0.45));
|
||||
bar = max(leftFill, rightFill);
|
||||
peak = max(leftPeakLine * leftRow, rightPeakLine * rightRow);
|
||||
}
|
||||
else
|
||||
{
|
||||
float leftColumn = rectMask(local, float2(0.14, 0.04), float2(0.42, 0.96));
|
||||
float rightColumn = rectMask(local, float2(0.58, 0.04), float2(0.86, 0.96));
|
||||
float leftFill = rectMask(local, float2(0.14, 0.04), float2(0.42, 0.04 + 0.92 * leftLevel));
|
||||
float rightFill = rectMask(local, float2(0.58, 0.04), float2(0.86, 0.04 + 0.92 * rightLevel));
|
||||
float leftPeakLine = rectMask(local, float2(0.11, 0.04 + 0.92 * leftPeak - 0.006), float2(0.45, 0.04 + 0.92 * leftPeak + 0.006));
|
||||
float rightPeakLine = rectMask(local, float2(0.55, 0.04 + 0.92 * rightPeak - 0.006), float2(0.89, 0.04 + 0.92 * rightPeak + 0.006));
|
||||
bar = max(leftFill * leftColumn, rightFill * rightColumn);
|
||||
peak = max(leftPeakLine, rightPeakLine);
|
||||
}
|
||||
|
||||
float3 metered = lerp(bg, meterColor.rgb, bar * saturate(meterOpacity) * meterColor.a);
|
||||
metered = lerp(metered, peakColor.rgb, peak * saturate(meterOpacity) * peakColor.a);
|
||||
return float4(metered, color.a);
|
||||
}
|
||||
Reference in New Issue
Block a user