Not a lot of progress since it is still not sure that we will need LPEs at Ubisoft Animation Studio, so I cannot really dedicate office hours to it
However I started working on it today on my free time, starting from this differential https://developer.blender.org/D4837 since it touches similar things.
For now I have extracted LPEs parsing/evaluation source code from OSL and removed its dependencies to other parts of OSL and OIIO (see here https://github.com/Celeborn2BeAlive/LightPathExpressions).
My next step is to experiment with it inside Cycles, using it for already existing passes (beauty, diffuse_direct, etc) to identify which parts of the source code I have to change and to check if the automata data structure should be changed to fit in Cycles.
After experiments my roadmap for the clean integration will be:
- In the UI, add a panel “LPE” in the view layer tab from the properties editor (like the AOV panel added D4837), allowing to add LPEs with a name associated to it to define a new render pass. I think I will have to look at the compositing graph part also to have LPE passes as output of the Render Layers node.
- Send user defined LPEs to Cycles and build the automata
- Adapt the structure PathRadiance to store accumulations for each LPE
- Use the automata during rendering to accumulate contributions based on LPE state during path tracing
- Write accumulations to framebuffer
- Check everything works correctly on the GPU and adapt the automata data structure if it’s not GPU friendly
Things I have to investigate:
- Where to store LPEs and pass names ? I guess its in DNA but I need to get more familiar with the system.
- Denoise of passes ? Is it done automatically for all passes of the framebuffer or should I do something ?
- Provide the python API to add LPEs (maybe this will come naturally when I’ll look at the UI part)
- About the LPE library code extracting from OSL, where should I put it ? “extern” directory with a C API ?
- Should LPE automata also be used for already existing passes (diffuse_direct, diffuse_indirect, etc) or just for user defined LPEs ? It can simplify the source code, but maybe decrease performance, so I think profiling will be needed to take a decision on that.
- LPEs (as defined by the OSL convention) support the usage of “tags” inside token. For example <‘L’.[‘light_1’|‘light_2’]> would match some event ending on a light with tag light_1 or light_2. The question is what to use to define the tags ? The obvious answer would be to use the name of the entity that is found during path tracing for a specific event. But maybe another properties added to objects would be better (something like “LpeTag”). It would permit to group some objects under a given LpeTag. But using names also allows to define groups by just using the ‘|’ operator. However I guess it might increase the size of the automata since more transitions are required. Maybe an hybrid solution is the best: Name by default, LpeTag if it exists on the object.