Commands/Shaders/Get-OBSFire3Shader.ps1

function Get-OBSFire3Shader {

[Alias('Set-OBSFire3Shader','Add-OBSFire3Shader')]
param(
# Set the ViewProj of OBSFire3Shader
[ComponentModel.DefaultBindingProperty('ViewProj')]
[Single[][]]
$ViewProj,
# Set the image of OBSFire3Shader
[ComponentModel.DefaultBindingProperty('image')]
[String]
$Image,
# Set the elapsed_time of OBSFire3Shader
[Alias('elapsed_time')]
[ComponentModel.DefaultBindingProperty('elapsed_time')]
[Single]
$ElapsedTime,
# Set the uv_offset of OBSFire3Shader
[Alias('uv_offset')]
[ComponentModel.DefaultBindingProperty('uv_offset')]
[Single[]]
$UvOffset,
# Set the uv_scale of OBSFire3Shader
[Alias('uv_scale')]
[ComponentModel.DefaultBindingProperty('uv_scale')]
[Single[]]
$UvScale,
# Set the uv_pixel_interval of OBSFire3Shader
[Alias('uv_pixel_interval')]
[ComponentModel.DefaultBindingProperty('uv_pixel_interval')]
[Single[]]
$UvPixelInterval,
# Set the uv_size of OBSFire3Shader
[Alias('uv_size')]
[ComponentModel.DefaultBindingProperty('uv_size')]
[Single[]]
$UvSize,
# Set the rand_f of OBSFire3Shader
[Alias('rand_f')]
[ComponentModel.DefaultBindingProperty('rand_f')]
[Single]
$RandF,
# Set the rand_instance_f of OBSFire3Shader
[Alias('rand_instance_f')]
[ComponentModel.DefaultBindingProperty('rand_instance_f')]
[Single]
$RandInstanceF,
# Set the rand_activation_f of OBSFire3Shader
[Alias('rand_activation_f')]
[ComponentModel.DefaultBindingProperty('rand_activation_f')]
[Single]
$RandActivationF,
# Set the loops of OBSFire3Shader
[ComponentModel.DefaultBindingProperty('loops')]
[Int32]
$Loops,
# Set the local_time of OBSFire3Shader
[Alias('local_time')]
[ComponentModel.DefaultBindingProperty('local_time')]
[Single]
$LocalTime,
# Set the Movement_Direction_Horizontal of OBSFire3Shader
[Alias('Movement_Direction_Horizontal')]
[ComponentModel.DefaultBindingProperty('Movement_Direction_Horizontal')]
[Single]
$MovementDirectionHorizontal,
# Set the Movement_Direction_Vertical of OBSFire3Shader
[Alias('Movement_Direction_Vertical')]
[ComponentModel.DefaultBindingProperty('Movement_Direction_Vertical')]
[Single]
$MovementDirectionVertical,
# Set the Alpha_Percentage of OBSFire3Shader
[Alias('Alpha_Percentage')]
[ComponentModel.DefaultBindingProperty('Alpha_Percentage')]
[Int32]
$AlphaPercentage,
# Set the Speed of OBSFire3Shader
[ComponentModel.DefaultBindingProperty('Speed')]
[Int32]
$Speed,
# Set the Invert of OBSFire3Shader
[ComponentModel.DefaultBindingProperty('Invert')]
[Management.Automation.SwitchParameter]
$Invert,
# Set the lumaMin of OBSFire3Shader
[ComponentModel.DefaultBindingProperty('lumaMin')]
[Single]
$LumaMin,
# Set the lumaMinSmooth of OBSFire3Shader
[ComponentModel.DefaultBindingProperty('lumaMinSmooth')]
[Single]
$LumaMinSmooth,
# Set the Apply_To_Image of OBSFire3Shader
[Alias('Apply_To_Image')]
[ComponentModel.DefaultBindingProperty('Apply_To_Image')]
[Management.Automation.SwitchParameter]
$ApplyToImage,
# Set the Replace_Image_Color of OBSFire3Shader
[Alias('Replace_Image_Color')]
[ComponentModel.DefaultBindingProperty('Replace_Image_Color')]
[Management.Automation.SwitchParameter]
$ReplaceImageColor,
# Set the Color_To_Replace of OBSFire3Shader
[Alias('Color_To_Replace')]
[ComponentModel.DefaultBindingProperty('Color_To_Replace')]
[String]
$ColorToReplace,
# Set the Apply_To_Specific_Color of OBSFire3Shader
[Alias('Apply_To_Specific_Color')]
[ComponentModel.DefaultBindingProperty('Apply_To_Specific_Color')]
[Management.Automation.SwitchParameter]
$ApplyToSpecificColor,
# Set the Full_Width of OBSFire3Shader
[Alias('Full_Width')]
[ComponentModel.DefaultBindingProperty('Full_Width')]
[Management.Automation.SwitchParameter]
$FullWidth,
# Set the Flame_Size of OBSFire3Shader
[Alias('Flame_Size')]
[ComponentModel.DefaultBindingProperty('Flame_Size')]
[Single]
$FlameSize,
# Set the Spark_Grid_Height of OBSFire3Shader
[Alias('Spark_Grid_Height')]
[ComponentModel.DefaultBindingProperty('Spark_Grid_Height')]
[Single]
$SparkGridHeight,
# Set the Flame_Modifier of OBSFire3Shader
[Alias('Flame_Modifier')]
[ComponentModel.DefaultBindingProperty('Flame_Modifier')]
[Single]
$FlameModifier,
# Set the Flame_Tongue_Size of OBSFire3Shader
[Alias('Flame_Tongue_Size')]
[ComponentModel.DefaultBindingProperty('Flame_Tongue_Size')]
[Single]
$FlameTongueSize,
# The name of the source. This must be provided when adding an item for the first time
[Parameter(ValueFromPipelineByPropertyName)]
[Alias('SceneItemName')]
[String]
$SourceName,
# The name of the filter. If this is not provided, this will default to the shader name.
[Parameter(ValueFromPipelineByPropertyName)]
[String]
$FilterName,
# The inline value of the shader. This will normally be provided as a default parameter, based off of the name.
[Alias('ShaderContent')]
[String]
$ShaderText,
# If set, will force the recreation of a shader that already exists
[Management.Automation.SwitchParameter]
$Force,
# If set, will pass thru the commands that would be sent to OBS (these can be sent at any time with Send-OBS)
[Management.Automation.SwitchParameter]
$PassThru,
# If set, will not wait for a response from OBS (this will be faster, but will not return anything)
[Management.Automation.SwitchParameter]
$NoResponse,
# If set, use the shader elapsed time, instead of the OBS system elapsed time
[ComponentModel.DefaultBindingProperty('use_shader_elapsed_time')]
[Management.Automation.SwitchParameter]
$UseShaderTime
)


process {
$shaderName = 'fire-3'
$ShaderNoun = 'OBSFire3Shader'
if (-not $psBoundParameters['ShaderText']) {    
    $psBoundParameters['ShaderText'] = $ShaderText = '
//My effect modified by Me for use with obs-shaderfilter month/year v.02
//Converted to OpenGL by Q-mii & Exeldro February 22, 2022
uniform float4x4 ViewProj;
uniform texture2d image;

//Section to converting GLSL to HLSL - can delete
#define vec2 float2
#define vec3 float3
#define vec4 float4
#define ivec2 int2
#define ivec3 int3
#define ivec4 int4
#define mat2 float2x2
#define mat3 float3x3
#define mat4 float4x4
#define fract frac
#define mix lerp


uniform float elapsed_time;
uniform float2 uv_offset;
uniform float2 uv_scale;
uniform float2 uv_pixel_interval;
uniform float2 uv_size;
uniform float rand_f;
uniform float rand_instance_f;
uniform float rand_activation_f;
uniform int loops;
uniform float local_time;

uniform float Movement_Direction_Horizontal<
    string label = "Movement Direction Horizontal";
    string widget_type = "slider";
    float minimum = -100.0;
    float maximum = 100.0;
    float step = 0.01;
> = 0.0;
uniform float Movement_Direction_Vertical<
    string label = "Movement Direction Vertical";
    string widget_type = "slider";
    float minimum = -100.0;
    float maximum = 100.0;
    float step = 0.01;
> = 0.0;

#define iTime elapsed_time
#define iResolution float4(uv_size,uv_pixel_interval)
#define Movement_Direction float2(Movement_Direction_Horizontal, Movement_Direction_Vertical)

uniform int Alpha_Percentage<
    string label = "Alpha Percentage";
    string widget_type = "slider";
    int minimum = 0;
    int maximum = 100;
    int step = 1;
> = 90;
uniform int Speed<
    string label = "Speed";
    string widget_type = "slider";
    int minimum = 0;
    int maximum = 100;
    int step = 1;
> = 80;
uniform bool Invert = false;
uniform float lumaMin<
    string label = "Luma Min";
    string widget_type = "slider";
    float minimum = 0.0;
    float maximum = 1.0;
    float step = 0.01;
> = 0.01;
uniform float lumaMinSmooth<
    string label = "Luma Min Smooth";
    string widget_type = "slider";
    float minimum = 0.0;
    float maximum = 1.0;
    float step = 0.01;
> = 0.04;
uniform bool Apply_To_Image = true;
uniform bool Replace_Image_Color = true;
uniform float4 Color_To_Replace;
uniform bool Apply_To_Specific_Color = false;

sampler_state textureSampler {
    Filter = Linear;
    AddressU = Border;
    AddressV = Border;
    BorderColor = 00000000;
};

struct VertData {
    float4 pos : POSITION;
    float2 uv : TEXCOORD0;
};

VertData mainTransform(VertData v_in)
{
    VertData vert_out;
    vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj);
    float2 uv = v_in.uv;
    if(Invert)
        uv = 1.0 - v_in.uv;
    vert_out.uv = v_in.uv * uv_scale + uv_offset;
    return vert_out;
}

int2 iMouse()
{
    return int2(Movement_Direction.x * uv_size.x, Movement_Direction.y * uv_size.y);
}


float mod(float x, float y)
{
    return x - y * floor(x / y);
}

float2 mod2(float2 x, float2 y)
{
    return x - y * floor(x / y);
}

/*ps start*/
#define PI 3.1415926535897932384626433832795
uniform bool Full_Width = false;

uniform float Flame_Size<
    string label = "Flame Size";
    string widget_type = "slider";
    float minimum = 0.0;
    float maximum = 10.0;
    float step = 0.01;
> = 1.0;

uniform float Spark_Grid_Height<
    string label = "Spark Grid Size";
    string widget_type = "slider";
    float minimum = 0.0;
    float maximum = 100.0;
    float step = 0.01;
> = 50.0;

uniform float Flame_Modifier<
    string label = "Flame Modifier";
    string widget_type = "slider";
    float minimum = 0.0;
    float maximum = 2.0;
    float step = 0.01;
> = 1.0;

uniform float Flame_Tongue_Size<
    string label = "Flame Tongue Size";
    string widget_type = "slider";
    float minimum = 0.0;
    float maximum = 2.0;
    float step = 0.01;
> = 8.5;

//
// Description : Array and textureless GLSL 2D/3D/4D simplex
// noise functions.
// Author : Ian McEwan, Ashima Arts.
// Maintainer : ijm
// Lastmod : 20110822 (ijm)
// License : Copyright (C) 2011 Ashima Arts. All rights reserved.
// Distributed under the MIT License. See LICENSE file.
// https://github.com/ashima/webgl-noise
//

vec3 mod2893(vec3 x)
{
    return x - floor(x * (1.0 / 289.0)) * 289.0;
}

vec4 mod289(vec4 x)
{
    return x - floor(x * (1.0 / 289.0)) * 289.0;
}

vec4 permute(vec4 x)
{
    return mod289(((x * 34.0) + 1.0) * x);
}

vec4 taylorInvSqrt(vec4 r)
{
    return 1.79284291400159 - 0.85373472095314 * r;
}

float snoise(vec3 v)
{
    const vec2 C = vec2(1.0 / 6.0, 1.0 / 3.0);
    const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);

// First corner
    vec3 i = floor(v + dot(v, C.yyy));
    vec3 x0 = v - i + dot(i, C.xxx);

// Other corners
    vec3 g = step(x0.yzx, x0.xyz);
    vec3 l = 1.0 - g;
    vec3 i1 = min(g.xyz, l.zxy);
    vec3 i2 = max(g.xyz, l.zxy);

    // x0 = x0 - 0.0 + 0.0 * C.xxx;
    // x1 = x0 - i1 + 1.0 * C.xxx;
    // x2 = x0 - i2 + 2.0 * C.xxx;
    // x3 = x0 - 1.0 + 3.0 * C.xxx;
    vec3 x1 = x0 - i1 + C.xxx;
    vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
    vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y

// Permutations
    i = mod2893(i);
    vec4 p = permute(permute(permute(
                     i.z + vec4(0.0, i1.z, i2.z, 1.0))
                     + i.y + vec4(0.0, i1.y, i2.y, 1.0))
                     + i.x + vec4(0.0, i1.x, i2.x, 1.0));

// Gradients: 7x7 points over a square, mapped onto an octahedron.
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
    float n_ = 0.142857142857; // 1.0/7.0
    vec3 ns = n_ * D.wyz - D.xzx;

    vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)

    vec4 x_ = floor(j * ns.z);
    vec4 y_ = floor(j - 7.0 * x_); // mod(j,N)

    vec4 x = x_ * ns.x + ns.yyyy;
    vec4 y = y_ * ns.x + ns.yyyy;
    vec4 h = 1.0 - abs(x) - abs(y);

    vec4 b0 = vec4(x.xy, y.xy);
    vec4 b1 = vec4(x.zw, y.zw);

    //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
    //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
    vec4 s0 = floor(b0) * 2.0 + 1.0;
    vec4 s1 = floor(b1) * 2.0 + 1.0;
    vec4 sh = -step(h, vec4(0.0, 0.0, 0.0, 0.0));

    vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;
    vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww;

    vec3 p0 = vec3(a0.xy, h.x);
    vec3 p1 = vec3(a0.zw, h.y);
    vec3 p2 = vec3(a1.xy, h.z);
    vec3 p3 = vec3(a1.zw, h.w);

//Normalise gradients
    //vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
    vec4 norm = rsqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
    p0 *= norm.x;
    p1 *= norm.y;
    p2 *= norm.z;
    p3 *= norm.w;

// Mix final noise value
    vec4 m = max(0.6 - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0);
    m = m * m;
    return 42.0 * dot(m * m, vec4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3)));
}

//////////////////////////////////////////////////////////////

// PRNG
// From https://www.shadertoy.com/view/4djSRW
float prng(in vec2 seed)
{
    seed = fract(seed * vec2(5.3983, 5.4427));
    seed += dot(seed.yx, seed.xy + vec2(21.5351, 14.3137));
    return fract(seed.x * seed.y * 95.4337);
}

//////////////////////////////////////////////////////////////

float noiseStack(vec3 pos, int octaves, float falloff)
{
    float noise = snoise(vec3(pos));
    float off = 1.0;
    if (octaves > 1)
    {
        pos *= 2.0;
        off *= falloff;
        noise = (1.0 - off) * noise + off * snoise(vec3(pos));
    }
    if (octaves > 2)
    {
        pos *= 2.0;
        off *= falloff;
        noise = (1.0 - off) * noise + off * snoise(vec3(pos));
    }
    if (octaves > 3)
    {
        pos *= 2.0;
        off *= falloff;
        noise = (1.0 - off) * noise + off * snoise(vec3(pos));
    }
    return (1.0 + noise) / 2.0;
}

vec2 noiseStackUV(vec3 pos, int octaves, float falloff, float diff)
{
    float displaceA = noiseStack(pos, octaves, falloff);
    float displaceB = noiseStack(pos + vec3(3984.293, 423.21, 5235.19), octaves, falloff);
    return vec2(displaceA, displaceB);
}

