Commands/Shaders/Get-OBSSimplexNoiseShader.ps1

function Get-OBSSimplexNoiseShader {

[Alias('Set-OBSSimplexNoiseShader','Add-OBSSimplexNoiseShader')]
param(
# Set the Snap_Percent of OBSSimplexNoiseShader
[Alias('Snap_Percent')]
[ComponentModel.DefaultBindingProperty('Snap_Percent')]
[Single]
$SnapPercent,
# Set the Speed_Percent of OBSSimplexNoiseShader
[Alias('Speed_Percent')]
[ComponentModel.DefaultBindingProperty('Speed_Percent')]
[Single]
$SpeedPercent,
# Set the Resolution of OBSSimplexNoiseShader
[ComponentModel.DefaultBindingProperty('Resolution')]
[Single]
$Resolution,
# Set the Fractal of OBSSimplexNoiseShader
[ComponentModel.DefaultBindingProperty('Fractal')]
[Management.Automation.SwitchParameter]
$Fractal,
# Set the Use_Alpha_Layer of OBSSimplexNoiseShader
[Alias('Use_Alpha_Layer')]
[ComponentModel.DefaultBindingProperty('Use_Alpha_Layer')]
[Management.Automation.SwitchParameter]
$UseAlphaLayer,
# Set the Fore_Color of OBSSimplexNoiseShader
[Alias('Fore_Color')]
[ComponentModel.DefaultBindingProperty('Fore_Color')]
[String]
$ForeColor,
# Set the Back_Color of OBSSimplexNoiseShader
[Alias('Back_Color')]
[ComponentModel.DefaultBindingProperty('Back_Color')]
[String]
$BackColor,
# Set the Alpha_Percent of OBSSimplexNoiseShader
[Alias('Alpha_Percent')]
[ComponentModel.DefaultBindingProperty('Alpha_Percent')]
[Single]
$AlphaPercent,
# Set the Notes of OBSSimplexNoiseShader
[ComponentModel.DefaultBindingProperty('Notes')]
[String]
$Notes,
# 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 = 'simplex_noise'
$ShaderNoun = 'OBSSimplexNoiseShader'
if (-not $psBoundParameters['ShaderText']) {    
    $psBoundParameters['ShaderText'] = $ShaderText = '
// Simplex Noise shader by Charles Fettinger (https://github.com/Oncorporation) 5/2019
// for use with obs-shaderfilter 1.0
//based upon: https://www.shadertoy.com/view/XsX3zB

#ifndef OPENGL
#define fract frac
#endif

uniform float Snap_Percent<
    string label = "Snap Percent";
    string widget_type = "slider";
    float minimum = 0.0;
    float maximum = 100.0;
    float step = 0.01;
> = 7.5;
uniform float Speed_Percent<
    string label = "Speed Percent";
    string widget_type = "slider";
    float minimum = 0.0;
    float maximum = 100.0;
    float step = 0.01;
> = 2.5;
uniform float Resolution<
    string label = "Resolution";
    string widget_type = "slider";
    float minimum = 0.0;
    float maximum = 100.0;
    float step = 0.01;
> = 16.0;
uniform bool Fractal = false;
uniform bool Use_Alpha_Layer = false;
uniform float4 Fore_Color = {0.95,0.95,0.95, 1.0};
uniform float4 Back_Color = {0.75, 0.75, 0.75, 1.0};
uniform float Alpha_Percent<
    string label = "Alpha Percent";
    string widget_type = "slider";
    float minimum = 0.0;
    float maximum = 100.0;
    float step = 0.01;
> = 100.0;
uniform string Notes<
    string widget_type = "info";
> = "Alpha Percentage applies to the shader, Use_Alpha_Layer applies effect with the image alpha layer, Resolution is the amount of detail of noise created.Fractal is a different algorithm. Snap Percent affects how many updates per second. Default values: 7.5%, 2.5%, 16.0, 100%";

float dot(float3 a, float3 b){
    return a.r*b.r+a.g*b.g+a.b*b.b;
}

float dot4(float4 a, float4 b){
    return a.r*b.r+a.g*b.g+a.b*b.b+a.a*b.a;
}
float snap(float x, float snap)
{
    return snap * round(x / max(0.01,snap));
}

float3 random3(float3 co)
{
    float j = 4096.0 * sin(dot(co, float3(17.0, 59.4, 15.0)));
    float3 result;
    result.z = fract(512.0 * j);
    j *= .125;
    result.x = fract(512.0 * j);
    j *= .125;
    result.y = fract(512.0 * j);
    return result - 0.5;
}

/* 3d simplex noise */
float simplex3d(float3 p) {
    /* 1. find current tetrahedron T and it''s four vertices */
    /* s, s+i1, s+i2, s+1.0 - absolute skewed (integer) coordinates of T vertices */
    /* x, x1, x2, x3 - unskewed coordinates of p relative to each of T vertices*/
    
    /* skew constants for 3d simplex functions */
    float F3 = 0.3333333;
    float G3 = 0.1666667;

    /* calculate s and x */
    float3 s = floor(p + dot(p, float3(F3,F3,F3)));
    float3 x = p - s + dot(s, float3(G3,G3,G3));

    /* calculate i1 and i2 */
    float3 e = step(float3(0.0,0.0,0.0), x - x.yzx);
    float3 i1 = e * (1.0 - e.zxy);
    float3 i2 = 1.0 - e.zxy * (1.0 - e);

    /* x1, x2, x3 */
    float3 x1 = x - i1 + G3;
    float3 x2 = x - i2 + 2.0 * G3;
    float3 x3 = x - 1.0 + 3.0 * G3;

    /* 2. find four surflets and store them in d */
    float4 w, d;

    /* calculate surflet weights */
    w.x = dot(x, x);
    w.y = dot(x1, x1);
    w.z = dot(x2, x2);
    w.w = dot(x3, x3);

    /* w fades from 0.6 at the center of the surflet to 0.0 at the margin */
    w = max(0.61 - w, 0.0);

    /* calculate surflet components */
    d.x = dot(random3(s), x);
    d.y = dot(random3(s + i1), x1);
    d.z = dot(random3(s + i2), x2);
    d.w = dot(random3(s + 1.0), x3);

    /* multiply d by w^4 */
    w *= w;
    w *= w;
    d *= w;

    /* 3. return the sum of the four surflets */
    return dot4(d, float4(52.0, 52.0, 52.0, 52.0));
}


/* directional artifacts can be reduced by rotating each octave */
float simplex3d_fractal(float3 m3) {
    /* const matrices for 3d rotation */
#ifdef OPENGL
    float3x3 rot1 = float3x3(
    float3(-0.37, 0.36, 0.85),
    float3(-0.14, -0.93, 0.34),
    float3(0.92, 0.01, 0.4 ));
    float3x3 rot2 = float3x3(
    float3(-0.55, -0.39, 0.74),
    float3(0.33, -0.91, -0.24),
    float3(0.77, 0.12, 0.63 ));
    float3x3 rot3 = float3x3(
    float3(-0.71, 0.52, -0.47),
    float3(-0.08, -0.72, -0.68),
    float3(-0.7, -0.45, 0.56 ));

    float3 m = float3(m3.x, m3.y, m3.z);
#else
    float3x3 rot1 = {
    -0.37, 0.36, 0.85,
    -0.14, -0.93, 0.34,
    0.92, 0.01, 0.4 };
    float3x3 rot2 = {
    -0.55, -0.39, 0.74,
    0.33, -0.91, -0.24,
    0.77, 0.12, 0.63 };
    float3x3 rot3 = {
    -0.71, 0.52, -0.47,
    -0.08, -0.72, -0.68,
    -0.7, -0.45, 0.56 };

    float3 m = {m3.x, m3.y, m3.z};
#endif

    return 0.5333333* simplex3d(mul(m, rot1))
        + 0.2666667 * simplex3d(2.0 * mul(m, rot2))
        + 0.1333333 * simplex3d(4.0 * mul(m, rot3))
        + 0.0666667 * simplex3d(8.0 * m);
}

float4 mainImage(VertData v_in) : TARGET
{
    float time = snap(elapsed_time, Snap_Percent * .01);
    float4 rgba = image.Sample(textureSampler, v_in.uv);
    float2 p = v_in.uv.xy + float2( 0, -0.5);
    float3 p3 = float3(p, time * (Speed_Percent * 0.01));
    
    float pixel_alpha = 1.0;
    // apply to mainImage rgba
    if (Use_Alpha_Layer) {
        p3 *= rgba.rgb;
        pixel_alpha = rgba.a;
    }

    float value;

    if (Fractal) {
        value = simplex3d_fractal(p3 * (Resolution * 0.5) + (Resolution * 0.5));
    }
    else {
        value = simplex3d(p3 * Resolution);
    }

    //soften color
    value = 0.5 + (0.5 * value);
    float intensity = dot(float3(value, value, value), float3(0.299, 0.587, 0.114));

    //use intensity to apply foreground and background colors
    float4 r = lerp(float4(float3(value, value, value), pixel_alpha), Fore_Color, saturate(intensity));
    r = lerp(Back_Color, r, saturate(intensity));
    r.a = pixel_alpha;

    return lerp(rgba, r, Alpha_Percent * 0.01);
}
'

}
$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
        }
    }
}

}


}