Coder Social home page Coder Social logo

obs-shaderfilter-plus's Introduction

OBS ShaderFilter Plus

OBS ShaderFilter Plus is a plugin for Open Broadcaster Software. It can be used to apply effects to sources using manually created GLSL/HLSL shaders.

  1. Add a filter to a source by right-clicking a source, going to Filters, and adding ShaderFilter Plus.
  2. Select a shader by clicking the Browse button and picking the file containing the shader source code via the file browser.
  3. Customize the behavior of the shader via the shader-specific user interface.

Example shaders may be found in the examples directory of this repository. It is a good starting point for the creation of custom effects.

Demo

What are Shaders?

Shaders are programs executed on the GPU. They can be used to apply customizable special visual effects. The shaders used by this plugin are a special subset of shaders called fragment shaders. These shaders are executed once for each pixel of the source, every frame. See Usage Guide for examples.

Different graphics interfaces, such as OpenGL and DirectX, use different shader languages with incompatible syntax, so it is important to be aware of the graphics interfaces OBS makes use of.

  • OBS on Windows uses DirectX by default, but can be forced to use OpenGL.
  • OBS on Linux uses OpenGL.

Shaders are executed using OpenGL (GLSL shaders) or DirectX (HLSL shaders), depending on your platform.

Writing Cross-Platform Shaders

Cross-Platform HLSL

When OBS is run with OpenGL, it performs primitive translation of HLSL sources to GLSL. However, this translation is limited and performed via basic string substitution, and therefore may not result in correct behavior. Despite these limitations, cross platform shaders could be written in HLSL, as long as they are simple.

Cross-Platform GLSL

OBS on Windows may be forced to use OpenGL by launching the program with the --allow-opengl launch parameter. This can be done by creating a shortcut to the executable and appending the parameter to the path, for example: "C:\Program Files\obs-studio\bin\64bit\obs64.exe" --allow-opengl. After launching OBS this way, the OpenGL renderer must be selected in the Advanced Settings. After restarting OBS with these settings applied, GLSL shaders will work properly.

Installation

  1. Download the latest binary for your platform from the Releases page.
    • On Windows, download the file ending with _windows_x64.dll
    • On Linux, download the file ending with _linux_x64.so
  2. Place it in the OBS plugin directory:
    • On Windows, that is usually C:\Program Files\obs-studio\obs-plugins\64bit
    • On Linux, that is usually /usr/lib/obs-plugins

Usage Guide

The structure of a shader is simple. All, that is required, is the following render function.

float4 render(float2 uv) {
    // sample the source texture and return its color to be displayed
    return image.Sample(builtin_texture_sampler, uv);
}

Builtin Variables

Every shader loaded by this plugin has access to the following uniform variables.

uniform texture2d image;                                       // the source texture (the image we are filtering)
uniform int       builtin_frame;                               // the current frame number
uniform float     builtin_framerate;                           // the current output framerate
uniform float     builtin_elapsed_time;                        // the current elapsed time
uniform float     builtin_elapsed_time_previous;               // the elapsed time in the previous frame
uniform float     builtin_elapsed_time_since_shown;            // the time since the source this filter is applied to was shown
uniform float     builtin_elapsed_time_since_shown_previous;   // the time since the source this filter is applied to was shown of the previous frame
uniform float     builtin_elapsed_time_since_enabled;          // the time since the filter itself was shown
uniform float     builtin_elapsed_time_since_enabled_previous; // the time since the filter itself was shown of the previous frame
uniform int2      builtin_uv_size;                             // the source dimensions

sampler_state     builtin_texture_sampler { ... }; // a texture sampler with linear filtering

On-Request Builtin Variables

These uniform variables will be assigned data by the plugin. If they are not defined, they do not use up processing resources.

uniform texture2d builtin_texture_fft_<NAME>;          // audio output frequency spectrum
uniform texture2d builtin_texture_fft_<NAME>_previous; // output from the previous frame (requires builtin_texture_fft_<NAME> to be defined)

Builtin FFT variables have specific properties. See the the section below on properties.

Example:

#pragma shaderfilter set myfft__mix__description Main Mix/Track
#pragma shaderfilter set myfft__channel__description Main Channel
#pragma shaderfilter set myfft__dampening_factor_attack__step 0.0001
#pragma shaderfilter set myfft__dampening_factor_attack__default 0.05
#pragma shaderfilter set myfft__dampening_factor_release 0.0001
uniform texture2d builtin_texture_fft_myfft;

See the examples directory for more examples.

Custom Variables

These uniform variables may be used to let the user provide values to the shader using the OBS UI. The allowed types are:

  • bool: A boolean variable
  • int: A signed 32-bit integer variable
  • float: A single precision floating point variable
  • float4/vec4: A color variable, shown as a color picker in the UI

Example:

#pragma shaderfilter set my_color__description My Color
#pragma shaderfilter set my_color__default 7FFF00FF
uniform float4 my_color;

See the examples directory for more examples.

Defining Properties in the Source Code

This plugin uses a simple preprocessor to process #pragma shaderfilter macros. It is not a fully-featured C preprocessor. It is executed before the shader is compiled. The shader compilation includes an actual C preprocessing step. Do not expect to be able to use macros within #pragma shaderfilter.

Most properties can be specified in the shader source code. The syntax is as follows:

#pragma shaderfilter set <PROPERTY> <VALUE>

Universal Properties

These properties can be applied to any user-defined uniform variable.

  • default: The default value of the uniform variable.
  • description: The user-facing text describing the variable. Displayed in the OBS UI.

Integer Properties

  • min (integer): The minimum allowed value
  • max (integer): The maximum allowed value
  • step (integer): The stride when changing the value
  • slider (true/false): Whether to display a slider or not

Float Properties

  • min (float): The minimum allowed value
  • max (float): The maximum allowed value
  • step (float): The stride when changing the value
  • slider (true/false): Whether to display a slider or not

FFT Properties

  • mix: The Mix/Track number corresponding to checkboxes in OBS' Advanced Audio Properties
  • channel: The channel number (0 = Left, 1 = Right for stereo)
  • dampening_factor_attack: The linear interpolation coefficient (in percentage) used to blend the previous FFT sample with the current sample, if it is larger than the previous
  • dampening_factor_release: The linear interpolation coefficient (in percentage) used to blend the previous FFT sample with the current sample, if it is lesser than the previous

Planned Features

  • Access to raw audio signal, without FFT
  • Specifying textures by a path to an image file

Development

Building

Windows

  1. Install Rust by following instructions at https://rustup.rs/
  2. Install CLang: Download and install the official pre-built binary from LLVM download page
  3. Compile OBS by following these instructions
    • This will require the installation of Visual Studio Build Tools 2019, Visual Studio Community 2019 and CMake.
      • Visual Studio Build Tools requirements:
        1. MSVC v142 - VS 2019 C++ x64/x86 build tools (v14.25) or later
        2. MSVC v142 - VS 2019 C++ x64/x86 Spectre-mitigated libs (v14.25) or later
      • Visual Studio Community 2019 requirements:
        1. MSVC v142 - VS 2019 C++ x64/x86 build tools (v14.25) or later
        2. MSVC v142 - VS 2019 C++ x64/x86 Spectre-mitigated libs (v14.25) or later
        3. C++ ATL for latest v142 build tools (x86 & x64) or later
        4. C++ ATL for latest v142 build tools with Spectre Mitigations (x86 & x64) or later
    • To configure OBS via cmake-gui, set the following variables:
      • DISABLE_PYTHON=TRUE, unless you are not getting errors while trying to build with Python enabled
  4. Compile OBS ShaderFilter Plus, replace <OBS_BUILD_DIR> with the path to the directory where you built OBS:
    set RUSTFLAGS=-L native=<OBS_BUILD_DIR>\libobs\Debug
    cargo build --release
  5. Move target/release/libobs_shaderfilter_plus.dll to the OBS plugin directory.

Linux

  1. Compile OBS by following these instructions.
  2. Add the directory in which libobs.so resides to the LD_LIBRARY_PATH environment variable.
  3. Install Rust (the package manager Cargo should be bundled with it)
  4. Clone this repository and open it in the terminal
  5. Compile using cargo build --release
  6. Move target/release/libobs_shaderfilter_plus.so to the OBS plugin directory.

Tips on building OBS (fish shell, Ubuntu)

These steps should not be necessary if you just want to compile OBS ShaderFilter Plus from source.

Ensure OBS is uninstalled using:

sudo apt remove obs-studio

Compile OBS using:

cmake -DUNIX_STRUCTURE=1 -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_BROWSER=ON -DCEF_ROOT_DIR="../../cef_binary_3770_linux64" ..; and make -j24; and sudo checkinstall --default --pkgname=obs-studio --fstrans=no --backup=no --pkgversion=(date +%Y%m%d)"-git" --deldoc=yes

Then recompile and install using:

make -j24; and sudo make install

obs-shaderfilter-plus's People

Contributors

limeth avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

obs-shaderfilter-plus's Issues

Example Shaders

Limeth, Is there a website that provides shaders that are compatible with the OBS Shader Plus plugin that you created? I'm looking fore more working examples that will work with the plugin. I'd like to build more examples for the OBS community. Your plugin is awesome and it deserves more love.

Invalid type 'mat4' used for assignment

Invalid type 'mat4' used for assignment.
it seems that it cant read mat4... and how do i choose glsl version without getting Unexpected token after preprocessor, expected newline error?

builtin_elapsed_time_since_shown not guaranteed to equal 0.0 when source is shown

Using the following simple (HLSL) shader:

float4 render(float2 uv0) {
    float4 p = image.Sample(builtin_texture_sampler, uv0);
    return lerp(p, float4(1.0, 0.0, 0.0, 1.0), builtin_elapsed_time_since_shown);
}

Expected result:
The output to transition from sampled input p to float4(1.0, 0.0, 0.0, 1.0) (solid red) over the course of one second, if builtin_elapsed_time_since_shown == 0.0 when the source is first shown and 1.0 one second later.

Observed:
When spamming the "show/hide" (eye) button in OBS, it works as expected (takes 1s to fade). However, when leaving the source hidden/visible for longer periods, the value of builtin_elapsed_time_since_shown when the source gets shown seems to start at a value between ~ 2.0 and 5.0 .

Unforunately I don't know enough about the functionality to know why it might be the case.

#else outside of #if/#ifdef/#ifndef block ???

I'm trying to make this shader (from https://www.shadertoy.com/view/Xsl3zn) work. :

#define PROCEDURAL 0

float4 render( float2 uv )
{
	float4 image_color = image.Sample(builtin_texture_sampler, uv);

#if PROCEDURAL==0
	vec2 warp = texture( image, uv*0.1 + builtin_elapsed_time*vec2(0.04,0.03) ).xz;
#else
	float freq = 3.0*sin(0.5*builtin_elapsed_time);
	vec2 warp = 0.5000*cos( uv.xy*1.0*freq + vec2(0.0,1.0) + builtin_elapsed_time ) +
				0.2500*cos( uv.yx*2.3*freq + vec2(1.0,2.0) + builtin_elapsed_time ) +
				0.1250*cos( uv.xy*4.1*freq + vec2(5.0,3.0) + builtin_elapsed_time ) +
				0.0625*cos( uv.yx*7.9*freq + vec2(3.0,4.0) + builtin_elapsed_time );
#endif

	float2 st = uv + warp*0.5;
	float4 new_image = image.Sample(builtin_texture_sampler, st);
	//~ new_image = vec4( texture( image_color, st ).xyz, 1.0 );
	return new_image;
}

The first problem that #if, #else and #endif lines are not working well:

Could not create the effect due to the following error: /home/mario/meytv/shaders/Warping - texture.glsl (30, 5): Unexpected token after preprocessor, expected newline
/home/mario/meytv/shaders/Warping - texture.glsl (32, 2): #else outside of #if/#ifdef/#ifndef block
/home/mario/meytv/shaders/Warping - texture.glsl (38, 2): #endif outside of #if/#ifdef/#ifndef block

