-
-
Notifications
You must be signed in to change notification settings - Fork 557
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add the possibility to create custom GLSL filters and use them as nodes. #1839
base: master
Are you sure you want to change the base?
Add the possibility to create custom GLSL filters and use them as nodes. #1839
Conversation
Thanks for working on this, it's something I've wanted to implement for quite some time (#692). It's nice to see the regex implementation for detecting uniforms since regex is not my strongest suit. However there are things that should be implemented differently. I think the shaders should be editable/compilable on the fly in the app rather than loaded on startup with external files. This makes testing a lot faster and easier, and also means they can be copied and pasted to other peoples' setups through text just like any other node setup without them having to set up the shaders too. I also think I'd have users set the data types (and other things like human names, min/max, etc) through shader comments rather than being part of the uniform name. It's up to you if you want to try implementing all of that too. I was planning to work on this soon anyway, and it would still be useful to use parts of this PR (like the uniform regex). |
I had always assumed there would be a text editor in the param view (similar ot the rich text node) but I suppose you could always have a file path selector instead and use an external IDE. For data types etc. would you be looking at something like:
I suppose you'd also need som ekind of syntax checker in the node for this custom data? |
I was thinking a separate dialog because shaders can get long quickly, and a more code-friendly editor with auto-indentation because coding without something like that is a pain. However, you make a good point about also allowing an external code editor. I think we should do both.
My thinking was it could be the lines just above the uniform, kind of like C# attributes:
Though perhaps doing it all in one line like yours is more practical? Either way, it should be relatively easy to string parse |
That becomes unwieldy rather quickly. It would also be nice to support descriptions. I would thus prefer the C#/JavaDoc/whatever style with multiple lines above the line of code. The exact syntax can still be discussed but should make it easy to parse. |
I see what you mean yes, a single line would get very messy
I suppose it becomes a question of whether we store these custom shaders as a file on disc or in memory/the |
The shaders will be stored in the |
Maybe it might be nice to not mangle the shader and it's metadata together and separate it? Like having a XML file with those attributes/parameters and the shader either within that XML-file like this (of course some things could/should move into attributes instead of nodes, but just for the idea :)): <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<filter>
<parameters>
<parameter>
<name>Color</name>
<type>color</type>
<uniform>color_in</uniform>
</parameter>
<parameter>
<name>Radius</name>
<type>float</type>
<uniform>radius_in</uniform>
<min>0</min>
<max>200</max>
<default>10</default>
<animateable>true</animateable>
</parameter>
</parameters>
<shader>
<![CDATA[
uniform vec4 color_in;
uniform float radius_in;
...
]]>
</shader>
</filter> Pro: All in one file <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<filter>
<parameters>
<parameter>
<name>Color</name>
<type>color</type>
<uniform>color_in</uniform>
</parameter>
<parameter>
<name>Radius</name>
<type>float</type>
<uniform>radius_in</uniform>
<min>0</min>
<max>200</max>
<default>10</default>
<animateable>true</animateable>
</parameter>
</parameters>
<shader>myShader.glsl</shader>
</filter> Pro: The shader file can be edited in a proper editor |
I don't think an XML format is necessary, that would be a whole other specification that would need to be maintained, and the point here is not to have them as external files so they're always easily portable with projects or with copy/paste data. Besides, I don't think a few comments in the shader is really mangling it that much. |
Just thinking as I type :) True that. I thought that you actually can write a whole specification with XML in some schema files etc.. External editors knowing the schema file could help as IDEs with autocompletion and syntax errors. And with the ove files, there is already everything in place to parse them. 🤔 |
I agree that compiling on the fly is way better than reload the application. This limitation is due to the fact that the only place where parameters can be added is the constructor of the node class, as most of the other function as "const". In order to have several shaders, we should have a complex editor with tabbed interface. If I understand, when you want to close or re-open a shader, you don't open or close a file, but you work with a list of shaders that is embedded in the project. Did I get it right? Also, the .ove file will contain the full code of the shader inside an XML tag. I'm not an expert with XML, but what would happen if shaders code contains in a comment a symbol like '/>' ? May this be close wrongly the XML tag? What about saving the shader in a .frag file and include the file path of the shader in the .ove project? I want to propose an intermediate step that goes in the direction pointed by Matt but it's not too much work for a single PR. About the comments for metadata, I think that the XML approach proposed by philiplb may be a little overkill, especially if the XML that contains the shader must be embedded again int the project file.
Each line starting with //! is an entry that will be applied to the next parameter defined by a 'uniform' line. |
There are mechanisms to add/remove inputs on the fly. They are limited, but they existed and I've been expanding their reach (specifically so that something like that can be implemented eventually).
It'd be both ultimately. Users will be able to save custom node setups for reusing in other projects, but also the node architecture is designed to be as shareable and portable as possible (e.g. you can copy node setups and paste them into text so they can be shared across e-mail/IM/forums/etc). For this to carry through, the shader code should be included.
Don't worry about this, our XML serializer should correctly escape anything that's not XML-compliant.
Creating/deleting nodes is unnecessary as I mentioned in the beginning. It should just be a "Shader Node" with a text input for code, and then the other inputs can be added/removed as necessary.
Something like this could be good, could perhaps even include an "Olive" or "OVE" keyword to make it even more unambiguous, but that may not be necessary. |
I was just typing that I'd find it strange as well to bind shaders to the project rather than to the application, but then this popped in:
So the user can have a collection of custom node setups he got from somewhere on the hard drive and just use it. Some nodes contain shaders. And of course, a node setup could just consist out of a shader node. |
@philiplb Yep that's the plan! |
OK, let me recap to see if I got it:
Hope it's all correct. |
I think that is correct yes. I'd add that edits within the text editor would also need to be undoable commands and put Olive in an unsaved state. I think there should also be a "Edit in external application" button that opens the shader in the chosen editor (VS code, Notepad whatever) which would be set in Preferences |
It should probably have frag and vert inputs?
Yes,
Yes, the ideal place to detect such changes is in
I don't know about this? As I've mentioned, we'll have separate functionality for saving node setups, which will include the code since it's just an input. Just to be clear, what are you currently planning to do @AngeloFrancabandiera? You mentioned earlier of proposing an intermediate step, are you still working in that sort of direction or are you going to try to take on the whole thing? |
I'd like to try the whole thing, but I don't know if it's a good idea to do all in a single Pull Request. In particular, I think the first step may have the following limitations:
OK, no 'save as file'. |
Those are minor convenience features. Olive is a video editor, not a code editor. I don't see why it should offer any of them only to compete with more appropriate tools – at least not until the day of Olive shipping something VEX-like. Let's just make "open in external editor" a thing. |
Qt provides a "simple code editor" example (I think with just line numbers and auto indent), perhaps we can throw that in as-is and then recommend external editors for anything more extensive. But otherwise, I think you're right that a big rich code editor is out of scope, at least for now. |
pull request 1839 (olive-editor#1839). The editor is still the default text editor and several parameters are not handled yet.
The node still uses the default editor to edit code and some issues with node inputs must be fixed.
parameter view. Keyframes are working but they are not shown in their pane until the project is saved and reloded
working pretty well, sometimes it does stop working suddenly if you make and save a ton of small edits, and it takes a bit of faffing about to get it to work again. closing and re-opening the editor fixes it. other then that I can preview the changes real time for the most case so that's really nice |
I'm pretty sure that there's no way without making Olive Wayland-aware. |
been using it for a bit now, I think it might be better to have internal and external editor both accessible from the node if at all possible, I find myself swapping between the two quite a bit, other then that, it's been fairly stable, I do run into issues sometimes when writing longer glsl filters with lots of functions as the screen will sometimes just go black instead of updating, until you play it when it will return to normal. |
@itsmattkc can we get CI on this? would be nice to get some more testers. |
I promised to @ThomasWilshaw that I would write some unit tests, at least for the parser. That's my next task. |
I've run the CI for you and I think it should run automatically from now on. ANytime you push it will re run unless you add |
I have added unit tests for input metadata parser. This also helped find a minor bug. |
Using it on windows and it's been pretty good!, a couple bugs with my editors, but im not sure they are related to the PR yet or if my editors are a bit buggy. for selecting text editor, I wonder if we might be able to optionally use a file select dialog. |
Yes, can be done.
This is a little more tricky, but I will give a thought. I can hardly imagine a feature that the current internal editor makes better than an external editor; maybe the templates for the new inputs. This feature is called "code snippets" or "code triggers" in most editors but effectively in Lapce I did not find this feature. |
lapce probably hasn't implemented it, it is undergoing a large UI re-write now so no worries on that front end, code snippets should be fine. I dont remeber if I had any other issues. editor selecting was a massive pain though , so file select dialog there IMO is necessary since app image names can sometimes be a large pain full file paths seem to out right not work on windows, all editors needed to be added to path for me to get them to work, regardless of whether or not there is spaces in the uri |
In this version I have added the file select button as requested by @Quackdoc, but I am not sure this will fix his problem; The file select dialog is just a utility to pick the executable full path and write it to the line-edit box as you would manually. @Quackdoc, may you please try with the full path with the folders separated by slash "/", backslash "" or double backslash "\"? Another variant in this version is that the custom shader nodes also appears in the transition menu. I have seen that, when using GLSL not as a filter but as a transition, it is way more convenient to have the same workflow as the other transitions (drag and drop between two adjacent clips). I have also updated the wiki page. |
it actually did fix the issue, I have a large variety of locales so maybe that's the issue? no idea, but it's a nice add regardless. I tested the transitions real quick and it does feel nice, this PR is getting to a very nice state. I don't have any qualms on either windows or linux myself from a usability standpoint other then occasionally needing to re-open the editor after a couple rounds of saving and testing (the temp file changes?). |
might be best to check for conflicts with #2236 |
This was not really easy because function 'GetShaderCode' must now be 'static' and this does not cope well with the fact that every instance must have its own shader code. |
It seems not to run automatically. Am I doing something wrong? |
Ah it's possibly only contributors who get auto run CI, I'll keep an eye on this and run it any time you do a significant commit. If I miss one feel dree to ping me as I know people are testing this. |
Yeah, pull requests from first-time contributors require approval from somebody with write access to the repository as far as I can tell. I've been holding off on approving CI runs on pull requests myself because I'm not sure how much Actions time Olive has per month. |
…' panel is open generates a crash
… multiple shaders are open
The purpose of this PR is to give the possibility to any Olive user to write a GLSL shader filter and use it in Olive's node editor.
This is the same logic of video filters that are already in Olive, but now new filters can be added without the need to re-build the application.
These filters can also be donated to the community to increase Olive's capabilities.
The shader script will specify which inputs are exposed in the GUI.
This is how it works:
in 'behavior' options panel, the user lists the ".frag" files that are located anywhere in file system;
On startup, Olive will create a new node for each valid file.
The file will be parsed to find inputs to be exposed in GUI according to the following convention:
any uniform variable starting with these prefixes, will become an input of the following type:
After the declaration of the uniform, a comment will indicate the name that will be shown in the GUI
For example if a .frag file starts with:
then 3 inputs will be added to the node; the first is a color whose name is "base tone", the second is a float whose name is "intensity" and the last is a checkbox named "use intensity".
The comment after the declaration is required to show the input in the GUI.
Each node has a built-in variable of kind "uniform sampler2D " named "tex_in" to be connected to an input image.
If this is not clear, I can provide some demo video to explain the idea a little better. I can also share simple .frag files for testing, (I will not push the to the repository because I can't figure out the right place).
Limitations: