There’s a code example for a multi-execution matchbox in
/opt/Autodesk/presets//matchbox/shaders/EXAMPLES
The ability to run multiple passes in one shader sounds interesting, but I can’t find any documentation on this.
The example file (MultiExecutionSeparableGaussianBlur) isn’t listed here:
https://help.autodesk.com/view/FLAME/2022/ENU/?guid=Flame_API_Shader_Builder_Creating_a_Matchbox_Shader_Matchbox_Shader_Examples_html
The codes uses a uniform (adsk_result_execution) that isn’t listed here:
https://help.autodesk.com/view/FLAME/2022/ENU/?guid=Flame_API_Shader_Builder_Shader_API_Documentation_html
And the XML uses a Shader attribute (NbExecutions) that isn’t listed here:
https://help.autodesk.com/view/FLAME/2022/ENU/?guid=Flame_API_Shader_Builder_About_shader_builder_XML_html
Does any documentation exist?
Or does anyone have any experience with it?
-Ted
1 Like
lewis
June 28, 2023, 6:46pm
2
I’m not sure what’s going on with the documentation either but I used it in the firefly-fixing shader linked below if you want an example… the slightly annoying thing was that you have to specify how many times to repeat in the XML, it can’t be set from a UI control, so if you do want it to be variable you have to write the logic for that yourself by checking the adsk_result_execution uniform and either running your process or just doing nothing and passing the input through. Actually I made it so that it can repeat the median process, or figure out that it’s on the last iteration and run some other stuff instead
Pretty cool if you want to do a similar process a few times, it avoids having to have loads of .glsl passes which are very similar, something I have definitely been guilty of in some shaders and I’m pretty sure wastes GPU memory!!
#version 120
// This single pass runs several times, first doing repeated
// 3x3 medians and then keying locally-hot pixels and replacing
// them with the median
uniform sampler2D front, strength, adsk_results_pass1;
uniform int iterations, adsk_result_execution;
uniform float sensitivity, trimnoise;
uniform bool showfireflies, showmedian;
uniform float adsk_result_w, adsk_result_h;
vec2 res = vec2(adsk_result_w, adsk_result_h);
// Macros for sorting network below
#define COMPARE(a, b) length(v[a]) < length(v[b])
#define SWAP(a, b) temp = v[a]; v[a] = v[b]; v[b] = temp;
#define COMPARESWAP(a, b) if(COMPARE(a, b)) { SWAP(a, b) }
void main(void) {
vec2 xy = gl_FragCoord.xy;
This file has been truncated. show original
<ShaderNodePreset SupportsAdaptiveDegradation="False" SupportsAction="False" SupportsTransition="False" SupportsTimeline="False" TimelineUseBack="False" MatteProvider="False" CommercialUsePermitted="True" ShaderType="Matchbox" SoftwareVersion="2017.0.0" LimitInputsToTexture="True" Version="2" Description="Attempts to remove the hot firefly pixel noise that appears in CG renders with bright lights hidden behind other objects
Quick demo: https://www.youtube.com/watch?v=GuvRoN5WfM4
lewis@lewissaunders.com" Name="Fireflies">
<Shader NbExecutions="12" Clear="0" GridSubdivision="1" OutputBitDepth="Output" Index="1">
<Uniform ResDependent="None" Max="1000000.0" Min="0.0" Default="5.0" Inc="0.01" Tooltip="Increase to remove more noise" Row="1" Col="2" Page="0" Type="float" ChannelName="Sensitivity" DisplayName="Sensitivity" Name="sensitivity">
</Uniform>
<Uniform ResDependent="None" Max="1000000.0" Min="0.0" Default="0.0" Inc="0.01" Tooltip="Increase to remove some darker noise that wouldn't be detected otherwise" Row="2" Col="2" Page="0" Type="float" ChannelName="Trim noise" DisplayName="Trim noise" Name="trimnoise">
</Uniform>
<Uniform Row="1" Col="3" Page="0" Default="False" Tooltip="Apply the median-like filter to the whole image, with no noise detection" Type="bool" ChannelName="Show median only" DisplayName="Show median only" Name="showmedian">
</Uniform>
<Uniform Row="2" Col="3" Page="0" Default="False" Tooltip="Output just the detected noise" Type="bool" ChannelName="Show fireflies only" DisplayName="Show fireflies only" Name="showfireflies">
</Uniform>
<Uniform InputColor="67, 77, 83" Mipmaps="False" GL_TEXTURE_WRAP_T="GL_CLAMP_TO_EDGE" GL_TEXTURE_WRAP_S="GL_CLAMP_TO_EDGE" GL_TEXTURE_MAG_FILTER="GL_LINEAR" GL_TEXTURE_MIN_FILTER="GL_LINEAR" Type="sampler2D" Name="adsk_results_pass1">
</Uniform>
<Uniform Index="0" NoInput="Error" Tooltip="" DisplayName="Front" InputType="Front" Mipmaps="False" GL_TEXTURE_WRAP_T="GL_CLAMP_TO_EDGE" GL_TEXTURE_WRAP_S="GL_CLAMP_TO_EDGE" GL_TEXTURE_MAG_FILTER="GL_LINEAR" GL_TEXTURE_MIN_FILTER="GL_LINEAR" Type="sampler2D" Name="front">
</Uniform>
<Uniform Index="1" NoInput="White" Tooltip="" DisplayName="Strength" InputType="Selective" InputColor="80, 80, 20" Mipmaps="False" GL_TEXTURE_WRAP_T="GL_CLAMP_TO_EDGE" GL_TEXTURE_WRAP_S="GL_CLAMP_TO_EDGE" GL_TEXTURE_MAG_FILTER="GL_LINEAR" GL_TEXTURE_MIN_FILTER="GL_LINEAR" Type="sampler2D" Name="strength">
</Uniform>
This file has been truncated. show original
Thank you!!
So is the result always adsk_results_pass1 no matter how many times the shader has been run?
-Ted
lewis
June 29, 2023, 4:32pm
4
Yeah exactly - feels weird to be reading from the pass you’re currently executing but you actually get the results from the previous iteration instead
I haven’t tried but I think you could have other passes after the multi-execution one, and if you read adsk_results_pass1 from those you’d get the last iteration…
You are correct, I’m using a pass after a multi-execution pass.
It took a lot of trial & error, and when I finally got it to work it still didn’t quite make sense to me
-Ted