Added green screen

This commit is contained in:
2026-05-02 20:24:40 +10:00
parent 4308e0b6f6
commit be16b03024
4 changed files with 133 additions and 3 deletions

View File

@@ -0,0 +1,90 @@
{
"id": "greenscreen-key",
"name": "Greenscreen Key",
"description": "Keys out a green screen background and outputs transparent alpha for compositing.",
"category": "Built-in",
"entryPoint": "shadeVideo",
"parameters": [
{
"id": "screenColor",
"label": "Screen Color",
"type": "color",
"default": [0.15, 0.85, 0.2, 1.0],
"min": [0.0, 0.0, 0.0, 0.0],
"max": [1.0, 1.0, 1.0, 1.0],
"step": [0.01, 0.01, 0.01, 0.01]
},
{
"id": "threshold",
"label": "Threshold",
"type": "float",
"default": 0.24,
"min": 0.01,
"max": 0.8,
"step": 0.005
},
{
"id": "softness",
"label": "Softness",
"type": "float",
"default": 0.12,
"min": 0.001,
"max": 0.5,
"step": 0.005
},
{
"id": "edgeSoftness",
"label": "Edge Softness",
"type": "float",
"default": 0.08,
"min": 0.0,
"max": 0.4,
"step": 0.005
},
{
"id": "erodeDilate",
"label": "Erode/Dilate",
"type": "float",
"default": 0.0,
"min": -0.3,
"max": 0.3,
"step": 0.005
},
{
"id": "despill",
"label": "Despill",
"type": "float",
"default": 0.45,
"min": 0.0,
"max": 1.5,
"step": 0.01
},
{
"id": "edgeBoost",
"label": "Edge Boost",
"type": "float",
"default": 0.08,
"min": -0.2,
"max": 0.3,
"step": 0.005
},
{
"id": "clipBlack",
"label": "Clip Black",
"type": "float",
"default": 0.0,
"min": 0.0,
"max": 0.5,
"step": 0.005
},
{
"id": "clipWhite",
"label": "Clip White",
"type": "float",
"default": 1.0,
"min": 0.5,
"max": 1.0,
"step": 0.005
}
]
}

View File

@@ -0,0 +1,40 @@
float3 safeNormalize(float3 value)
{
float len = max(length(value), 0.0001);
return value / len;
}
float luma709(float3 color)
{
return dot(color, float3(0.2126, 0.7152, 0.0722));
}
float4 shadeVideo(ShaderContext context)
{
float4 src = context.sourceColor;
float3 color = saturate(src.rgb);
float3 keyColor = safeNormalize(max(screenColor.rgb, float3(0.0001, 0.0001, 0.0001)));
float3 sampleColor = safeNormalize(max(color, float3(0.0001, 0.0001, 0.0001)));
float chromaDistance = length(sampleColor - keyColor);
float matteCenter = threshold - erodeDilate;
float matteFeather = max(softness + edgeSoftness, 0.0005);
float alpha = smoothstep(matteCenter - matteFeather, matteCenter + matteFeather, chromaDistance);
alpha = saturate((alpha - clipBlack) / max(clipWhite - clipBlack, 0.0001));
alpha = saturate(alpha + edgeBoost);
float greenExcess = max(0.0, color.g - max(color.r, color.b));
float spillReduction = greenExcess * despill;
float3 despilled = color;
despilled.g = max(0.0, despilled.g - spillReduction);
float neutral = luma709(despilled);
despilled.rb += spillReduction * 0.25;
despilled = lerp(float3(neutral, neutral, neutral), despilled, 0.92);
float3 premultiplied = saturate(despilled) * alpha;
return float4(premultiplied, alpha);
}

View File

@@ -6,7 +6,7 @@
"entryPoint": "shadeVideo",
"temporal": {
"enabled": true,
"historySource": "source",
"historySource": "preLayerInput",
"historyLength": 8
},
"parameters": [

View File

@@ -8,8 +8,8 @@ float4 shadeVideo(ShaderContext context)
int lowerPhase = int(context.frameCount) % lowerHoldLength;
int upperPhase = int(context.frameCount) % upperHoldLength;
float4 lowerHeld = lowerPhase == 0 ? context.sourceColor : sampleSourceHistory(lowerPhase - 1, context.uv);
float4 upperHeld = upperPhase == 0 ? context.sourceColor : sampleSourceHistory(upperPhase - 1, context.uv);
float4 lowerHeld = lowerPhase == 0 ? context.sourceColor : sampleTemporalHistory(lowerPhase - 1, context.uv);
float4 upperHeld = upperPhase == 0 ? context.sourceColor : sampleTemporalHistory(upperPhase - 1, context.uv);
float4 held = lerp(lowerHeld, upperHeld, fractional);
return lerp(context.sourceColor, held, clamp(blendAmount, 0.0, 1.0));
}