Limeth / obs-shaderfilter-plus

obs-shaderfilter rewritten in Rust and improved
Other
183 stars 19 forks source link

A guide for rewriting Shadertoy shaders #6

Open MarioMey opened 4 years ago

MarioMey commented 4 years ago

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... :+1:

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

Limeth commented 4 years ago

Hello, thank you for the question! I think that it would be helpful to create a wiki page comparing shadertoy and OBS ShaderFilter Plus shaders and about how to adapt the shaders.

In your particular example, the uniforms would have to be renamed according to the README and

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

would be replaced with

float4 render(float2 st) {

or

vec4 render(vec2 st) {

depending whether you use DirectX or OpenGL, respectively.

MarioMey commented 4 years ago

After playing a while, I could make it work:


vec4 render(vec2 st) {
    st.x *= builtin_uv_size.x/builtin_uv_size.y;

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

    return vec4(color,1.0);
}

imagen

Since we are talking about shaders, let me ask you something: Can I create/use a shader that overlap some image/video over another with "Add" or "Screen" blending?

Limeth commented 4 years ago

This plugin currently does not let you combine multiple sources, though I would definitely like to see this functionality added in the future. I assume it would not be facilitated using "Effect Filters", but rather a new source that combines other sources. The OBS documentation regarding this seems very scarce, however, so I have not made much progress on that front.

josephyooo commented 4 years ago

Your solution didn't work for me as it said that vec[1-4] was an unrecognized identifier. What worked for me was

float4 render(float2 st) {
    st.x *= builtin_uv_size.x/builtin_uv_size.y;

    float3 color = float3(st.x,st.y,abs(sin(builtin_elapsed_time)));

    return float4(color, 1.0);
}

Also, this might be a naive question, but what exactly is being passed to render (st)? Is it just the equivalent of gl_FragCoord/u_resolution.xy since Limeth suggested that you delete the line declaring st altogether and just use whatever is passed to render?

Limeth commented 4 years ago

@josephyooo The issue with vec not working is related to which graphics API is in use. On Windows, obs-shaderfilter-plus uses DirectX and HLSL by default (as opposed to GLSL), which uses the syntax you responded with. You can read more about the graphics APIs in the README.md: https://github.com/Limeth/obs-shaderfilter-plus#what-are-shaders

Also, this might be a naive question, but what exactly is being passed to render (st)? Is it just the equivalent of gl_FragCoord/u_resolution.xy since Limeth suggested that you delete the line declaring st altogether and just use whatever is passed to render?

The usage guide may be ambiguous on what the parameter is, so let me clear this up -- the st parameter of the render function are the UV texture coordinates of the source this filter is being applied to. Its components range from 0 to 1. In order to access the resolution (size) of the source, you can use the builtin_uv_size uniform.

opyate commented 3 years ago

Hi @Limeth , thanks for a great plugin :)

While we're on the shadertoy topic, what would be the equivalent of iChannel, e.g. I want to pull in a texture like here: https://www.shadertoy.com/view/XsfyDl (this is to help me debug shaders)

I guess it's still a planned feature?

Limeth commented 3 years ago

Hello @opyate, glad you find it useful. The reason I didn't implement it yet is because I would like channels to be more powerful than just static textures, in theory you could also supply video, sound, other scenes, etc. I found OBS to be unsuitable for that, though. However, if anyone wants to add just support for textures via a PR, feel free to do so!