[EDIT] Also, if I comment those lines and lines for PROCEDURAL==1 and I try to make the vec2 warp = texture(... line work, I get no error... but image is unmodified.
โ˜ This is erroneous: it does work, but the texture that it is used to warp the image does the job (with image moved up-right), and, finally, it dissapears... and then, image is not warped any more. It's a nice warpping effect... I would like it to work, but it isn't indispensable. So, it is not part of the bug.

Additional builtin variables

Would it be possible for some additional builtin variables to be added to this plug-in as described below? My motivation is that they would allow shaders to be automated in a sense based on stream-related actions.

  • Elapsed time since started outputting (whether streaming, recording, or otherwise). This would allow shaders to be written as a transition for the beginning of a stream or recording.
  • Elapsed time since scene became active. This would allow some transitions to be performed that may not be possible with OBSโ€™ current transition system.

How to install on Linux?

How do I install this properly?

I places the libobs_shaderfilter_plus_linux_x64.so file in my home/.config/obs-studio/plugins folder. That's the same folder I have the move-transition plugin in. But no shaderfilter shows up.

So why is this plugin not showing up in my filters?

Elapsed time & frames origin

Hi there,

I am trying to get a uniform of elapsed time from the moment that the source becomes visible. For example:

float4 render(float2 uv) {
    if (builtin_elapsed_time > 2.0) {
        return float4(1.0, 1.0, 1.0, 1.0);
    }
    return image.Sample(builtin_texture_sampler, uv);
}

Should render white after 2 seconds if I understood correctly. Instead, it always renders white. I also tried using builtin_frame.
I'm trying to get the shader to restart when the source/parent scene becomes visible.

Thanks!

Build fails on Linux: `FE_*` redefined here

error[E0428]: the name `FE_INVALID` is defined multiple times
    --> /home/fratti/Projekte/obs-shaderfilter-plus/target/release/build/obs-sys-0941a661be0ede12/out/bindings.rs:7844:1
     |
499  | pub const FE_INVALID: u32 = 1;
     | ------------------------------ previous definition of the value `FE_INVALID` here
...
7844 | pub const FE_INVALID: _bindgen_ty_3 = 1;
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `FE_INVALID` redefined here
     |
     = note: `FE_INVALID` must be defined only once in the value namespace of this module

error[E0428]: the name `FE_DIVBYZERO` is defined multiple times
    --> /home/fratti/Projekte/obs-shaderfilter-plus/target/release/build/obs-sys-0941a661be0ede12/out/bindings.rs:7846:1
     |
500  | pub const FE_DIVBYZERO: u32 = 4;
     | -------------------------------- previous definition of the value `FE_DIVBYZERO` here
...
7846 | pub const FE_DIVBYZERO: _bindgen_ty_3 = 4;
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `FE_DIVBYZERO` redefined here
     |
     = note: `FE_DIVBYZERO` must be defined only once in the value namespace of this module

error[E0428]: the name `FE_OVERFLOW` is defined multiple times
    --> /home/fratti/Projekte/obs-shaderfilter-plus/target/release/build/obs-sys-0941a661be0ede12/out/bindings.rs:7847:1
     |
501  | pub const FE_OVERFLOW: u32 = 8;
     | ------------------------------- previous definition of the value `FE_OVERFLOW` here
...
7847 | pub const FE_OVERFLOW: _bindgen_ty_3 = 8;
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `FE_OVERFLOW` redefined here
     |
     = note: `FE_OVERFLOW` must be defined only once in the value namespace of this module

error[E0428]: the name `FE_UNDERFLOW` is defined multiple times
    --> /home/fratti/Projekte/obs-shaderfilter-plus/target/release/build/obs-sys-0941a661be0ede12/out/bindings.rs:7848:1
     |
502  | pub const FE_UNDERFLOW: u32 = 16;
     | --------------------------------- previous definition of the value `FE_UNDERFLOW` here
...
7848 | pub const FE_UNDERFLOW: _bindgen_ty_3 = 16;
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `FE_UNDERFLOW` redefined here
     |
     = note: `FE_UNDERFLOW` must be defined only once in the value namespace of this module

error[E0428]: the name `FE_INEXACT` is defined multiple times
    --> /home/fratti/Projekte/obs-shaderfilter-plus/target/release/build/obs-sys-0941a661be0ede12/out/bindings.rs:7849:1
     |
503  | pub const FE_INEXACT: u32 = 32;
     | ------------------------------- previous definition of the value `FE_INEXACT` here
...
7849 | pub const FE_INEXACT: _bindgen_ty_3 = 32;
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `FE_INEXACT` redefined here
     |
     = note: `FE_INEXACT` must be defined only once in the value namespace of this module

error[E0428]: the name `FE_TONEAREST` is defined multiple times
    --> /home/fratti/Projekte/obs-shaderfilter-plus/target/release/build/obs-sys-0941a661be0ede12/out/bindings.rs:7851:1
     |
505  | pub const FE_TONEAREST: u32 = 0;
     | -------------------------------- previous definition of the value `FE_TONEAREST` here
...
7851 | pub const FE_TONEAREST: _bindgen_ty_4 = 0;
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `FE_TONEAREST` redefined here
     |
     = note: `FE_TONEAREST` must be defined only once in the value namespace of this module

error[E0428]: the name `FE_DOWNWARD` is defined multiple times
    --> /home/fratti/Projekte/obs-shaderfilter-plus/target/release/build/obs-sys-0941a661be0ede12/out/bindings.rs:7852:1
     |
506  | pub const FE_DOWNWARD: u32 = 1024;
     | ---------------------------------- previous definition of the value `FE_DOWNWARD` here
...
7852 | pub const FE_DOWNWARD: _bindgen_ty_4 = 1024;
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `FE_DOWNWARD` redefined here
     |
     = note: `FE_DOWNWARD` must be defined only once in the value namespace of this module

error[E0428]: the name `FE_UPWARD` is defined multiple times
    --> /home/fratti/Projekte/obs-shaderfilter-plus/target/release/build/obs-sys-0941a661be0ede12/out/bindings.rs:7853:1
     |
507  | pub const FE_UPWARD: u32 = 2048;
     | -------------------------------- previous definition of the value `FE_UPWARD` here
...
7853 | pub const FE_UPWARD: _bindgen_ty_4 = 2048;
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `FE_UPWARD` redefined here
     |
     = note: `FE_UPWARD` must be defined only once in the value namespace of this module

error[E0428]: the name `FE_TOWARDZERO` is defined multiple times
    --> /home/fratti/Projekte/obs-shaderfilter-plus/target/release/build/obs-sys-0941a661be0ede12/out/bindings.rs:7854:1
     |
508  | pub const FE_TOWARDZERO: u32 = 3072;
     | ------------------------------------ previous definition of the value `FE_TOWARDZERO` here
...
7854 | pub const FE_TOWARDZERO: _bindgen_ty_4 = 3072;
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `FE_TOWARDZERO` redefined here
     |
     = note: `FE_TOWARDZERO` must be defined only once in the value namespace of this module

For more information about this error, try `rustc --explain E0428`.
error: could not compile `obs-sys` due to 9 previous errors

Rust version:

$ rustc --version
rustc 1.65.0 (Arch Linux rust 1:1.65.0-1)

Empty Folders

A friend and I have both downloaded this and when trying to implement it in OBS the folders are empty so we can't apply any shaders

Add vertex shader support

As discussed in this PR, it would be desirable to add a proper way to specify entry points for the vertex stage. The mentioned PR successfully shadows the definition of builtin_shader_vertex from the template. Maybe we could abuse this technique to provide a more user-friendly way to optionally specify the logic for the vertex stage:

void vertex(inout float4 vertex, inout float2 uv)

shader that shakes the image

good day, I'm trying to use shaderfilter plus to create a shader that shakes the image coming from the camera, I have created some glsl shaders in the past for touchdesigner but I cannot manage to create one for shaderfilter plus, i get errors all the time; could anybody point me to a simple version of a shader that would shake the image continuously at a certain editable rhythm and that I can then tweak in here, thank you so much

Using compiled glsl shaders

How would you go about using precompiled shaders like the ones provided for example by bloc97/Anime4K?
I am not sure if this is something that is currently supported because when selecting the shader I seem to get a bunch Expected identifier errors.

A guide for rewriting Shadertoy shaders

I would like to use shaders in OBS, but I know Python, not shaders language.

Can I use shaders from pages as shadertoy, shaderfrog, etc? How should I do the code conversion to use with obs-shaderfilter-plus? For example, this is a simple one: https://thebookofshaders.com/edit.php

// Author:
// Title:

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

void main() {
    vec2 st = gl_FragCoord.xy/u_resolution.xy;
    st.x *= u_resolution.x/u_resolution.y;

    vec3 color = vec3(0.);
    color = vec3(st.x,st.y,abs(sin(u_time)));

    gl_FragColor = vec4(color,1.0);
}

I know that it has to has float4 render(float2 uv) { to work, but I don' know how... ๐Ÿ‘

I know this is not a bug, if it doesn't correspond here, you can delete this issue. Thanks.

Issues installing on Windows

Installation seemed pretty straightforward, I downloaded it and placed it in obs-plugins, in the 64bit folder. Did this with obs closed, and opened it after. Tried to add the filter to an image, but it didn't show up in the filters list. Tried with a few other types of sources, still nowhere to be found. How can I fix this?

On-Request Texture Buffers / Shader multi-pass & buffer access

I really appreciate the FFT source support. A feature I'd like to see is access to additional buffers we can write to, and retrieve in additional passes, in order to build more complex effects like the following examples:

https://www.shadertoy.com/view/3lKSz3
https://www.shadertoy.com/view/4tGfRd

In order to reduce development complexity, having access to the following on-request buffers would be a nice feature:

uniform texture2d image_previous;                 // previous frame of the source texture (same frame or blank if initialized)
uniform texture2d target_previous;                // shader output from the previous frame (as above)
uniform texture2d builtin_texture_source_<NAME>;  // selectable OBS source to use as additional texture

With access to additional sources, and previous pre-FX and post-FX texture buffers, most of the complex shader chains could be built using source mirrors and shader chaining.

Building on macOS

Hi there, I was wondering if anyone has tried to build this for macOS yet, or if there's any pointers that I might need to look at if I wanted to try.

I'm currently interested in building for x86_64, and I'm assuming building for ARM64 might be a different story.

Alternatively, if you happen to know an alternative (I know there's a few builds/versions of this floating around) that would work on macOS, I'd love to try that instead if this project doesn't support it. Appreciate any thoughts.


edit: having looked around a bit more, I found that exeldro/obs-shaderfilter works on Mac and has prebuilt releases, in case anyone would like to use this on Mac.

How to install with snap-managed OBS

Somewhat related to #30 and #35

Running snap info obs-studio shows:

name:      obs-studio
summary:   Free and open source software for live streaming and screen recording
publisher: Snapcrafters
store-url: https://snapcraft.io/obs-studio
contact:   https://github.com/snapcrafters/obs-studio/issues
license:   GPL-2.0
description: |
  OBS Studio is software designed for capturing, compositing, encoding, recording, and streaming
  video content, efficiently. _This is a community-supported modified build of OBS Studio; please
  file issues on the Snapcrafters GitHub:_ https://github.com/snapcrafters/obs-studio/issues
  
  **Batteries included**
  
  The snap of OBS studio comes pre-loaded with some extra features:
  
    * Supports **nvenc (NVIDIA) and VA-API (AMD & Intel) accelerated video encoding**.
    * **Advanced Scene Switcher** plugin; an automated scene switcher
    * **Browser** plugin; CEF-based OBS Studio browser plugin
    * **Directory Watch Media** plugin; filter you can add to a media source to load the oldest
    or newest file in a directory.
    * **Dynamic Delay** plugin; filter for dynamic delaying a video source.
    * **Freeze Filter** plugin; freeze a source using a filter.
    * **gPhoto** plugin; connect DSLR cameras with obs-studio via gPhoto.
    * **GStreamer** plugins; feed GStreamer launch pipelines into OBS Studio and use GStreamer
    encoder elements.
    * **Move Transition** plugin; move sources to a new position during a scene transition.
    * **NDI** plugin; Network A/V via NewTek's NDI.
    * **NvFBC** plugin; screen capture via NVIDIA FBC API. Requires NvFBC patches for Nvidia
    drivers for consumer-grade GPUs.
    * **RGB Levels** plugin; simple filter to adjust RGB levels.
    * **Source Switcher** plugin; to switch between a list of sources.
    * **Spectralizer** plugin; audio visualization using fftw.
    * **StreamFX** plugin; collection modern effects filters and transitions.
    * **Text Pango** plugin; Provides a text source rendered using Pango with multi-language
    support, emoji support, vertical rendering and RTL support.
    * **Transition Matrix** plugin; customize Any -> One or One -> One scene transitions.
    * **VNC Source** plugin; VNC viewer that works as a source.
    * **Websockets** plugin; remote-control OBS Studio through WebSockets.
  
  **Connecting Interfaces**
  
  For the best experience, you'll want to connect the following interfaces.
  
     sudo snap connect obs-studio:alsa
     sudo snap connect obs-studio:audio-record
     sudo snap connect obs-studio:avahi-control
     sudo snap connect obs-studio:camera
     sudo snap connect obs-studio:jack1
     sudo snap connect obs-studio:kernel-module-observe
  
  **NDI**
  
  If you want to use the NDI plugin you'll need to connect the Avahi Control interface.
  
     snap connect obs-studio:avahi-control
  
  **Virtual Camera**
  
  Starting with OBS 26.1.0, Virtual Camera support is integrated. Here's how to install and
  configure `v4l2loopback`:
  
     sudo snap connect obs-studio:kernel-module-observe
     sudo apt -y install v4l2loopback-dkms v4l2loopback-utils
     echo "options v4l2loopback devices=1 video_nr=13 card_label='OBS Virtual Camera'   
     exclusive_caps=1" | sudo tee /etc/modprobe.d/v4l2loopback.conf
     echo "v4l2loopback" | sudo tee /etc/modules-load.d/v4l2loopback.conf
     sudo modprobe -r v4l2loopback
     sudo modprobe v4l2loopback devices=1 video_nr=13 card_label='OBS Virtual Camera'
     exclusive_caps=1
  
  **NOTE!** Using `video_nr` greater than 64 will not work.
  
  **Removable Storage**
  
  To access content on external storage, connect to the removable-media plug:
  
     snap connect obs-studio:removable-media
  
  **gPhoto**
  
  The gPhoto plugin allows some DSLR cameras to be connected via USB. You'll need to connect the
  Raw USB interface.
  
     snap connect obs-studio:raw-usb
  
  **3rd Party plugins**
  
  To install pre-compiled plugins, download and extract the plugin to
  `~/snap/obs-studio/current/.config/obs-studio/plugins/`.
  
  This is how the Input Overlay plugin looks when correctly installed:
  
     /home/username/snap/obs-studio/current/.config/obs-studio/plugins/
     โ””โ”€โ”€ input-overlay
         โ”œโ”€โ”€ bin
         โ”‚ย ย  โ””โ”€โ”€ 64bit
         โ”‚ย ย      โ””โ”€โ”€ input-overlay.so
         โ””โ”€โ”€ data
             โ””โ”€โ”€ locale
                 โ”œโ”€โ”€ de-DE.ini
                 โ”œโ”€โ”€ en-US.ini
                 โ””โ”€โ”€ ru-RU.ini
  
  If you want to use the Input Overlay plugin, you'll also need to connect the joystick
  interface:
  
     snap connect obs-studio:joystick
commands:
  - obs-studio.eglinfo
  - obs-studio.ffmpeg
  - obs-studio.ffplay
  - obs-studio.ffprobe
  - obs-studio.glxinfo
  - obs-studio
  - obs-studio.srt-ffplay
  - obs-studio.srt-file-transmit
  - obs-studio.srt-live-transmit
  - obs-studio.srt-tunnel
  - obs-studio.vainfo
  - obs-studio.vdpauinfo
  - obs-studio.vulkaninfo
snap-id:      6uLU2MJmBURfLNz4rmL4WT2CmtVULE2u
tracking:     latest/stable
refresh-date: 2022-02-08
channels:
  latest/stable:    27.1.3 2021-12-20 (1284) 418MB -
  latest/candidate: โ†‘                              
  latest/beta:      โ†‘                              
  latest/edge:      27.2.1 2022-02-24 (1287) 439MB -
installed:          27.1.3            (1284) 418MB -

Of particular interest is:

  **3rd Party plugins**
  
  To install pre-compiled plugins, download and extract the plugin to
  `~/snap/obs-studio/current/.config/obs-studio/plugins/`.
  
  This is how the Input Overlay plugin looks when correctly installed:
  
     /home/username/snap/obs-studio/current/.config/obs-studio/plugins/
     โ””โ”€โ”€ input-overlay
         โ”œโ”€โ”€ bin
         โ”‚   โ””โ”€โ”€ 64bit
         โ”‚       โ””โ”€โ”€ input-overlay.so
         โ””โ”€โ”€ data
             โ””โ”€โ”€ locale
                 โ”œโ”€โ”€ de-DE.ini
                 โ”œโ”€โ”€ en-US.ini
                 โ””โ”€โ”€ ru-RU.ini

I've extracted the .so file to either:

$ find /home/$USER/snap/obs-studio/current/.config/obs-studio/plugins
/home/opyate/snap/obs-studio/current/.config/obs-studio/plugins
/home/opyate/snap/obs-studio/current/.config/obs-studio/plugins/shaderfilter-plus
/home/opyate/snap/obs-studio/current/.config/obs-studio/plugins/shaderfilter-plus/bin
/home/opyate/snap/obs-studio/current/.config/obs-studio/plugins/shaderfilter-plus/bin/64bit
/home/opyate/snap/obs-studio/current/.config/obs-studio/plugins/shaderfilter-plus/bin/64bit/libobs_shaderfilter_plus_linux_x64.so

And:

$ find /home/$USER/snap/obs-studio/current/.config/obs-studio/plugins/
/home/opyate/snap/obs-studio/current/.config/obs-studio/plugins/
/home/opyate/snap/obs-studio/current/.config/obs-studio/plugins/libobs_shaderfilter_plus_linux_x64.so

...but in neither location does ShaderFilter Plus show up in my effects options.

Open "Discussions" to share ShaderFilter-Plus shaders?

I know that @NetherEran wrote some nice shaders to use with this plugin. I transported some others... it would be greate to have a place to share this kind of shaders.

If someone needs help about transporting from another shaders platforms, we can use Discussion also for it.

Main Mix/Track for FFT data always uses first track

This might be a bug - I cannot get FFT data to listen to any other track than Track 1.

In the following screenshots Track 5 is selected, and right now Track 5 is silent, there should be no shader effects.
image
image

The pragmas in both shaders are defined as such:

#pragma shaderfilter set main__mix__description Main Mix/Track
#pragma shaderfilter set main__channel__description Main Channel
#pragma shaderfilter set main__dampening_factor_attack 0.0005
#pragma shaderfilter set main__dampening_factor_release 0.01
uniform texture2d builtin_texture_fft_main;
uniform texture2d builtin_texture_fft_main_previous;

Issues installing on Linux

I'm trying to install shaderfilter-plus after switching to Linux recently, and I'm having issues installing it. I read through the readme and #30, but I don't have the folders mentioned in either of those. I tried putting it in /obs-studio/plugins/ to no avail. I'm using the Flatpak version if that changes anything.

UVs with stacked shaders

I have been trying out shaderfilter-plus for a few days now (and it's great !) and I stumbled upon a behavior that I'm not sure if it's a bug or by design.

I'm trying to build generic effects that I can re-use over different sources in OBS and also to make the shaders easier to manage and maintain. So I built a first shader that applies an animated gradient by manipulating the UV coordinates. Then I added a second shader to perform another kind of gradient/UV based animation.

Current behavior:
When shaders are stacked, it seems the second shader inherit the UVs from the previous one (or something alike).

Expected behavior:
When shaders are stacked, the given uv variable at the entry or render() should give the same values with or without stacked shaders.

  • Shaderfilter-plus version : 0.1.3
  • OBS Version : 25.0.8-1
  • OS : Linux, Manjaro
  • GPU : AMD Radeon RX 5600 XT
  • Drivers/Versions : NAVI10, DRM 3.36.0, 5.6.16-1-MANJARO, LLVM 10.0.0, Mesa 20.1.3

The current behavior prevent the creation of effects based on multiple pass (like separable/box blurs) and make other effects difficult to build if you have to take into account previous shaders.

Demo of the behavior


Simple Shader code to replicate that behavior:

Shader 1

float4 render(float2 uv)
{
	vec4 Result = image.Sample(builtin_texture_sampler, uv);
	float Mask = fract( uv.x + builtin_elapsed_time * 2.0 );
	Mask = abs( Mask * 2.0 - 1.0 );

	Result.rgb *= Mask;
	return Result;
}

Shader 2

float4 render(float2 uv)
{
	return vec4( uv.x, uv.y, 0.0, 1.0 );
}

builtin_elapsed_time_since_shown uniform bug/question

Hi there,

The uniform builtin_elapsed_time_since_shown added in one of the patches creates a timer which gets refreshed when the source it's applied to is hidden and shown. I was wondering if it is possible to have this uniform (or a seperate one) which refreshes when the filter itself is hidden and shown?

This would allow the user to "restart" the shader filter without having to hide/show the source itself, as the current implementation requires that the source will flicker off when the visibility of the source is toggled.

Thanks!

glsl example

First, thanks to limeth!!! I am really appreciate your work on this plugin for obs.

I do have some filters that I want to use for in glsl format.

However, when I added then, it tells me that error(#202) No matching overloaded function found: HOOKED_tex

I would like to know the correct way to write the file and any conversion parametres/variables for shaderfilter plus.

I attached the filter code I use in this issue. If you have time, anyone who has time please have a look.

code:

//Anime4K v3.1 GLSL

// MIT License

// Copyright (c) 2019-2020 bloc97
// All rights reserved.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

//!DESC Anime4K-v3.1-Upscale(x2)-CNN(M)-Conv-4x3x3x1
//!HOOK NATIVE
//!BIND HOOKED
//!WHEN OUTPUT.w NATIVE.w / 1.200 > OUTPUT.h NATIVE.h / 1.200 > *
//!SAVE LUMAN0
//!COMPONENTS 4


vec4 hook() {
	vec2 dp = HOOKED_pt;
	float a = HOOKED_tex(HOOKED_pos + vec2(-dp.x, -dp.y)).x;
	float b = HOOKED_tex(HOOKED_pos + vec2(-dp.x, 0)).x;
	float c = HOOKED_tex(HOOKED_pos + vec2(-dp.x, dp.y)).x;
	float d = HOOKED_tex(HOOKED_pos + vec2(0, -dp.y)).x;
	float e = HOOKED_tex(HOOKED_pos + vec2(0, 0)).x;
	float f = HOOKED_tex(HOOKED_pos + vec2(0, dp.y)).x;
	float g = HOOKED_tex(HOOKED_pos + vec2(dp.x, -dp.y)).x;
	float h = HOOKED_tex(HOOKED_pos + vec2(dp.x, 0)).x;
	float i = HOOKED_tex(HOOKED_pos + vec2(dp.x, dp.y)).x;

	float s = -0.09440448*a + 0.49120164*b + -0.022703001*c + -0.016553257*d + 0.6272513*e + -0.97632706*f + 0.10815585*g + -0.21898738*h + 0.09604159*i;
	float o = s+0.00028890301;
	s = 0.061990097*a + -0.87003845*b + -0.037461795*c + 0.13172528*d + 0.87585527*e + -0.13609451*f + -0.070119604*g + -0.051131595*h + 0.09209152*i;
	float p = s+-0.017290013;
	s = 0.45264956*a + -1.1240269*b + 0.07975403*c + 0.6734861*d + -0.05388544*e + 0.007570164*f + -0.06987841*g + 0.012247365*h + 0.034949988*i;
	float q = s+-0.0145500265;
	s = -0.035659406*a + 0.043313805*b + -0.056556296*c + 0.08745333*d + 0.6312519*e + -0.24501355*f + -0.13407958*g + -0.18634492*h + -0.08149098*i;
	float r = s+-0.009025143;

	return vec4(o, p, q, r);
}


//!DESC Anime4K-v3.1-Upscale(x2)-CNN(M)-Conv-4x3x3x8
//!HOOK NATIVE
//!BIND HOOKED
//!WHEN OUTPUT.w NATIVE.w / 1.200 > OUTPUT.h NATIVE.h / 1.200 > *
//!BIND LUMAN0
//!SAVE LUMAN1
//!COMPONENTS 4

#define L_tex LUMAN0_tex

vec4 hook() {
	vec2 dp = HOOKED_pt;
	vec4 a = L_tex(HOOKED_pos + vec2(-dp.x, -dp.y));
	vec4 b = L_tex(HOOKED_pos + vec2(-dp.x, 0));
	vec4 c = L_tex(HOOKED_pos + vec2(-dp.x, dp.y));
	vec4 d = L_tex(HOOKED_pos + vec2(0, -dp.y));
	vec4 e = L_tex(HOOKED_pos + vec2(0, 0));
	vec4 f = L_tex(HOOKED_pos + vec2(0, dp.y));
	vec4 g = L_tex(HOOKED_pos + vec2(dp.x, -dp.y));
	vec4 h = L_tex(HOOKED_pos + vec2(dp.x, 0));
	vec4 i = L_tex(HOOKED_pos + vec2(dp.x, dp.y));
	
	vec4 na = -min(a, 0);
	vec4 nb = -min(b, 0);
	vec4 nc = -min(c, 0);
	vec4 nd = -min(d, 0);
	vec4 ne = -min(e, 0);
	vec4 nf = -min(f, 0);
	vec4 ng = -min(g, 0);
	vec4 nh = -min(h, 0);
	vec4 ni = -min(i, 0);
	
	a = max(a, 0);
	b = max(b, 0);
	c = max(c, 0);
	d = max(d, 0);
	e = max(e, 0);
	f = max(f, 0);
	g = max(g, 0);
	h = max(h, 0);
	i = max(i, 0);
	
	float s = -0.05327107*a.x + -0.07160779*b.x + -0.053545203*c.x + 0.30653647*d.x + -0.623205*e.x + -0.25135925*f.x + -0.18046309*g.x + 0.5326353*h.x + -0.09099461*i.x;
	float t = -0.16687301*a.y + 0.29383695*b.y + -0.15116534*c.y + 0.013435781*d.y + -0.3595954*e.y + 0.3222953*f.y + 0.20127103*g.y + 1.1504021*h.y + 0.6521217*i.y;
	float u = -0.0015649797*a.z + -0.18814865*b.z + 0.061695296*c.z + 0.013806492*d.z + 0.12745698*e.z + -0.30406427*f.z + -0.05947408*g.z + 0.33141926*h.z + -0.20066342*i.z;
	float v = 0.30095318*a.w + 0.36586058*b.w + 0.22645043*c.w + 0.1612967*d.w + -0.37834042*e.w + -0.08229078*f.w + -0.64827895*g.w + 0.04798959*h.w + 0.50426966*i.w;
	float w = 0.126555*na.x + 0.079004966*nb.x + -0.06367056*nc.x + -0.16546968*nd.x + 0.50795466*ne.x + 0.18011826*nf.x + 0.16996312*ng.x + -0.51605004*nh.x + 0.10505295*ni.x;
	float x = 0.1540833*na.y + -0.26913214*nb.y + 0.13605806*nc.y + -0.12155722*nd.y + 0.21405062*ne.y + -0.27972937*nf.y + -0.41382065*ng.y + -1.7224138*nh.y + -0.60294384*ni.y;
	float y = 0.00970452*na.z + 0.20325865*nb.z + 0.0015745827*nc.z + -0.107312985*nd.z + 0.009980262*ne.z + 0.2720558*nf.z + 0.15321876*ng.z + -0.036781967*nh.z + 0.051229585*ni.z;
	float z = -0.27454868*na.w + -0.4432009*nb.w + -0.003881375*nc.w + 0.18336153*nd.w + 0.19950926*ne.w + 0.045014136*nf.w + 0.6243142*ng.w + -0.16252244*nh.w + -0.42274413*ni.w;
	float o = s+t+u+v+w+x+y+z+0.039423503;
	s = -0.10775202*a.x + -0.031339962*b.x + 0.0060642078*c.x + -0.10545187*d.x + 0.12458454*e.x + 0.0021231163*f.x + 0.07905482*g.x + 0.08223747*h.x + 0.04828753*i.x;
	t = 0.13271476*a.y + -0.40485632*b.y + 0.054641176*c.y + -0.4327063*d.y + -0.19545476*e.y + 0.09262824*f.y + -0.36247733*g.y + 0.12627794*h.y + -0.075792745*i.y;
	u = -0.09226349*a.z + 0.24326*b.z + -0.021355193*c.z + 0.1444612*d.z + -0.102547936*e.z + 0.05568293*f.z + 0.013875915*g.z + 0.19688046*h.z + 0.0154764345*i.z;
	v = -0.1431215*a.w + -0.26233566*b.w + -0.020626735*c.w + 0.019540034*d.w + 0.18164286*e.w + -0.16356231*f.w + 0.17014627*g.w + -0.27788106*h.w + 0.0718594*i.w;
	w = 0.20348297*na.x + 0.10994786*nb.x + 0.014990544*nc.x + 1.033602*nd.x + 0.024537617*ne.x + 0.009609228*nf.x + 0.12779616*ng.x + 0.06813842*nh.x + -0.04269685*ni.x;
	x = -0.2430749*na.y + 0.37466663*nb.y + -0.06150604*nc.y + 0.28204092*nd.y + 0.22226551*ne.y + -0.19715464*nf.y + 0.003657579*ng.y + -0.30363604*nh.y + 0.0542432*ni.y;
	y = 0.1447509*na.z + -0.28650913*nb.z + -0.058723953*nc.z + -0.092879236*nd.z + 0.26428574*ne.z + -0.104749136*nf.z + -0.070094705*ng.z + 0.047571726*nh.z + -0.010061374*ni.z;
	z = 0.0438258*na.w + 0.34031448*nb.w + -0.013600149*nc.w + 0.28250962*nd.w + -0.73591596*ne.w + 0.21241076*nf.w + -0.27542746*ng.w + 0.14023423*nh.w + -0.10678145*ni.w;
	float p = s+t+u+v+w+x+y+z+-0.021502364;
	s = 0.032163877*a.x + -0.66642886*b.x + 0.044751197*c.x + 0.05605561*d.x + 0.6945027*e.x + -0.07645503*f.x + -0.04662916*g.x + -0.2509118*h.x + 0.098923184*i.x;
	t = 0.03268785*a.y + 0.2343848*b.y + -0.058907576*c.y + -0.6397386*d.y + -0.15121439*e.y + 0.15354797*f.y + -0.3191564*g.y + -0.24138322*h.y + -0.71516746*i.y;
	u = -0.069602974*a.z + -0.4111596*b.z + 0.021718252*c.z + 0.2399502*d.z + 0.64263207*e.z + 0.3311527*f.z + -0.2513218*g.z + -0.48004037*h.z + 0.78069997*i.z;
	v = -0.6631432*a.w + 0.15360248*b.w + 0.012449814*c.w + -0.9210798*d.w + 0.77063346*e.w + 0.10402895*f.w + 0.26728597*g.w + -0.3063174*h.w + 0.07107563*i.w;
	w = -0.22910015*na.x + 0.60668314*nb.x + -0.07472177*nc.x + -0.2976557*nd.x + -0.31179214*ne.x + 0.17979208*nf.x + -0.059973676*ng.x + 0.48262063*nh.x + 0.10012325*ni.x;
	x = -0.008694405*na.y + -0.19812866*nb.y + 0.024916848*nc.y + 0.57730144*nd.y + 0.20505147*ne.y + -0.22297408*nf.y + 0.09352177*ng.y + -0.548608*nh.y + 0.56032515*ni.y;
	y = 0.05522713*na.z + 0.3843459*nb.z + -0.017952677*nc.z + -0.24958606*nd.z + -0.641729*ne.z + -0.13842992*nf.z + 0.20486256*ng.z + 0.24058507*nh.z + -0.53553283*ni.z;
	z = 0.7243502*na.w + -0.16880396*nb.w + 0.11347028*nc.w + 0.98730826*nd.w + -0.4131502*ne.w + -0.605653*nf.w + -0.20231946*ng.w + 0.268739*nh.w + -0.25494024*ni.w;
	float q = s+t+u+v+w+x+y+z+-0.011375127;
	s = 0.004939782*a.x + 0.04961287*b.x + -0.022315059*c.x + -0.36721465*d.x + 0.02673542*e.x + -0.055127766*f.x + -0.3139398*g.x + 0.011177372*h.x + -0.002486109*i.x;
	t = 0.0029139163*a.y + -0.018279694*b.y + 0.23850645*c.y + -0.053427566*d.y + -0.19388364*e.y + 0.25149515*f.y + -0.15969065*g.y + 0.003607878*h.y + 0.47864768*i.y;
	u = 0.018587857*a.z + 0.04256821*b.z + -0.084889054*c.z + -0.10649675*d.z + 0.1413508*e.z + -0.014863062*f.z + 0.046072394*g.z + 0.044705987*h.z + -0.3495728*i.z;
	v = -0.25952607*a.w + -0.37138674*b.w + -0.31769684*c.w + -0.47086135*d.w + 0.4518305*e.w + 0.23906761*f.w + 0.37785494*g.w + -0.12342203*h.w + -0.18958518*i.w;
	w = -0.0987012*na.x + -0.23680592*nb.x + -0.038128883*nc.x + 0.021003952*nd.x + -0.21279961*ne.x + 0.02450331*nf.x + 0.22508678*ng.x + -0.050619982*nh.x + -0.12929344*ni.x;
	x = 0.024458453*na.y + 0.07273773*nb.y + -0.26048952*nc.y + 0.18460196*nd.y + 0.4304707*ne.y + -0.17272879*nf.y + 0.28351468*ng.y + 1.3116083*nh.y + -0.29540524*ni.y;
	y = -0.041094407*na.z + 0.024719454*nb.z + 0.19896787*nc.z + 0.07664201*nd.z + -0.25621203*ne.z + 0.10749328*nf.z + -0.067182586*ng.z + 0.06065049*nh.z + 0.47074008*ni.z;
	z = 0.13518347*na.w + 0.20488833*nb.w + 0.24956091*nc.w + 0.07386013*nd.w + -0.9938687*ne.w + -0.15375653*nf.w + -0.55804706*ng.w + -0.0036114866*nh.w + 0.3378182*ni.w;
	float r = s+t+u+v+w+x+y+z+-0.047199935;

	return vec4(o, p, q, r);
}

//!DESC Anime4K-v3.1-Upscale(x2)-CNN(M)-Conv-4x3x3x8
//!HOOK NATIVE
//!BIND HOOKED
//!WHEN OUTPUT.w NATIVE.w / 1.200 > OUTPUT.h NATIVE.h / 1.200 > *
//!BIND LUMAN1
//!SAVE LUMAN2
//!COMPONENTS 4

#define L_tex LUMAN1_tex

vec4 hook() {
	vec2 dp = HOOKED_pt;
	vec4 a = L_tex(HOOKED_pos + vec2(-dp.x, -dp.y));
	vec4 b = L_tex(HOOKED_pos + vec2(-dp.x, 0));
	vec4 c = L_tex(HOOKED_pos + vec2(-dp.x, dp.y));
	vec4 d = L_tex(HOOKED_pos + vec2(0, -dp.y));
	vec4 e = L_tex(HOOKED_pos + vec2(0, 0));
	vec4 f = L_tex(HOOKED_pos + vec2(0, dp.y));
	vec4 g = L_tex(HOOKED_pos + vec2(dp.x, -dp.y));
	vec4 h = L_tex(HOOKED_pos + vec2(dp.x, 0));
	vec4 i = L_tex(HOOKED_pos + vec2(dp.x, dp.y));
	
	vec4 na = -min(a, 0);
	vec4 nb = -min(b, 0);
	vec4 nc = -min(c, 0);
	vec4 nd = -min(d, 0);
	vec4 ne = -min(e, 0);
	vec4 nf = -min(f, 0);
	vec4 ng = -min(g, 0);
	vec4 nh = -min(h, 0);
	vec4 ni = -min(i, 0);
	
	a = max(a, 0);
	b = max(b, 0);
	c = max(c, 0);
	d = max(d, 0);
	e = max(e, 0);
	f = max(f, 0);
	g = max(g, 0);
	h = max(h, 0);
	i = max(i, 0);

	float s = 0.062563986*a.x + 0.7022818*b.x + -0.011810557*c.x + 0.25277942*d.x + -0.2097257*e.x + 0.17233184*f.x + -0.28609228*g.x + -0.32957354*h.x + -0.11091415*i.x;
	float t = 0.0074290223*a.y + 0.25707433*b.y + 0.02356039*c.y + -0.0033311683*d.y + 0.78796846*e.y + -0.8613285*f.y + 0.020431397*g.y + -0.014993784*h.y + -0.5224642*i.y;
	float u = -0.099318005*a.z + 0.096692294*b.z + -0.081225544*c.z + 0.4837614*d.z + 0.40215006*e.z + 0.06631713*f.z + -0.28298393*g.z + -0.15690443*h.z + -0.11722153*i.z;
	float v = -0.20104708*a.w + 0.29773432*b.w + -0.059524678*c.w + 0.672484*d.w + 0.58850944*e.w + 0.19088581*f.w + 0.085560724*g.w + -0.3429526*h.w + -0.01970963*i.w;
	float w = 0.2530852*na.x + -0.26206517*nb.x + -0.0087517025*nc.x + -0.33815455*nd.x + -0.00843703*ne.x + -0.22927909*nf.x + -0.062886484*ng.x + 0.17524554*nh.x + -0.008373106*ni.x;
	float x = 0.17741594*na.y + -0.52788115*nb.y + -0.10984838*nc.y + -0.13678722*nd.y + -0.28618953*ne.y + 0.1595905*nf.y + -0.04411071*ng.y + -0.3234863*nh.y + 0.4967709*ni.y;
	float y = 0.042347442*na.z + 0.08541207*nb.z + -0.15857157*nc.z + -0.30902776*nd.z + -0.8957161*ne.z + -0.29276812*nf.z + 0.47053015*ng.z + 0.6092259*nh.z + 0.31623343*ni.z;
	float z = 0.17963913*na.w + -0.30821583*nb.w + 0.15316938*nc.w + -0.37125722*nd.w + -0.5975526*ne.w + -0.07182377*nf.w + 0.069451295*ng.w + 0.61750644*nh.w + 0.07411387*ni.w;
	float o = s+t+u+v+w+x+y+z+0.025282431;
	s = 0.15042752*a.x + 0.76578605*b.x + 0.15916896*c.x + 0.062038895*d.x + 0.90041196*e.x + 0.44829968*f.x + -0.1525204*g.x + -0.0769386*h.x + -0.017208606*i.x;
	t = -0.24956173*a.y + -0.4890138*b.y + -0.5667875*c.y + -0.04361386*d.y + -1.2683009*e.y + 0.49874577*f.y + -0.023511255*g.y + -0.44963378*h.y + -0.44784302*i.y;
	u = -0.4755887*a.z + 0.5499969*b.z + -0.40806842*c.z + 0.18438272*d.z + -0.24848352*e.z + -0.6397795*f.z + -0.26359263*g.z + 0.48188695*h.z + 0.4296102*i.z;
	v = -0.42948166*a.w + 0.47963342*b.w + 0.2660744*c.w + 0.009006623*d.w + -0.20249301*e.w + 0.3191499*f.w + -0.009933394*g.w + 0.022085298*h.w + -0.05937115*i.w;
	w = 0.39071006*na.x + 0.96707124*nb.x + 0.5870382*nc.x + -0.0009634084*nd.x + -0.60501117*ne.x + -0.26205206*nf.x + 0.0022803913*ng.x + 0.19914602*nh.x + -0.0075327456*ni.x;
	x = 0.6501524*na.y + -0.6191325*nb.y + 0.033584982*nc.y + -0.23792362*nd.y + 0.28443542*ne.y + 0.7995467*nf.y + 0.61443925*ng.y + -0.2151685*nh.y + -0.64213204*ni.y;
	y = -0.028933166*na.z + -0.8038524*nb.z + -0.89384586*nc.z + -0.5202012*nd.z + 0.2658711*ne.z + -0.9662124*nf.z + 0.16669375*ng.z + 0.00071032986*nh.z + -0.15632267*ni.z;
	z = 0.04982121*na.w + 0.3209018*nb.w + -0.18828197*nc.w + 0.09291354*nd.w + -0.17046586*ne.w + -0.34567246*nf.w + -0.30839518*ng.w + 0.10585062*nh.w + 0.21802926*ni.w;
	float p = s+t+u+v+w+x+y+z+-0.038783036;
	s = -0.0086537115*a.x + 0.29274273*b.x + -0.14299169*c.x + 0.24355909*d.x + 0.44158313*e.x + 0.3856316*f.x + 0.1826302*g.x + 0.0468175*h.x + 0.08368182*i.x;
	t = -0.0030031276*a.y + -0.25766936*b.y + -0.16684678*c.y + -0.07155021*d.y + 0.49751604*e.y + 0.51993954*f.y + -0.055723842*g.y + -0.20152062*h.y + -0.3310546*i.y;
	u = -0.19360077*a.z + 0.29092705*b.z + -0.14313088*c.z + -0.12219053*d.z + 0.3336699*e.z + 0.19800198*f.z + 0.12873465*g.z + 0.16162138*h.z + 0.05346552*i.z;
	v = -0.12214463*a.w + -0.32187235*b.w + -0.4942458*c.w + 0.047901243*d.w + 0.1315279*e.w + 0.25730842*f.w + -0.03230636*g.w + -0.35371637*h.w + -0.16514161*i.w;
	w = 0.06874291*na.x + -0.19512849*nb.x + 0.4657543*nc.x + -0.031914163*nd.x + 0.37405568*ne.x + 0.15239602*nf.x + -0.023567*ng.x + 0.31183028*nh.x + 0.0394527*ni.x;
	x = -0.07513823*na.y + 0.041872643*nb.y + 0.35610527*nc.y + -0.1445567*nd.y + -1.024163*ne.y + -0.6282327*nf.y + 0.06843732*ng.y + 0.009273292*nh.y + -0.23500894*ni.y;
	y = 0.10864135*na.z + -0.25950822*nb.z + -0.27286842*nc.z + -0.0922535*nd.z + -0.49195388*ne.z + -0.9883521*nf.z + -0.16378482*ng.z + -0.44275576*nh.z + -0.19259977*ni.z;
	z = -0.07329517*na.w + 0.73912215*nb.w + -0.27922824*nc.w + -0.19892885*nd.w + -0.029165866*ne.w + -0.64475375*nf.w + -0.1735304*ng.w + 0.030360926*nh.w + 0.023611842*ni.w;
	float q = s+t+u+v+w+x+y+z+0.0059805913;
	s = 0.0520063*a.x + 0.32099065*b.x + 0.10096528*c.x + -0.3286558*d.x + 0.21782263*e.x + -0.16726571*f.x + -0.0061505553*g.x + -0.006116407*h.x + 0.04923024*i.x;
	t = -0.0034328692*a.y + -0.093817174*b.y + -0.16234896*c.y + 0.070740886*d.y + 0.09283234*e.y + -0.5086407*f.y + 0.14033465*g.y + 0.2656622*h.y + -0.069810264*i.y;
	u = 0.0036944423*a.z + -0.12574191*b.z + -0.05118089*c.z + -0.57802665*d.z + 0.7782018*e.z + -0.50453955*f.z + 0.020464642*g.z + 0.036232006*h.z + 0.07828021*i.z;
	v = 0.14491023*a.w + -0.08246158*b.w + 0.0048284433*c.w + -0.41679582*d.w + -0.37185597*e.w + -0.5086088*f.w + -0.101141416*g.w + 0.021782609*h.w + 0.024443237*i.w;
	w = -0.09724159*na.x + -0.13913961*nb.x + 0.13188085*nc.x + 0.4496926*nd.x + -0.2343041*ne.x + 0.30554664*nf.x + 0.10852492*ng.x + 0.09672956*nh.x + 0.06470584*ni.x;
	x = -0.22092621*na.y + -0.17034335*nb.y + -0.46865875*nc.y + -0.16638382*nd.y + -0.36817726*ne.y + 2.8126082*nf.y + 0.20136675*ng.y + -0.028155493*nh.y + -0.6738389*ni.y;
	y = 0.08178478*na.z + -0.13104321*nb.z + -0.0031215427*nc.z + 0.25492746*nd.z + -0.6011733*ne.z + 1.2705562*nf.z + -0.053312294*ng.z + 0.04038377*nh.z + -0.21168794*ni.z;
	z = -0.26104185*na.w + 0.24431077*nb.w + 0.44925603*nc.w + 0.23646158*nd.w + 0.45555523*ne.w + 0.9546111*nf.w + -0.24485165*ng.w + -0.13658847*nh.w + 0.033205047*ni.w;
	float r = s+t+u+v+w+x+y+z+-0.039946888;
	
	return vec4(o, p, q, r);
}

//!DESC Anime4K-v3.1-Upscale(x2)-CNN(M)-Conv-4x3x3x8
//!HOOK NATIVE
//!BIND HOOKED
//!WHEN OUTPUT.w NATIVE.w / 1.200 > OUTPUT.h NATIVE.h / 1.200 > *
//!BIND LUMAN2
//!SAVE LUMAN3
//!COMPONENTS 4

#define L_tex LUMAN2_tex

vec4 hook() {
	vec2 dp = HOOKED_pt;
	vec4 a = L_tex(HOOKED_pos + vec2(-dp.x, -dp.y));
	vec4 b = L_tex(HOOKED_pos + vec2(-dp.x, 0));
	vec4 c = L_tex(HOOKED_pos + vec2(-dp.x, dp.y));
	vec4 d = L_tex(HOOKED_pos + vec2(0, -dp.y));
	vec4 e = L_tex(HOOKED_pos + vec2(0, 0));
	vec4 f = L_tex(HOOKED_pos + vec2(0, dp.y));
	vec4 g = L_tex(HOOKED_pos + vec2(dp.x, -dp.y));
	vec4 h = L_tex(HOOKED_pos + vec2(dp.x, 0));
	vec4 i = L_tex(HOOKED_pos + vec2(dp.x, dp.y));
	
	vec4 na = -min(a, 0);
	vec4 nb = -min(b, 0);
	vec4 nc = -min(c, 0);
	vec4 nd = -min(d, 0);
	vec4 ne = -min(e, 0);
	vec4 nf = -min(f, 0);
	vec4 ng = -min(g, 0);
	vec4 nh = -min(h, 0);
	vec4 ni = -min(i, 0);
	
	a = max(a, 0);
	b = max(b, 0);
	c = max(c, 0);
	d = max(d, 0);
	e = max(e, 0);
	f = max(f, 0);
	g = max(g, 0);
	h = max(h, 0);
	i = max(i, 0);

	float s = -0.10675473*a.x + -0.0054621263*b.x + 0.04762056*c.x + -0.09147545*d.x + -0.37308994*e.x + 0.293996*f.x + -0.089725204*g.x + 0.33136362*h.x + -0.052014586*i.x;
	float t = 0.02504269*a.y + -0.06090801*b.y + -1.0442187e-05*c.y + 0.06697992*d.y + -0.029154606*e.y + -0.0022566947*f.y + -0.00791601*g.y + 0.09337469*h.y + -0.040103186*i.y;
	float u = 0.21693788*a.z + -0.055160753*b.z + -0.009791719*c.z + -0.333904*d.z + 0.27527252*e.z + -0.12840816*f.z + -0.18639135*g.z + -0.13602877*h.z + 0.06346381*i.z;
	float v = -0.03963725*a.w + -0.26795068*b.w + 0.012137692*c.w + -0.17869234*d.w + -0.06644175*e.w + 0.010630859*f.w + -0.07681673*g.w + -0.0041983854*h.w + -0.026523955*i.w;
	float w = 0.13531718*na.x + 0.12938923*nb.x + -0.050681178*nc.x + 0.062877566*nd.x + -0.08772176*ne.x + 0.006759793*nf.x + 0.15809533*ng.x + -0.08294619*nh.x + 0.06690071*ni.x;
	float x = 0.018558182*na.y + -0.16493246*nb.y + 0.02380415*nc.y + 0.08744932*nd.y + -0.021898141*ne.y + 0.026684938*nf.y + 0.032703754*ng.y + 0.052364938*nh.y + 0.056927126*ni.y;
	float y = -0.0901643*na.z + -0.09282382*nb.z + 0.07358982*nc.z + 0.3232882*nd.z + -1.0591649*ne.z + 0.17128727*nf.z + 0.22159135*ng.z + -0.3007047*nh.z + -0.05238468*ni.z;
	float z = -0.06714734*na.w + 0.04850284*nb.w + -0.011960667*nc.w + -0.18101339*nd.w + -0.34727672*ne.w + 0.030268785*nf.w + -0.09629506*ng.w + -0.28136835*nh.w + -0.13334738*ni.w;
	float o = s+t+u+v+w+x+y+z+0.006057905;
	s = 0.018881252*a.x + 0.06384664*b.x + -0.011764481*c.x + 0.15501355*d.x + -0.2185426*e.x + -0.07557788*f.x + 0.025938602*g.x + -0.14496502*h.x + 0.024891714*i.x;
	t = -0.01996556*a.y + -0.00053282635*b.y + 0.00061660836*c.y + 0.024429671*d.y + 0.054617107*e.y + -0.021867601*f.y + 0.032060657*g.y + 0.0031433336*h.y + -0.012301998*i.y;
	u = -0.070778325*a.z + -0.19530736*b.z + 0.011512594*c.z + -0.27479392*d.z + -0.013253852*e.z + -0.022542335*f.z + 0.05682861*g.z + 0.0012437729*h.z + -0.0150462305*i.z;
	v = 0.066125244*a.w + 0.020368045*b.w + -0.03502752*c.w + 0.1109599*d.w + -0.060857326*e.w + 0.06733562*f.w + 0.012108426*g.w + 0.0063430844*h.w + -0.004283166*i.w;
	w = -0.06497726*na.x + -0.17359954*nb.x + -0.011175394*nc.x + -0.18982106*nd.x + 0.5939919*ne.x + -0.021145599*nf.x + -0.064499505*ng.x + -0.014329371*nh.x + -0.015423945*ni.x;
	x = -0.03674411*na.y + -0.0043503637*nb.y + 0.010304639*nc.y + -0.0012494766*nd.y + -0.13278799*ne.y + 0.032555994*nf.y + -0.052385017*ng.y + 0.010176496*nh.y + -0.0026763906*ni.y;
	y = 0.06123568*na.z + 0.14374596*nb.z + 0.056109104*nc.z + 0.019599102*nd.z + 0.18616806*ne.z + -0.03179762*nf.z + 0.036342375*ng.z + 0.029431945*nh.z + 0.043751024*ni.z;
	z = 0.12073644*na.w + 0.0733359*nb.w + 0.08390864*nc.w + -0.11528834*nd.w + 0.3467376*ne.w + -0.033535313*nf.w + 0.041739017*ng.w + 0.058267288*nh.w + 0.08858209*ni.w;
	float p = s+t+u+v+w+x+y+z+-0.0028000006;
	s = -0.09027117*a.x + -0.14622006*b.x + -0.16810851*c.x + -0.24796103*d.x + 0.2572285*e.x + 0.47094887*f.x + 0.032027613*g.x + 0.11410892*h.x + 0.1613444*i.x;
	t = -0.0012083473*a.y + 0.17305928*b.y + -0.05621104*c.y + 0.036259834*d.y + -0.03851184*e.y + -0.0055326805*f.y + -0.012463582*g.y + 0.35876498*h.y + 0.1724837*i.y;
	u = 0.40897495*a.z + 0.17421961*b.z + 0.28644145*c.z + -0.25477505*d.z + -0.4277018*e.z + -0.18726684*f.z + 0.13615106*g.z + 0.026969131*h.z + -0.15176998*i.z;
	v = 0.04463327*a.w + -0.04876386*b.w + -0.031818386*c.w + 0.03954202*d.w + 0.09516337*e.w + 0.052471045*f.w + -0.13383369*g.w + -0.21776986*h.w + 0.015097585*i.w;
	w = 0.2092236*na.x + 0.48777798*nb.x + 0.2956695*nc.x + 0.23978968*nd.x + -0.59248745*ne.x + -0.13063201*nf.x + 0.061278455*ng.x + -0.10234516*nh.x + 0.002134229*ni.x;
	x = 0.07130507*na.y + 0.121942736*nb.y + -0.01583503*nc.y + 0.14037956*nd.y + -0.37520966*ne.y + -0.067429096*nf.y + 0.05821935*ng.y + -0.35461438*nh.y + -0.07123769*ni.y;
	y = -0.468684*na.z + -0.30739802*nb.z + -0.38813922*nc.z + -0.33846653*nd.z + -0.08206715*ne.z + 0.15765728*nf.z + -0.16559663*ng.z + -0.055957757*nh.z + -0.11368465*ni.z;
	z = -0.4303523*na.w + -0.84991306*nb.w + -0.2505638*nc.w + 0.35179257*nd.w + 1.0163839*ne.w + 0.23950848*nf.w + 0.08583142*ng.w + -0.2591442*nh.w + -0.045323353*ni.w;
	float q = s+t+u+v+w+x+y+z+0.017286068;
	s = 0.101637*a.x + -0.23477565*b.x + -0.03157821*c.x + -0.20734964*d.x + -0.16431263*e.x + 0.2424383*f.x + -0.11075752*g.x + 0.16768074*h.x + -0.418383*i.x;
	t = 0.006255804*a.y + 0.042100485*b.y + 0.0036014041*c.y + -0.08597467*d.y + 0.048351593*e.y + -0.13372381*f.y + -0.061134014*g.y + -0.33137617*h.y + 0.019631254*i.y;
	u = 0.18377675*a.z + 0.58994883*b.z + 0.2991301*c.z + 0.74260485*d.z + -0.1369073*e.z + 0.24632849*f.z + -0.03240025*g.z + 0.2981277*h.z + 0.3513618*i.z;
	v = -0.04465667*a.w + -0.15135704*b.w + 0.13290188*c.w + -0.049763512*d.w + -0.6689857*e.w + -0.28756517*f.w + 0.04422787*g.w + 0.14173377*h.w + -0.027095031*i.w;
	w = 0.010524522*na.x + 0.2286293*nb.x + -0.15575987*nc.x + 0.19659552*nd.x + 0.2584596*ne.x + 0.53996265*nf.x + 0.1819511*ng.x + 0.20248987*nh.x + 0.08608274*ni.x;
	x = 0.054287046*na.y + 0.04735612*nb.y + 0.0861212*nc.y + -0.028863167*nd.y + 0.20381325*ne.y + -0.109093554*nf.y + 0.010826272*ng.y + 0.23420005*nh.y + -0.022509871*ni.y;
	y = 0.1786933*na.z + 0.126716*nb.z + 0.046265166*nc.z + 0.071686745*nd.z + 0.323193*ne.z + 0.42820987*nf.z + 0.062808044*ng.z + 0.13638002*nh.z + 0.29570308*ni.z;
	z = -0.31819153*na.w + -0.4878216*nb.w + -0.33641538*nc.w + -0.43968466*nd.w + -0.588631*ne.w + 0.06131746*nf.w + -0.28163537*ng.w + -0.49008766*nh.w + -0.5446552*ni.w;
	float r = s+t+u+v+w+x+y+z+0.020686742;
	
	return vec4(o, p, q, r);
}

//!DESC Anime4K-v3.1-Upscale(x2)-CNN(M)-Conv-4x3x3x8
//!HOOK NATIVE
//!BIND HOOKED
//!WHEN OUTPUT.w NATIVE.w / 1.200 > OUTPUT.h NATIVE.h / 1.200 > *
//!BIND LUMAN3

//!SAVE LUMAN4
//!COMPONENTS 4

#define L_tex LUMAN3_tex

vec4 hook() {
vec2 dp = HOOKED_pt;
vec4 a = L_tex(HOOKED_pos + vec2(-dp.x, -dp.y));
vec4 b = L_tex(HOOKED_pos + vec2(-dp.x, 0));
vec4 c = L_tex(HOOKED_pos + vec2(-dp.x, dp.y));
vec4 d = L_tex(HOOKED_pos + vec2(0, -dp.y));
vec4 e = L_tex(HOOKED_pos + vec2(0, 0));
vec4 f = L_tex(HOOKED_pos + vec2(0, dp.y));
vec4 g = L_tex(HOOKED_pos + vec2(dp.x, -dp.y));
vec4 h = L_tex(HOOKED_pos + vec2(dp.x, 0));
vec4 i = L_tex(HOOKED_pos + vec2(dp.x, dp.y));

vec4 na = -min(a, 0);
vec4 nb = -min(b, 0);
vec4 nc = -min(c, 0);
vec4 nd = -min(d, 0);
vec4 ne = -min(e, 0);
vec4 nf = -min(f, 0);
vec4 ng = -min(g, 0);
vec4 nh = -min(h, 0);
vec4 ni = -min(i, 0);

a = max(a, 0);
b = max(b, 0);
c = max(c, 0);
d = max(d, 0);
e = max(e, 0);
f = max(f, 0);
g = max(g, 0);
h = max(h, 0);
i = max(i, 0);

float s = -0.23822114*a.x + -0.49224076*b.x + -0.2603839*c.x + -0.22270115*d.x + -0.23199631*e.x + -0.08860003*f.x + -0.11150333*g.x + -0.31895813*h.x + -0.035482813*i.x;
float t = 0.06318636*a.y + -0.53629327*b.y + -0.10155968*c.y + -0.06471427*d.y + 0.5817465*e.y + -0.13474646*f.y + 0.0058701304*g.y + 0.1711669*h.y + 0.08656512*i.y;
float u = -0.06168478*a.z + -0.014518998*b.z + -0.038895532*c.z + -0.18411076*d.z + 0.06959173*e.z + -0.03780323*f.z + -0.054073177*g.z + 0.05846756*h.z + 0.0526453*i.z;
float v = 0.1637899*a.w + -0.17392571*b.w + -0.044026185*c.w + -0.36689785*d.w + 0.14791447*e.w + -0.03293263*f.w + -0.13484396*g.w + 0.025672594*h.w + 0.0018860486*i.w;
float w = 0.00056899054*na.x + -0.018397113*nb.x + 0.092683315*nc.x + 0.15637913*nd.x + -0.093613446*ne.x + -0.12215183*nf.x + -0.01812064*ng.x + 0.052842487*nh.x + 0.024374953*ni.x;
float x = -0.18763757*na.y + 0.30196622*nb.y + 0.08883403*nc.y + -0.054503135*nd.y + -0.6387117*ne.y + -0.051367637*nf.y + 0.062047742*ng.y + -0.25852874*nh.y + -0.16576186*ni.y;
float y = 0.13587122*na.z + 0.08522579*nb.z + 0.03095689*nc.z + 0.25446168*nd.z + -0.1795436*ne.z + 0.12887624*nf.z + 0.16522995*ng.z + -0.12371819*nh.z + 0.018461064*ni.z;
float z = 0.33695576*na.w + 0.27555978*nb.w + 0.12422293*nc.w + 0.4810716*nd.w + 0.24170946*ne.w + 0.109018564*nf.w + 0.1475024*ng.w + 0.008883083*nh.w + -0.06614558*ni.w;
float o = s+t+u+v+w+x+y+z+-0.009210918;
s = 0.011271452*a.x + -0.42887446*b.x + -0.16086382*c.x + -0.2105586*d.x + 0.24786222*e.x + -0.13847941*f.x + -0.18258463*g.x + -0.32100454*h.x + 0.014219074*i.x;
t = 0.023105236*a.y + -0.01578845*b.y + -0.050536994*c.y + 0.039284714*d.y + 0.16437066*e.y + 0.0356428*f.y + -0.062688194*g.y + 0.07783894*h.y + 0.009747119*i.y;
u = 0.030821703*a.z + 0.06083882*b.z + 0.025873283*c.z + 0.017223293*d.z + 0.08845148*e.z + 0.061377097*f.z + 0.06515027*g.z + 0.0019544929*h.z + 0.017247573*i.z;
v = 0.012934576*a.w + 0.07368678*b.w + -0.040340308*c.w + 0.067247815*d.w + -0.08931617*e.w + 0.031227414*f.w + -0.06303663*g.w + 0.03044627*h.w + 0.012112707*i.w;
w = -0.024660507*na.x + -0.009060651*nb.x + -0.0035039044*nc.x + 0.06341225*nd.x + -0.52527195*ne.x + -0.005501108*nf.x + 0.0588685*ng.x + 0.09516038*nh.x + 0.04720441*ni.x;
x = -0.063695304*na.y + -0.067882225*nb.y + 0.009680431*nc.y + 0.11614084*nd.y + 0.07604306*ne.y + -0.2850213*nf.y + 0.06081603*ng.y + -0.078130275*nh.y + 0.010210937*ni.y;
y = 0.020847162*na.z + 0.08855373*nb.z + 0.0023585085*nc.z + 0.046964426*nd.z + 0.029082319*ne.z + -0.010446979*nf.z + 0.069331944*ng.z + -0.1097909*nh.z + 0.0066273385*ni.z;
z = 0.07595761*na.w + 0.21096602*nb.w + -0.0016103018*nc.w + 0.01423776*nd.w + 0.39817473*ne.w + 0.017830608*nf.w + 0.10896886*ng.w + 0.05775906*nh.w + -0.008378969*ni.w;
float p = s+t+u+v+w+x+y+z+0.007218698;
s = 0.034728855*a.x + -0.24261177*b.x + 0.28377128*c.x + -0.07902698*d.x + 0.53327984*e.x + 0.25865844*f.x + -0.0034399142*g.x + -0.43674976*h.x + 0.032661323*i.x;
t = -0.07738957*a.y + 0.057249602*b.y + 0.2050702*c.y + 0.17566027*d.y + 0.011081271*e.y + -0.23351799*f.y + -0.09890139*g.y + 0.018036745*h.y + 0.047635887*i.y;
u = -0.020469286*a.z + 0.047594436*b.z + -0.002022923*c.z + -0.20256907*d.z + -0.78263223*e.z + 0.0072576823*f.z + -0.0490066*g.z + 0.029040253*h.z + 0.017826209*i.z;
v = -0.020083593*a.w + 0.06858024*b.w + 0.06368863*c.w + 0.20496108*d.w + -0.16528691*e.w + -0.10180708*f.w + -0.16950546*g.w + 0.10020681*h.w + 0.012377215*i.w;
w = -0.03253046*na.x + 0.066873014*nb.x + -0.068452045*nc.x + -0.010155748*nd.x + -0.46329933*ne.x + -0.1307425*nf.x + 0.048001047*ng.x + 0.123704046*nh.x + 0.074856944*ni.x;
x = 0.062060773*na.y + 0.13428265*nb.y + -0.24431407*nc.y + -0.072135694*nd.y + 0.9167748*ne.y + 0.23750597*nf.y + 0.04223396*ng.y + -0.39293385*nh.y + -0.2623536*ni.y;
y = 0.021315947*na.z + 0.09439878*nb.z + 0.015211157*nc.z + 0.2038265*nd.z + 0.69010055*ne.z + 0.042161886*nf.z + 0.0677661*ng.z + -0.023256699*nh.z + 0.014574618*ni.z;
z = -0.04407271*na.w + 0.11794614*nb.w + 0.03630912*nc.w + 0.7663727*nd.w + 0.39717525*ne.w + 0.22002636*nf.w + -0.010754877*ng.w + -0.051768698*nh.w + -0.010918847*ni.w;
float q = s+t+u+v+w+x+y+z+0.024105644;
s = 0.030766528*a.x + 0.16373588*b.x + 0.21841961*c.x + 0.10914003*d.x + 0.05621998*e.x + 0.25531125*f.x + 0.058601663*g.x + -0.029884653*h.x + -0.03693911*i.x;
t = -0.045011982*a.y + 0.093240164*b.y + 0.09846852*c.y + 0.06726326*d.y + 0.628559*e.y + -0.02637863*f.y + 0.0064472784*g.y + 0.042976446*h.y + 0.0080402335*i.y;
u = -0.017018517*a.z + -0.0002487334*b.z + 0.051482406*c.z + 0.09698756*d.z + -0.06515222*e.z + 0.020085098*f.z + 0.049856555*g.z + 0.09850702*h.z + 0.06601598*i.z;
v = 0.0029910787*a.w + 0.027113425*b.w + 0.056177218*c.w + 0.1544931*d.w + 0.28678927*e.w + -0.031562537*f.w + -0.015119418*g.w + 0.059966877*h.w + 0.009752991*i.w;
w = -0.06231565*na.x + -0.03341734*nb.x + -0.072572425*nc.x + -0.04877089*nd.x + -0.047237467*ne.x + -0.10683365*nf.x + -0.002816312*ng.x + -0.05710042*nh.x + -0.01591127*ni.x;
x = 0.025939502*na.y + 0.10218501*nb.y + -0.10536432*nc.y + -0.071161434*nd.y + -0.3066342*ne.y + 0.061602294*nf.y + 0.03169828*ng.y + 0.005768011*nh.y + -0.18946463*ni.y;
y = -0.013577987*na.z + -0.025278145*nb.z + 0.00625481*nc.z + -0.08724931*nd.z + 0.15522881*ne.z + -0.015623531*nf.z + -0.040420238*ng.z + 0.07587788*nh.z + -0.026974916*ni.z;
z = 0.05199736*na.w + -0.046465985*nb.w + 0.020043945*nc.w + -0.1230899*nd.w + -0.26674423*ne.w + 0.039947394*nf.w + -0.039006326*ng.w + -0.08176985*nh.w + 0.030418074*ni.w;
float r = s+t+u+v+w+x+y+z+-0.012540265;

return vec4(o, p, q, r);

}
//!DESC Anime4K-v3.1-Upscale(x2)-CNN(M)-Conv-4x3x3x8
//!HOOK NATIVE
//!BIND HOOKED
//!WHEN OUTPUT.w NATIVE.w / 1.200 > OUTPUT.h NATIVE.h / 1.200 > *
//!BIND LUMAN4
//!SAVE LUMAN5
//!COMPONENTS 4

#define L_tex LUMAN4_tex

vec4 hook() {
vec2 dp = HOOKED_pt;
vec4 a = L_tex(HOOKED_pos + vec2(-dp.x, -dp.y));
vec4 b = L_tex(HOOKED_pos + vec2(-dp.x, 0));
vec4 c = L_tex(HOOKED_pos + vec2(-dp.x, dp.y));
vec4 d = L_tex(HOOKED_pos + vec2(0, -dp.y));
vec4 e = L_tex(HOOKED_pos + vec2(0, 0));
vec4 f = L_tex(HOOKED_pos + vec2(0, dp.y));
vec4 g = L_tex(HOOKED_pos + vec2(dp.x, -dp.y));
vec4 h = L_tex(HOOKED_pos + vec2(dp.x, 0));
vec4 i = L_tex(HOOKED_pos + vec2(dp.x, dp.y));

vec4 na = -min(a, 0);
vec4 nb = -min(b, 0);
vec4 nc = -min(c, 0);
vec4 nd = -min(d, 0);
vec4 ne = -min(e, 0);
vec4 nf = -min(f, 0);
vec4 ng = -min(g, 0);
vec4 nh = -min(h, 0);
vec4 ni = -min(i, 0);

a = max(a, 0);
b = max(b, 0);
c = max(c, 0);
d = max(d, 0);
e = max(e, 0);
f = max(f, 0);
g = max(g, 0);
h = max(h, 0);
i = max(i, 0);

float s = 0.00025631802*a.x + 0.057320878*b.x + -0.041412644*c.x + 0.16791897*d.x + 0.16617729*e.x + -0.48703465*f.x + -0.12931561*g.x + 0.4140343*h.x + -0.33470672*i.x;
float t = 0.03830889*a.y + -0.051282525*b.y + 0.09902938*c.y + 0.051170327*d.y + -1.0059495*e.y + 0.3998207*f.y + -0.026771523*g.y + -0.23292333*h.y + 0.23323184*i.y;
float u = 0.033804324*a.z + -0.16789144*b.z + 0.11551676*c.z + 0.2096383*d.z + -0.5732962*e.z + 0.37778842*f.z + -0.035116088*g.z + 0.089063995*h.z + 0.070677355*i.z;
float v = 0.22857346*a.w + -0.079091504*b.w + -0.31563935*c.w + 0.5057771*d.w + -1.3217461*e.w + -0.12721835*f.w + 0.16177909*g.w + -0.2629097*h.w + -0.0029459773*i.w;
float w = -0.030586343*na.x + -0.13376898*nb.x + 0.13974473*nc.x + -0.24266301*nd.x + -0.11947399*ne.x + 0.19367288*nf.x + -0.34237102*ng.x + 0.3096073*nh.x + 0.043135814*ni.x;
float x = -0.14012407*na.y + 0.016800448*nb.y + 0.1570266*nc.y + 0.7430246*nd.y + -0.005562219*ne.y + 0.26139715*nf.y + 0.64244574*ng.y + -0.51432157*nh.y + -0.114942044*ni.y;
float y = -0.10178008*na.z + 0.23307206*nb.z + -0.29321644*nc.z + 0.24498452*nd.z + -1.1282628*ne.z + 0.022412058*nf.z + -0.16838956*ng.z + 0.40056717*nh.z + -0.21463306*ni.z;
float z = -1.005476*na.w + 0.8050052*nb.w + 0.12235334*nc.w + -0.6732282*nd.w + 0.3369146*ne.w + 0.06454999*nf.w + -0.17765191*ng.w + 0.10384625*nh.w + -0.11302512*ni.w;
float o = s+t+u+v+w+x+y+z+-0.061198946;
s = 0.08390676*a.x + -0.011123063*b.x + -0.03269317*c.x + -0.19219291*d.x + -0.050676446*e.x + 0.07472215*f.x + 0.085977115*g.x + 0.11578824*h.x + -0.28158212*i.x;
t = -0.02405043*a.y + -0.13468283*b.y + 0.014654289*c.y + 0.28977296*d.y + 0.6254546*e.y + 0.16947387*f.y + -0.026750885*g.y + 0.037516773*h.y + 0.29321685*i.y;
u = 0.017659916*a.z + -0.0513346*b.z + 0.014308151*c.z + -0.07032843*d.z + -0.124652594*e.z + 0.027099187*f.z + -0.042692557*g.z + -0.32160884*h.z + -0.124402575*i.z;
v = 0.173668*a.w + 0.16868736*b.w + 0.105285004*c.w + -0.27488157*d.w + -0.62909824*e.w + -0.28937566*f.w + 0.021574946*g.w + 0.090454094*h.w + 0.088722266*i.w;
w = 0.011426444*na.x + -0.16358133*nb.x + -0.24628234*nc.x + -0.12582813*nd.x + 0.37491634*ne.x + 0.66146225*nf.x + 0.17739972*ng.x + -0.24103446*nh.x + -0.12512414*ni.x;
x = 0.049656067*na.y + 0.35043705*nb.y + -0.06541586*nc.y + 0.036384188*nd.y + -0.88243604*ne.y + 0.15085825*nf.y + 0.01566454*ng.y + 0.26099333*nh.y + -0.23653607*ni.y;
y = -0.05713696*na.z + 0.31915048*nb.z + 0.09413395*nc.z + -0.056367278*nd.z + 0.500199*ne.z + -0.10129501*nf.z + 0.22792955*ng.z + 0.27008235*nh.z + 0.11766709*ni.z;
z = -0.30272278*na.w + -0.032818265*nb.w + -0.0091206925*nc.w + 0.7295555*nd.w + 0.078978635*ne.w + -0.036731187*nf.w + -0.04899552*ng.w + -0.23233992*nh.w + 0.120634325*ni.w;
float p = s+t+u+v+w+x+y+z+-0.006999369;
s = -0.021856444*a.x + -0.0006963466*b.x + 0.02784665*c.x + -0.1285126*d.x + -0.47980213*e.x + 0.3816084*f.x + 0.11308428*g.x + -0.43742862*h.x + 0.43896514*i.x;
t = -0.053421438*a.y + 0.0963073*b.y + -0.13441114*c.y + -0.12122123*d.y + -0.15046698*e.y + -0.39540198*f.y + -0.0028491614*g.y + 0.22168712*h.y + -0.33935112*i.y;
u = -0.02753673*a.z + 0.13554272*b.z + -0.08918299*c.z + -0.17173594*d.z + 0.46268475*e.z + -0.35359815*f.z + 0.046332352*g.z + 0.02462448*h.z + -0.023167444*i.z;
v = -0.23453364*a.w + 0.07788929*b.w + 0.16012788*c.w + -0.41643515*d.w + -0.6417199*e.w + 0.3087294*f.w + -0.14682502*g.w + 0.25157255*h.w + -0.0602734*i.w;
w = 0.028217131*na.x + 0.12867944*nb.x + -0.05617058*nc.x + 0.28762993*nd.x + -0.5784438*ne.x + -0.36014605*nf.x + 0.21616842*ng.x + -0.18586996*nh.x + -0.009710477*ni.x;
x = 0.123937346*na.y + -0.112089925*nb.y + -0.079855986*nc.y + -0.65935284*nd.y + 1.6843947*ne.y + -0.37654027*nf.y + -0.5687655*ng.y + 0.36904392*nh.y + 0.22348003*ni.y;
y = 0.10575013*na.z + -0.28616336*nb.z + 0.22265147*nc.z + -0.2137293*nd.z + -0.91093117*ne.z + 0.011338876*nf.z + 0.10558912*ng.z + -0.47041062*nh.z + 0.16206238*ni.z;
z = 0.9702835*na.w + -0.82380474*nb.w + -0.0043063024*nc.w + 0.4436007*nd.w + -0.69435906*ne.w + -0.11961962*nf.w + 0.18174438*ng.w + -0.050473217*nh.w + 0.07299529*ni.w;
float q = s+t+u+v+w+x+y+z+-0.042621654;
s = 0.012985117*a.x + 0.069789566*b.x + 0.012881662*c.x + -0.013086082*d.x + -0.16663207*e.x + 0.18778817*f.x + -0.009702196*g.x + 0.038190898*h.x + -0.050225593*i.x;
t = -0.07929176*a.y + -0.06990447*b.y + -0.06669893*c.y + 0.025257275*d.y + 0.7689759*e.y + -0.10249004*f.y + 0.017197285*g.y + -0.10194497*h.y + 0.090725824*i.y;
u = 0.0030403193*a.z + 0.012294587*b.z + -0.023400322*c.z + -0.043591868*d.z + -0.16327766*e.z + -0.02788577*f.z + 0.018733488*g.z + -0.034326617*h.z + -0.05105706*i.z;
v = -0.062092993*a.w + 0.18108387*b.w + 0.0864376*c.w + -0.16197896*d.w + -0.12865224*e.w + -0.069327936*f.w + 0.0015153112*g.w + 0.018491505*h.w + 0.049098536*i.w;
w = 0.019960985*na.x + 0.051785935*nb.x + -0.21044643*nc.x + 0.09824475*nd.x + -0.14958306*ne.x + 0.3990458*nf.x + 0.016052058*ng.x + 0.049709063*nh.x + -0.17706677*ni.x;
x = 0.019563846*na.y + 0.18184721*nb.y + -0.11986355*nc.y + -0.2601329*nd.y + -0.28785226*ne.y + 0.085305505*nf.y + 0.024360009*ng.y + -0.20685866*nh.y + -0.086421244*ni.y;
y = -0.0028385085*na.z + -0.007392961*nb.z + 0.12550405*nc.z + 0.05340696*nd.z + -0.24601264*ne.z + -0.19635704*nf.z + -0.035968296*ng.z + 0.10348485*nh.z + -0.009769748*ni.z;
z = 0.26647258*na.w + -0.63420767*nb.w + -0.02826515*nc.w + 0.06637238*nd.w + 0.57809395*ne.w + 0.06882983*nf.w + -0.004849368*ng.w + -0.093381576*nh.w + -0.10812531*ni.w;
float r = s+t+u+v+w+x+y+z+-0.018241946;

return vec4(o, p, q, r);

}

//!DESC Anime4K-v3.1-Upscale(x2)-CNN(M)-Conv-Reduce
//!HOOK NATIVE
//!BIND HOOKED
//!WHEN OUTPUT.w NATIVE.w / 1.200 > OUTPUT.h NATIVE.h / 1.200 > *
//!BIND LUMAN1
//!BIND LUMAN2
//!BIND LUMAN3
//!BIND LUMAN4
//!BIND LUMAN5
//!SAVE LUMAN0
//!COMPONENTS 4

vec4 hook() {
vec2 dp = HOOKED_pt;
vec4 a = LUMAN1_tex(HOOKED_pos);
vec4 b = LUMAN2_tex(HOOKED_pos);
vec4 c = LUMAN3_tex(HOOKED_pos);
vec4 d = LUMAN4_tex(HOOKED_pos);
vec4 e = LUMAN5_tex(HOOKED_pos);

vec4 na = -min(a, 0);
vec4 nb = -min(b, 0);
vec4 nc = -min(c, 0);
vec4 nd = -min(d, 0);
vec4 ne = -min(e, 0);

a = max(a, 0);
b = max(b, 0);
c = max(c, 0);
d = max(d, 0);
e = max(e, 0);

float o = 0.016170086*a.x + -0.07807932*a.y + -0.01608141*a.z + 0.04596583*a.w + 0.0010671375*na.x + 0.13604787*na.y + -0.103508055*na.z + -0.053727165*na.w + 0.05931074*b.x + -0.03741526*b.y + 0.007310368*b.z + 0.021383934*b.w + 0.07797022*nb.x + 0.010276286*nb.y + -0.044151705*nb.z + 0.018349322*nb.w + -0.10480624*c.x + -0.19607827*c.y + -0.017716367*c.z + -0.03210694*c.w + 0.030397506*nc.x + 0.13205609*nc.y + 0.027324466*nc.z + 0.011638977*nc.w + -0.046764173*d.x + -0.14180084*d.y + -0.041110236*d.z + -0.3233351*d.w + -0.13833268*nd.x + 0.35512686*nd.y + -0.08653635*nd.z + -0.15801503*nd.w + -0.26316383*e.x + -0.2056243*e.y + -0.09891177*e.z + 0.09735771*e.w + 0.17222679*ne.x + 0.10222737*ne.y + 0.17698137*ne.z + -0.045976873*ne.w + -0.016519222;
float p = -0.0070673134*a.x + -0.10279413*a.y + -0.030861663*a.z + 0.019370042*a.w + -0.0014143038*na.x + 0.05432107*na.y + -0.15635669*na.z + -0.05455238*na.w + 0.027550258*b.x + 0.014056243*b.y + -0.016198097*b.z + 0.03419058*b.w + -0.004207751*nb.x + -0.0113672*nb.y + 0.034180697*nb.z + 0.04015298*nb.w + -0.06339332*c.x + 0.0036280584*c.y + -0.010639602*c.z + 0.026508855*c.w + -0.02524984*nc.x + 0.11936996*nc.y + -0.031202994*nc.z + -0.021372601*nc.w + -0.025080366*d.x + -0.021841787*d.y + 0.06487728*d.z + -0.06460682*d.w + 0.04119384*nd.x + -0.008643975*nd.y + -0.2078446*nd.z + 0.11259166*nd.w + -0.10560037*e.x + 0.14785078*e.y + 0.1384287*e.z + -0.06915313*e.w + 0.010694984*ne.x + -0.034556255*ne.y + -0.03377371*ne.z + 0.06635877*ne.w + -0.002248366;
float q = 0.02117986*a.x + -0.051776726*a.y + 0.15544093*a.z + 0.070309296*a.w + -0.011411071*na.x + 0.0055163414*na.y + 0.06413486*na.z + -0.045615938*na.w + 0.033726115*b.x + -0.052270424*b.y + 0.019222505*b.z + 0.02011268*b.w + -0.11609392*nb.x + 0.033497345*nb.y + -0.06132894*nb.z + -0.10658528*nb.w + 0.038067166*c.x + 0.086731836*c.y + 0.08148008*c.z + 0.010150495*c.w + -0.016870074*nc.x + 0.01104681*nc.y + 0.009952575*nc.z + 0.020137098*nc.w + -0.06427216*d.x + -0.12534674*d.y + -0.09109642*d.z + -0.46550632*d.w + -0.1370387*nd.x + 0.24063608*nd.y + -0.33579165*nd.z + -0.08938409*nd.w + -0.09131308*e.x + -0.17998323*e.y + -0.33354574*e.z + -0.20851119*e.w + 0.21100727*ne.x + 0.0667875*ne.y + 0.23766036*ne.z + 0.10573718*ne.w + -0.023920521;
float r = -0.06296154*a.x + 0.06051705*a.y + 0.11386459*a.z + 0.019399049*a.w + -0.015610163*na.x + 0.0037772388*na.y + 0.04038177*na.z + 0.020901382*na.w + 0.0468376*b.x + 0.004552797*b.y + 0.08530895*b.z + -0.0020661093*b.w + -0.075115256*nb.x + 0.01650069*nb.y + 0.025982859*nb.z + -0.063966826*nb.w + 0.14024706*c.x + 0.03896333*c.y + -0.070236415*c.z + 0.013854423*c.w + -0.023396354*nc.x + -0.10749727*nc.y + 0.018419292*nc.z + 0.0051121856*nc.w + -0.098157406*d.x + -0.24840991*d.y + -0.01761279*d.z + -0.48552045*d.w + -0.11399571*nd.x + 0.2751265*nd.y + -0.4713016*nd.z + 0.009285934*nd.w + -0.11395686*e.x + 0.04294104*e.y + -0.33598495*e.z + 0.14753135*e.w + 0.18233627*ne.x + 0.06840005*ne.y + 0.23921333*ne.z + -0.087927036*ne.w + -0.020836344;

return vec4(o, p, q, r);

}

//!HOOK NATIVE
//!BIND HOOKED
//!WHEN OUTPUT.w NATIVE.w / 1.200 > OUTPUT.h NATIVE.h / 1.200 > *
//!BIND LUMAN0
//!WIDTH NATIVE.w 2 *
//!HEIGHT NATIVE.h 2 *
//!DESC Anime4K-v3.1-Upscale(x2)-CNN(M)

vec4 hook() {
vec2 f = fract(LUMAN0_pos * LUMAN0_size);
ivec2 i = ivec2(f * vec2(2));
float c = LUMAN0_tex((vec2(0.5) - f) * LUMAN0_pt + LUMAN0_pos)[i.y * 2 + i.x];
return vec4(c + HOOKED_tex(HOOKED_pos).x, HOOKED_tex(HOOKED_pos).yz, 0);
}


Shaderfilter Plus suffers from OBS internal audio buffer delays

When applying negative delay to audio sources in OBS, OBS will internally delay both video and audio mix buffers by the maximum negative delay amount, so that it has room to bring these components into sync with each other.

image

The video and audio monitoring in OBS does not show this delay, as it is applied post-compositing, pre-encoding.

Shaderfilter Plus accesses the mix buffers after this has been applied, so shader effects using FFT data generated from those mix tracks are delayed by the maximum negative offset. This results in a delay in the shader effect by that amount. As that shader effect is applied to video source in real-time, it is effectively delayed twice.

Here is an example video showing the result of the effect being delayed.

Ideally Shaderfilter Plus accesses these buffers before this delay has been applied, so that effects are rendered in real-time and not delayed twice.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.