osc multi arguments
This commit is contained in:
63
shaders/composition-guides/shader.json
Normal file
63
shaders/composition-guides/shader.json
Normal file
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"id": "composition-guides",
|
||||
"name": "Composition Guides",
|
||||
"description": "Overlays rule-of-thirds guides and a center crosshair for camera alignment and framing.",
|
||||
"category": "Utility",
|
||||
"entryPoint": "shadeVideo",
|
||||
"parameters": [
|
||||
{
|
||||
"id": "showThirds",
|
||||
"label": "Rule of Thirds",
|
||||
"type": "bool",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"id": "showCrosshair",
|
||||
"label": "Center Crosshair",
|
||||
"type": "bool",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"id": "lineColor",
|
||||
"label": "Line Color",
|
||||
"type": "color",
|
||||
"default": [1.0, 1.0, 1.0, 1.0]
|
||||
},
|
||||
{
|
||||
"id": "lineOpacity",
|
||||
"label": "Line Opacity",
|
||||
"type": "float",
|
||||
"default": 0.65,
|
||||
"min": 0.0,
|
||||
"max": 1.0,
|
||||
"step": 0.01
|
||||
},
|
||||
{
|
||||
"id": "lineThicknessPixels",
|
||||
"label": "Line Thickness",
|
||||
"type": "float",
|
||||
"default": 2.0,
|
||||
"min": 0.5,
|
||||
"max": 12.0,
|
||||
"step": 0.1
|
||||
},
|
||||
{
|
||||
"id": "crosshairSizePixels",
|
||||
"label": "Crosshair Size",
|
||||
"type": "float",
|
||||
"default": 54.0,
|
||||
"min": 8.0,
|
||||
"max": 240.0,
|
||||
"step": 1.0
|
||||
},
|
||||
{
|
||||
"id": "crosshairGapPixels",
|
||||
"label": "Crosshair Gap",
|
||||
"type": "float",
|
||||
"default": 10.0,
|
||||
"min": 0.0,
|
||||
"max": 80.0,
|
||||
"step": 1.0
|
||||
}
|
||||
]
|
||||
}
|
||||
48
shaders/composition-guides/shader.slang
Normal file
48
shaders/composition-guides/shader.slang
Normal file
@@ -0,0 +1,48 @@
|
||||
float lineMask(float coordinate, float target, float pixelThickness, float resolution)
|
||||
{
|
||||
float halfWidth = max(pixelThickness, 0.5) * 0.5 / max(resolution, 1.0);
|
||||
float distanceToLine = abs(coordinate - target);
|
||||
float feather = halfWidth * 0.85 + (1.0 / max(resolution, 1.0));
|
||||
return 1.0 - smoothstep(halfWidth, feather, distanceToLine);
|
||||
}
|
||||
|
||||
float thirdsMask(float2 uv, float2 resolution)
|
||||
{
|
||||
float thickness = max(lineThicknessPixels, 0.5);
|
||||
float mask = 0.0;
|
||||
mask = max(mask, lineMask(uv.x, 1.0 / 3.0, thickness, resolution.x));
|
||||
mask = max(mask, lineMask(uv.x, 2.0 / 3.0, thickness, resolution.x));
|
||||
mask = max(mask, lineMask(uv.y, 1.0 / 3.0, thickness, resolution.y));
|
||||
mask = max(mask, lineMask(uv.y, 2.0 / 3.0, thickness, resolution.y));
|
||||
return mask;
|
||||
}
|
||||
|
||||
float crosshairMask(float2 uv, float2 resolution)
|
||||
{
|
||||
float2 pixel = (uv - 0.5) * resolution;
|
||||
float halfThickness = max(lineThicknessPixels, 0.5) * 0.5;
|
||||
float halfSize = max(crosshairSizePixels, 1.0) * 0.5;
|
||||
float halfGap = max(crosshairGapPixels, 0.0) * 0.5;
|
||||
|
||||
float horizontalExtent = step(abs(pixel.x), halfSize) * (1.0 - step(abs(pixel.x), halfGap));
|
||||
float verticalExtent = step(abs(pixel.y), halfSize) * (1.0 - step(abs(pixel.y), halfGap));
|
||||
|
||||
float horizontalLine = horizontalExtent * (1.0 - smoothstep(halfThickness, halfThickness + 1.5, abs(pixel.y)));
|
||||
float verticalLine = verticalExtent * (1.0 - smoothstep(halfThickness, halfThickness + 1.5, abs(pixel.x)));
|
||||
return max(horizontalLine, verticalLine);
|
||||
}
|
||||
|
||||
float4 shadeVideo(ShaderContext context)
|
||||
{
|
||||
float2 resolution = max(context.outputResolution, float2(1.0, 1.0));
|
||||
float mask = 0.0;
|
||||
|
||||
if (showThirds)
|
||||
mask = max(mask, thirdsMask(context.uv, resolution));
|
||||
if (showCrosshair)
|
||||
mask = max(mask, crosshairMask(context.uv, resolution));
|
||||
|
||||
float opacity = saturate(lineOpacity * lineColor.a) * mask;
|
||||
float3 color = lerp(context.sourceColor.rgb, lineColor.rgb, opacity);
|
||||
return float4(color, context.sourceColor.a);
|
||||
}
|
||||
54
shaders/video-transform/shader.json
Normal file
54
shaders/video-transform/shader.json
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"id": "video-transform",
|
||||
"name": "Video Transform",
|
||||
"description": "Zooms, pans, and rotates the video by remapping output pixels back into source UV space.",
|
||||
"category": "Utility",
|
||||
"entryPoint": "shadeVideo",
|
||||
"parameters": [
|
||||
{
|
||||
"id": "zoom",
|
||||
"label": "Zoom",
|
||||
"type": "float",
|
||||
"default": 1.0,
|
||||
"min": 0.1,
|
||||
"max": 8.0,
|
||||
"step": 0.01
|
||||
},
|
||||
{
|
||||
"id": "pan",
|
||||
"label": "Pan",
|
||||
"type": "vec2",
|
||||
"default": [0.0, 0.0],
|
||||
"min": [-1.0, -1.0],
|
||||
"max": [1.0, 1.0],
|
||||
"step": [0.001, 0.001]
|
||||
},
|
||||
{
|
||||
"id": "rotationDegrees",
|
||||
"label": "Rotation",
|
||||
"type": "float",
|
||||
"default": 0.0,
|
||||
"min": -180.0,
|
||||
"max": 180.0,
|
||||
"step": 0.1
|
||||
},
|
||||
{
|
||||
"id": "edgeMode",
|
||||
"label": "Edge Mode",
|
||||
"type": "enum",
|
||||
"default": "black",
|
||||
"options": [
|
||||
{ "value": "black", "label": "Black" },
|
||||
{ "value": "clamp", "label": "Clamp" },
|
||||
{ "value": "wrap", "label": "Wrap" },
|
||||
{ "value": "mirror", "label": "Mirror" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "outsideColor",
|
||||
"label": "Outside Color",
|
||||
"type": "color",
|
||||
"default": [0.0, 0.0, 0.0, 1.0]
|
||||
}
|
||||
]
|
||||
}
|
||||
44
shaders/video-transform/shader.slang
Normal file
44
shaders/video-transform/shader.slang
Normal file
@@ -0,0 +1,44 @@
|
||||
static const float PI = 3.14159265358979323846;
|
||||
|
||||
float2 rotateAroundCenter(float2 uv, float radians)
|
||||
{
|
||||
float2 centered = uv - 0.5;
|
||||
float s = sin(radians);
|
||||
float c = cos(radians);
|
||||
return float2(c * centered.x - s * centered.y, s * centered.x + c * centered.y) + 0.5;
|
||||
}
|
||||
|
||||
float mirroredCoordinate(float coordinate)
|
||||
{
|
||||
float wrapped = frac(coordinate * 0.5) * 2.0;
|
||||
return wrapped <= 1.0 ? wrapped : 2.0 - wrapped;
|
||||
}
|
||||
|
||||
float2 applyEdgeMode(float2 uv, out bool inside)
|
||||
{
|
||||
inside = uv.x >= 0.0 && uv.x <= 1.0 && uv.y >= 0.0 && uv.y <= 1.0;
|
||||
|
||||
if (edgeMode == 1)
|
||||
return clamp(uv, 0.0, 1.0);
|
||||
if (edgeMode == 2)
|
||||
return frac(uv);
|
||||
if (edgeMode == 3)
|
||||
return float2(mirroredCoordinate(uv.x), mirroredCoordinate(uv.y));
|
||||
|
||||
return uv;
|
||||
}
|
||||
|
||||
float4 shadeVideo(ShaderContext context)
|
||||
{
|
||||
float safeZoom = max(zoom, 0.001);
|
||||
float2 sourceUv = (context.uv - 0.5) / safeZoom + 0.5;
|
||||
sourceUv -= pan;
|
||||
sourceUv = rotateAroundCenter(sourceUv, -rotationDegrees * (PI / 180.0));
|
||||
|
||||
bool inside = false;
|
||||
float2 sampledUv = applyEdgeMode(sourceUv, inside);
|
||||
if (!inside && edgeMode == 0)
|
||||
return outsideColor;
|
||||
|
||||
return sampleVideo(sampledUv);
|
||||
}
|
||||
Reference in New Issue
Block a user