Does anybody know how to change the ofelia video example code so that i can use it like the gem [pixfilm] object?
I want to load videos with (kind of) [openpanel], have stop and play buttons with variable speed. And I want to build "effect chains": connect the video example object to a blur object for example.
-
Ofelia - videoPlayer and GLSL Effects
-
@Cuinjune thanks for your explanations.
so in comparison to Gem lua is the bottleneck in ofelia when processing video in real time?- Okay, that does not make much sense then...
- That sounds like a good solution, at least for very heavy and often used tasks...
- Having a shader class sounds great. Actually the sketch filters in the patch above are shader effects, i tried to understand with your shader examples how to implement them, but no luck so far...
-
I added 21 GLSL effects to the videoPlayer. And finally the pixel effect, which was the reason why i looked into GLSL.
I modified some effects that I found, so it is not my code. Still try to understand GLSL.
Would be nice to have a bigger video glsl collection.
ofelia_video_glsl.zip -
I updated the collection. There is now also a magnifying glass effect that works with the mouse.
Fascinating what is possible with a few lines of code in GLSL.
@Cuinjune do you know if it would be difficult to make a shader chain? So that one shader effect is one [ofelia] object.
My question regarding that is how to use a shader output as the input for the next shader... -
@Jona I don't know how easy or difficult it would be to design the shader effect chain but If you can implement multiple shader effects in one [ofelia] object, it won't be difficult to split it into multiple [ofelia] objects that work in chain. So first, I would suggest you try to implement two shader effect chain in one [ofelia] object and then try to split it into two [ofelia] objects.
I think this post might be helpful: https://gamedev.stackexchange.com/questions/22216/using-multiple-shaders -
@Cuinjune thanks for the link and your suggestions. so it sounds like it is possible, but also not the easiest task.
It seems the easiest to put every effect of the desired chain into one shader.
But this sounds promising:
"You just bind one shader, render all the objects using that shader, then bind the next shader, render the objects using that one, etc.
You can have as many shader objects (shaders loaded into memory and compiled) as you want; only one can be bound (active) at a time."
They also write about framebuffers, perhaps that is what I would need for a video delay, but that is another topic...
And I am really new to GLSL, so not everything that is possible with openGL is possible for me (yet).
I will give it a try perhaps...A few websites with GLSL content and code:
https://www.interactiveshaderformat.com/
https://thebookofshaders.com/
https://www.shadertoy.com/
https://gl-transitions.com/
http://glslsandbox.com/ -
i emulated the pixfilm metaimage object. I had to write the shader by myself this time, because I did not found anything similar. I am sure the code can be optimized, but it works
ofelia_video_glsl.zip// fragment program uniform sampler2D Tex0; uniform vec2 resolution; uniform float colorFade; uniform float MosaicNumber; void main() { vec2 texCoords = vec2(floor(gl_TexCoord[0].s * MosaicNumber) / MosaicNumber, floor(gl_TexCoord[0].t * MosaicNumber) / MosaicNumber); vec4 color = texture2D(Tex0, texCoords); vec3 lum1 = vec3(0.299, 0.587, 0.114); color = vec4(vec3(dot(color.rgb, lum1) * (1.0 - (colorFade*(-1.0)+1.0)) + (color.rgb*(colorFade * (-1.0) + 1.0))), color.a); vec2 uv = (gl_FragCoord.xy - 20.0) / resolution; uv.y = uv.y * (-1.) + 1.; uv.xy *= MosaicNumber *(ceil((1.-uv.x))); vec4 color2 = texture2D(Tex0, mod(uv, 1.0)); vec3 lum = vec3(0.299, 0.587, 0.114); color2 = vec4(vec3(dot(color2.rgb, lum) * (1.0 - colorFade) + (color2.rgb * colorFade)), color2.a); vec4 color3 = (color * color2); gl_FragColor = color3 * 2.; }
and this are the effects that i collected so far ( also finding out about the possibilities...):
-
@Cuinjune apparently I could not figure out how to implement two shaders in one object.
Is there a simple trick or is it some openGL magic?
From your link:
"The simple answer is you change them between each draw call. Set a shader, draw a teapot, set another shader, draw another teapot."
But than the draw function needs to be faster than what is drawn on the screen? And somehow I need to get the render result from shader 1 to shader 2?Or is that an easy solution?
"In terms of implementation, in every frame I use glUseProgram(1) and glUseProgram(2) to change shaders?"The Framebuffer Object https://www.khronos.org/opengl/wiki/Framebuffer_Object sounds very interesting, but that is over my head...
Or perhaps it is really the the best solution to have all effects in one shader?
Something like that:uniform int shaderType; const int kShaderType_X = 1; const int kShaderType_Y = 2; const int kShaderType_Z = 3; vec4 doShaderTypeX() { // ... do whatever you need for the first shader type } vec4 doShaderTypeY() { // ... do whatever you need for the second shader type } vec4 do ShaderTypeZ() { // ... etc. } void main() { vec4 result; if (shaderType == kShaderType_X) { result = doShaderTypeX(); } else if (shaderType == kShaderType_Y) { result = doShaderTypeY(); } else if (shaderType == kShaderType_Z) { result = doShaderTypeZ(); } }
I will think about it...
-
I think I found a solution for mixing shaders.
First I tried to use 3 fbo´s (one for each video effect). That did work, but not for mixing but for layering the results.
Now I use only one fbo. Perhaps that is really the simple trick
I am not totally sure because, there are some video artefacts, with some effect combinations.
But I think it is the interaction of the (for interaction wrongly programmed) shaders, because the artefacts are reproduceble and not random.
It is not really modular yet, but I think it could be possible to build such a system.
Right now it is kind of a glitch generator for videos... -
The glitches are gone and the mixer works now as expected
It is now also an effect chain, effect one goes into effect two and so on.
I think in the glitch version everything was mixed together...
Very nice that this is possible with Ofelia (Pure Data / Lua / Open Frameworks/ GLSL).
I use 4 fbo´s now (one for the video player and one for each effect), just did not know how to use them right.
But somehow I found some of the old glitches quite fascinating.
I would be happy about feedback and suggestions (how to improve the patch)...
One question: Right now the functionality depends on the creation order of the Ofelia objects, because that also seems to be the draw order.
Can I create a constant draw order somehow?
Edit: I think the fbo's are also the solution for a video delay, i just need to find out how to grab for example every 5th frame into 10 fbo buffers. Then I can mix the fbo's with a GLSL file...