float4 mainImage(VertData v_in) : TARGET
{
    float2 UV = (1.0 - v_in.uv) * uv_scale;
    if (Invert)
        UV = v_in.uv * uv_scale;
    float alpha = saturate(Alpha_Percentage * .01);
    float flame_size = clamp(Flame_Size * .01, 0.0, 4.0);
    
    vec2 resolution = (.25 * uv_scale * UV.xy) + (0.75 * uv_scale);
    if (Full_Width)
    {
        resolution = (2.0 * (UV.xy)) / 1.0; //iResolution.xy;
       
    }
    resolution.x = mul(resolution.x, 1 / 1);
    float time = iTime * (Speed * 0.01);
    //vec2 drag = iMouse().xy;
    vec2 offset = iMouse().xy;
    //
    float xpart = UV.x / resolution.x;
    float ypart = UV.y / resolution.y;
    //
    
    float ypartClip = UV.y / ( flame_size * 75.0);
    float ypartClippedFalloff = clamp(2.0 - ypartClip, 0.0, 1.0);
    float ypartClipped = min(ypartClip, 1.0);
    float ypartClippedn = (1 - ypartClipped);
    //
    float xfuel = pow(1.0 - abs(2.0 * xpart - 1.0), 0.5); //pow(1.0-abs(2.0*xpart-1.0),0.5);
    //
    float timeSpeed = 0.5 * (Speed * 0.01);
    float realTime = -1.0 * timeSpeed * time;
    //
    vec2 coordScaled = -1 * Flame_Tongue_Size * UV - 0.1 * offset;
    vec3 position = vec3(coordScaled, 0.0); // +vec3(1223.0, 6434.0, 8425.0);
    vec3 flow = vec3(4.1 * (0.5 - xpart) * pow(ypartClippedn, 4.0), -2.0 * xfuel * pow(ypartClippedn, 64.0), 0.0);
    vec3 timing = realTime * vec3(0.0, -1.7, 1.1) + flow;
    //
    vec3 displacePos = vec3(1.0, 0.5, 1.0) * 2.4 * position + realTime * vec3(0.01, -0.7, 1.3);
    vec3 displace3 = vec3(noiseStackUV(displacePos, 2, 0.4, 0.1), 0.0);
    //
    vec3 noiseCoord = (vec3(2.0, 1.0, 1.0) * position + timing + 0.4 * displace3) / 1.0;
    float noise = noiseStack(noiseCoord, 3, 0.4);
    //
    float flames = pow(ypartClipped, 0.3 * xfuel) * pow(noise, 0.3 * xfuel);
    //
    float f = ypartClippedFalloff * pow(Flame_Modifier - flames * flames * flames, 8.0);
    float fff = f * f * f;
    vec3 fire = 1.5 * vec3(f, fff, fff * fff);
    //
    // smoke
    float smokeNoise = 0.5 + snoise(0.4 * position + timing * vec3(1.0, 1.0, 0.2)) / 2.0;
    float smokePart = 0.3 * pow(xfuel, 3.0) * pow(ypart, 2.0) * (smokeNoise + 0.4 * (1.0 - noise));
    vec3 smoke = vec3(smokePart, smokePart, smokePart);
    //
    // sparks
    float sparkGridSize = Spark_Grid_Height;
    vec2 sparkCoord = UV *uv_size - vec2(2.0 * offset.x, 190.0 * sin(realTime));
    sparkCoord -= 30.0 * noiseStackUV(0.01 * vec3(sparkCoord, 15.0 * time), 1, 0.4, 0.1);
    sparkCoord += 100.0 * flow.xy;
    if (mod(sparkCoord.y / sparkGridSize, 2.0) < 1.0)
        sparkCoord.x += 0.5 * sparkGridSize;
    vec2 sparkGridIndex = vec2(floor(sparkCoord / sparkGridSize));
    float sparkRandom = prng( sparkGridIndex);
    float sparkLife = min(10.0 * (1.0 - min((sparkGridIndex.y + (190.0 * realTime / sparkGridSize)) / (24.0 - 20.0 * sparkRandom), 1.0)), 1.0);
    vec3 sparks = vec3(0.0, 0.0, 0.0);
    if (sparkLife > 0.0)
    {
        float sparkSize = xfuel * xfuel * sparkRandom * 0.08;
        float sparkRadians = 999.0 * sparkRandom * 2.0 * PI + 2.0 * time;
        vec2 sparkCircular = vec2(sin(sparkRadians), cos(sparkRadians));
        vec2 sparkOffset = (0.5 - sparkSize) * sparkGridSize * sparkCircular;
        vec2 sparkModulus = mod2(sparkCoord + sparkOffset, float2(sparkGridSize, sparkGridSize)) - 0.5 * float2(sparkGridSize, sparkGridSize);
        float sparkLength = length(sparkModulus);
        float sparksGray = max(0.0, 1.0 - sparkLength / (sparkSize * sparkGridSize));
        sparks = sparkLife * sparksGray * vec3(1.0, 0.3, 0.0);
    }
    //
    float4 rgba = vec4(max(fire, sparks) + smoke, 1.0);
    
    // remove dark areas per user
    float luma_fire = dot(rgba.rgb, float3(0.299, 0.587, 0.114));
    float luma_min_fire = smoothstep(lumaMin, lumaMin + lumaMinSmooth, luma_fire);
    rgba.a = clamp(luma_min_fire, 0.0, alpha);
    
    float4 color;
    float4 original_color;
    if (Apply_To_Image)
    {
        float4 color = image.Sample(textureSampler, v_in.uv);
        float4 original_color = color;
        if (color.a > 0.0)
        {
            float luma = color.r * 0.299 + color.g * 0.587 + color.b * 0.114;
            if (Replace_Image_Color)
                color = float4(luma, luma, luma, luma);
            rgba = lerp(original_color, lerp(original_color,rgba * color,rgba.a), alpha);
        }
        else
        {
            rgba = color;
        }
        
    }
    if (Apply_To_Specific_Color)
    {
        color = image.Sample(textureSampler, v_in.uv);
        original_color = color;
        color = (distance(color.rgb, Color_To_Replace.rgb) <= 0.075) ? rgba : color;
        rgba = lerp(original_color, color, alpha);
    }
    
    return rgba;
}

