Last active
July 12, 2016 00:09
-
-
Save s-leroux/97a222330216bb732e6c34521aade2f7 to your computer and use it in GitHub Desktop.
Pologon mask effect for LightWorks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//--------------------------------------------------------------// | |
// Header | |
// | |
// Lightworks effects have to have a _LwksEffectInfo block | |
// which defines basic information about the effect (ie. name | |
// and category). EffectGroup must be "GenericPixelShader". | |
//--------------------------------------------------------------// | |
int _LwksEffectInfo | |
< | |
string EffectGroup = "GenericPixelShader"; | |
string Description = "PolyMask"; // The title | |
string Category = "Masks"; // Governs the category that the effect appears in in Lightworks | |
> = 0; | |
//--------------------------------------------------------------// | |
// Inputs | |
//--------------------------------------------------------------// | |
// For each 'texture' declared here, Lightworks adds a matching | |
// input to your effect (so for a four input effect, you'd need | |
// to delcare four textures and samplers) | |
float _OutputWidth, _OutputHeight, _OutputAspectRatio; | |
texture fg; | |
texture bg; | |
sampler FGround = sampler_state { | |
Texture = <fg>; | |
AddressU = Clamp; | |
AddressV = Clamp; | |
MinFilter = Linear; | |
MagFilter = Linear; | |
MipFilter = Linear; | |
}; | |
sampler BGround = sampler_state { | |
Texture = <bg>; | |
AddressU = Clamp; | |
AddressV = Clamp; | |
MinFilter = Linear; | |
MagFilter = Linear; | |
MipFilter = Linear; | |
}; | |
texture MaskTexture : RenderColorTarget; | |
sampler Mask = sampler_state { | |
Texture = <MaskTexture>; | |
AddressU = Clamp; | |
AddressV = Clamp; | |
MinFilter = Linear; | |
MagFilter = Linear; | |
MipFilter = Linear; | |
}; | |
//--------------------------------------------------------------// | |
// Define parameters here. | |
// | |
// The Lightworks application will automatically generate | |
// sliders/controls for all parameters which do not start | |
// with a a leading '_' character | |
//--------------------------------------------------------------// | |
bool show | |
< | |
string Description = "Show mask"; | |
> = false; | |
bool P1 | |
< | |
string Description = "Enable"; | |
string Group = "P1"; | |
> = true; | |
float P1X | |
< | |
string Description = "P1"; | |
string Group = "P1"; | |
string Flags = "SpecifiesPointX"; | |
float MinVal = -1.00; | |
float MaxVal = 2.00; | |
> = 0.25; | |
float P1Y | |
< | |
string Description = "P1"; | |
string Group = "P1"; | |
string Flags = "SpecifiesPointY"; | |
float MinVal = -1.00; | |
float MaxVal = 2.00; | |
> = 0.25; | |
bool P2 | |
< | |
string Description = "Enable"; | |
string Group = "P2"; | |
> = true; | |
float P2X | |
< | |
string Description = "P2"; | |
string Group = "P2"; | |
string Flags = "SpecifiesPointX"; | |
float MinVal = -1.00; | |
float MaxVal = 2.00; | |
> = 0.25; | |
float P2Y | |
< | |
string Description = "P2"; | |
string Group = "P2"; | |
string Flags = "SpecifiesPointY"; | |
float MinVal = -1.00; | |
float MaxVal = 2.00; | |
> = 0.75; | |
bool P3 | |
< | |
string Description = "Enable"; | |
string Group = "P3"; | |
> = true; | |
float P3X | |
< | |
string Description = "P3"; | |
string Group = "P3"; | |
string Flags = "SpecifiesPointX"; | |
float MinVal = -1.00; | |
float MaxVal = 2.00; | |
> = 0.75; | |
float P3Y | |
< | |
string Description = "P3"; | |
string Group = "P3"; | |
string Flags = "SpecifiesPointY"; | |
float MinVal = -1.00; | |
float MaxVal = 2.00; | |
> = 0.75; | |
bool P4 | |
< | |
string Description = "Enable"; | |
string Group = "P4"; | |
> = true; | |
float P4X | |
< | |
string Description = "P4"; | |
string Group = "P4"; | |
string Flags = "SpecifiesPointX"; | |
float MinVal = -1.00; | |
float MaxVal = 2.00; | |
> = 0.75; | |
float P4Y | |
< | |
string Description = "P4"; | |
string Group = "P4"; | |
string Flags = "SpecifiesPointY"; | |
float MinVal = -1.00; | |
float MaxVal = 2.00; | |
> = 0.25; | |
// ??? | |
//#pragma warning ( disable : 3571 ) | |
//-------------------------------------------------------------- | |
// Pixel Shader | |
// | |
// This section defines the code which the GPU will | |
// execute for every pixel in an output image. | |
// | |
// Note that pixels are processed out of order, in parallel. | |
// Using shader model 2.0, so there's a 64 instruction limit - | |
// use multple passes if you need more. | |
//-------------------------------------------------------------- | |
float4 mask( float2 xy : TEXCOORD1 ) : COLOR | |
{ | |
// Build the sequence of vertex indexes | |
int idx[4+1]; | |
int count = 0; | |
if (P1) idx[count++] = 0; | |
if (P2) idx[count++] = 1; | |
if (P3) idx[count++] = 2; | |
if (P4) idx[count++] = 3; | |
idx[count] = idx[0]; | |
if (count < 3) return float4(0,0,0,0); | |
bool oddPixel = false; | |
float2 vertex[4]; | |
vertex[0] = float2(P1X, 1.0f - P1Y); | |
vertex[1] = float2(P2X, 1.0f - P2Y); | |
vertex[2] = float2(P3X, 1.0f - P3Y); | |
vertex[3] = float2(P4X, 1.0f - P4Y); | |
float2 pixel = xy; | |
int x = 0; | |
for(x=0; x < count; ++x) { | |
int i = idx[x]; | |
int j = idx[x+1]; | |
// (vertex[i] - vertex[j]) is an oriented edge. | |
if (vertex[i].y != vertex[j].y) { | |
// Not an horizontal edge | |
float s = (pixel.y - vertex[i].y)/(vertex[j].y - vertex[i].y); | |
if (s >= 0.0f && s <= 1.0f) { | |
// on the scan line | |
if (lerp(vertex[i].x, vertex[j].x, s) < pixel.x) { | |
oddPixel = !oddPixel; | |
} | |
} | |
} | |
} | |
return (oddPixel) ? float4(1,1,1,1) : float4(0,0,0,0); | |
} | |
/* | |
float4 GrowablePoissonDisc13FilterRGBA (sampler tSource, float2 texCoord, float2 pixelSize, float discRadius, float run) | |
{ | |
float4 cOut; | |
float2 poisson[12] = {float2(-0.326212f, -0.40581f), | |
float2(-0.840144f, -0.07358f), | |
float2(-0.695914f, 0.457137f), | |
float2(-0.203345f, 0.620716f), | |
float2(0.96234f, -0.194983f), | |
float2(0.473434f, -0.480026f), | |
float2(0.519456f, 0.767022f), | |
float2(0.185461f, -0.893124f), | |
float2(0.507431f, 0.064425f), | |
float2(0.89642f, 0.412458f), | |
float2(-0.32194f, -0.932615f), | |
float2(-0.791559f, -0.59771f)}; | |
// center tap | |
cOut = tex2D (tSource, texCoord); | |
for (int tap = 0; tap < 12; tap++) | |
{ | |
float2 coord = texCoord.xy + (pixelSize * (poisson[tap]/run) * discRadius); | |
cOut += tex2D (tSource, coord); | |
} | |
return (cOut / 13.0f); | |
} | |
float4 PSBlur( float2 Tex : TEXCOORD0, uniform float run ) : COLOR0 | |
{ | |
float2 pixsize = float2(1.0f / _OutputWidth, 1.0f / _OutputHeight); | |
float4 orig; | |
if (run == 1.0f) orig = GrowablePoissonDisc13FilterRGBA(Samp2, Tex + (pixsize / 2.0f), pixsize, feather, run); | |
else orig = GrowablePoissonDisc13FilterRGBA(Samp1, Tex + (pixsize / 2.0f), pixsize, feather, run); | |
return orig; | |
} | |
*/ | |
float4 combine( float2 uv : TEXCOORD0 ) : COLOR0 | |
{ | |
float4 mk = tex2D( Mask, uv); | |
if (show) | |
return mk; | |
float4 fg = tex2D( FGround, uv); | |
float4 bg = tex2D( BGround, uv); | |
float4 color = lerp(fg,bg,mk.a); | |
return color; | |
} | |
//-------------------------------------------------------------- | |
// Technique | |
// | |
// Specifies the order of passes | |
//-------------------------------------------------------------- | |
technique SampleFxTechnique | |
{ | |
pass Pass1 | |
< | |
string Script = "RenderColorTarget0 = MaskTexture;"; | |
> | |
{ | |
PixelShader = compile PROFILE mask(); | |
} | |
pass Pass2 | |
{ | |
PixelShader = compile PROFILE combine(); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment