Writing an Imagepipeline Plugin
C++ Code
Files that need to be created:
- Header: include/slg/film/imagepipeline/plugins/yourpluginname.h
- Source: src/slg/film/imagepipeline/plugins/yourpluginname.cpp
Files that need to be edited:
- Filmparse: src/slg/film/filmparse.cpp
- CMakeLists.txt: src/slg/CMakeLists.txt
Example: OverExposureDetection Plugin
As an exmaple for this tutorial, we'll write a plugin that sets the pixel color to red when it detects pixels which are brighter than a specified threshold. The threshold can be specified by the user in the .cfg file.
Header File
Create a new header file with filepath include/slg/film/imagepipeline/plugins/overexposuredetection.h
Modifying Filmparse
Open the file src/slg/film/filmparse.cpp and include your header file, right under the last include line and before the "using namespace x" lines.
#include "slg/film/imagepipeline/plugins/overexposuredetection.h"
In the same file, go to the function Film::AllocImagePipeline. You'll see a long if/else if/... section where the plugins are initialized. Add an else if clause at the end, before the final else:
// ... } else if (type == "OVEREXPOSURE_DETECTION") { const float threshold = Clamp(props.Get(Property(prefix + ".threshold")(1000.f)).Get<float>(), 0.f, INFINITY); imagePipeline->AddPlugin(new OverExposureDetection(threshold)); } else // ...
The string for the type == "PLUGINNAME"
comparison can be chosen freely (it does not occur in any other files).
By convention it should be all upper case, with underscores for better readability in long names.
Next, parse the value that the user set for the "threshold" parameter in the .cfg configuration file of a luxcore scene definition. Our plugin is configured like this:
# Film image pipeline plug-ins film.imagepipeline.0.type = TONEMAP_LINEAR film.imagepipeline.1.type = GAMMA_CORRECTION film.imagepipeline.1.value = 2.2 # Our plugin: detect overexposure after all other imagepipeline operations are done film.imagepipeline.2.type = OVEREXPOSURE_DETECTION film.imagepipeline.2.threshold = 10
However, the user can also omit the film.imagepipeline.2.threshold
line if we define a default value in the filmparse function.
It is also a good idea to sanitize the input with a Clamp function. In our case, a threshold below 0 does not make sense.