technique Draw
{
    pass
    {
        vertex_shader = mainTransform(v_in);
        pixel_shader = mainImage(v_in);
    }
}

'

}
$MyVerb, $myNoun = $MyInvocation.InvocationName -split '-',2
if (-not $myNoun) {
    $myNoun = $myVerb
    $myVerb = 'Get'    
}
switch -regex ($myVerb) {
    Get {
        $FilterNamePattern = "(?>$(
            if ($FilterName) {
                [Regex]::Escape($FilterName)
            }
            else {
                [Regex]::Escape($ShaderNoun -replace '^OBS' -replace 'Shader$'),[Regex]::Escape($shaderName) -join '|'
            }
        ))"

        if ($SourceName) {
            Get-OBSInput | 
                Where-Object InputName -eq $SourceName |
                Get-OBSSourceFilterList |
                Where-Object FilterName -Match $FilterNamePattern
        } else {
            $obs.Inputs |
                Get-OBSSourceFilterList |
                Where-Object FilterName -Match $FilterNamePattern
        }        
    }
    'Remove' {
        if ($SourceName) {
            Get-OBSInput | 
                Where-Object InputName -eq $SourceName |
                Get-OBSSourceFilterList |
                Where-Object FilterName -Match $FilterNamePattern |
                Remove-OBSSourceFilter
        }
    }
    '(?>Add|Set)' {
        $ShaderSettings = [Ordered]@{}
        :nextParameter foreach ($parameterMetadata in $MyInvocation.MyCommand.Parameters[@($psBoundParameters.Keys)]) {
            foreach ($parameterAttribute in $parameterMetadata.Attributes) {
                if ($parameterAttribute -isnot [ComponentModel.DefaultBindingPropertyAttribute]) { continue }
                $ShaderSettings[$parameterAttribute.Name] = $PSBoundParameters[$parameterMetadata.Name]
                if ($ShaderSettings[$parameterAttribute.Name] -is [switch]) {
                    $ShaderSettings[$parameterAttribute.Name] = $ShaderSettings[$parameterAttribute.Name] -as [bool]
                }
                continue nextParameter
            }            
        }

        if (-not $PSBoundParameters['FilterName']) {
            $filterName = $PSBoundParameters['FilterName'] = $shaderName
        }

        $ShaderFilterSplat = [Ordered]@{
            ShaderSetting = $ShaderSettings
            FilterName = $FilterName
            SourceName = $SourceName
        }        

        foreach ($CarryOnParameter in "PassThru", "NoResponse","Force") {
            if ($PSBoundParameters.ContainsKey($CarryOnParameter)) {
                $ShaderFilterSplat[$CarryOnParameter] = $PSBoundParameters[$CarryOnParameter]
            }
        }

        if (-not $script:CachedShaderFilesFromCommand) {
            $script:CachedShaderFilesFromCommand = @{}
        }

        if ($Home -and -not $script:CachedShaderFilesFromCommand[$shaderName]) {
            $MyObsPowerShellPath = Join-Path $home ".obs-powershell"
            $ThisShaderPath = Join-Path $MyObsPowerShellPath "$shaderName.shader"
            $shaderText | Set-Content -LiteralPath $ThisShaderPath
            $script:CachedShaderFilesFromCommand[$shaderName] = Get-Item -LiteralPath $ThisShaderPath
        }
        if ($script:CachedShaderFilesFromCommand[$shaderName]) {
            $ShaderFilterSplat.ShaderFile = $script:CachedShaderFilesFromCommand[$shaderName].FullName
        } else {
            $ShaderFilterSplat.ShaderText = $shaderText
        }        

        if ($myVerb -eq 'Add') {                        
            Add-OBSShaderFilter @ShaderFilterSplat
        } else {
            Set-OBSShaderFilter @ShaderFilterSplat
        }
    }
}

}


}