FrameGraph API

Over the last several weeks, I’ve been working on improving @JhonKkk’s FrameGraph API. That project turned into a complete rewrite, which turned into another rewrite, so I guess this would be “JME FrameGraph, version 3.” Hopefully this one will make it into the core engine.

This API is based on the GDC presentation linked below, and on @JhonKkk’s work.

The goal is to provide a modular rendering architecture and a render resource manager to minimize resource creation and binding. While Johnkkk’s implementation worked, it did not provide a clean, reusable API. Therefore, I’ve reworked virtually all of the related Java code and API. I am finally ready to present the work I’ve done to the community for review so that hopefully this will get integrated to the core engine.

How the FrameGraph works

The FrameGraph, put simply, is an object that renders a ViewPort according to a list of passes. The FrameGraph can be thought as a node editor (like Blender’s shader editor), where each pass is a node, and passes, like nodes, can share resources between each other. The tricky part is managing the resources that pass between passes as efficiently as possible.

To handle resources, I’ve implemented a “lazy” resource manager, which attempts to minimize the number of existing resources by reusing resources where possible. It also includes a “reservation” protocol that allows passes to snag the exact resource they used last frame to minimize the number of texture binds that occur.

Rendering a ViewPort with a FrameGraph has 4 stages:

  1. Resource Declaration. All passes are expected to declare whatever resources they plan to use for rendering ahead of time, so that the resource manager can plan out which resources are allocated where and when.

  2. Pass Culling. Any passes which produce resources that are not then referenced by another pass are culled. This process is recursive, so once a pass is culled, whatever pass it was getting resources from might be culled as well.

  3. Execution. All unculled passes are expected to, during this step, acquire whatever resources necessary, do whatever is needed (like rendering), and release all declared or referenced resources.

  4. Reset. All resource pointers are destroyed (not the resources themselves), and passes do whatever cleanup is necessary.

All resources that are not used for the entire rendering process of all ViewPorts are deleted.

Here is the PR for this feature:

I would greatly appreciate any advice and testing. Thank you all for your support!

17 Likes

I am not a big fan of enums for things that are ment to be customizable.

enum RenderPath //in RenderManager.java

for example.

1 Like

Actually, that enum could probably be removed right now, as I’m not using it. It was left over from Johnkkk’s code.

1 Like

Nice. was not sure how much of johns code is still used from a quick lookover

1 Like

Most of his shader code is still in use, but his Java code is rapidly approaching zero at this point.

Thank you for taking the challenge for creating version 3 of the frame graph enhancements initiative.
So, if I understand correctly there are two parts for this feature, first is the " framegraph framework that supports 3 render paths" which is what Jonkk did for improving JME’s FrameGraph.
Second, is the API on top of that which the community asked for improving before merging the entire feature.
So if I’m reading this right, you modified both those parts to meet the community requirements (in the API part) and while doing so you also changed/improved large parts of Jhonkkk’s work.
This is really exciting! because now we have new ownership for this feature. did you try integrating it with v3.7? I’m curious to see whether or not we have major conflicts with existing code.

5 Likes

You’re welcome, glad to do it. :smiley:

I have not tried integrating with 3.7. I had assumed this feature would be integrated in the next engine release past 3.7, since we are now in feature freeze. Also, a feature as large as this will need a good deal of testing and bug fixing, so it will probably be a while longer before this is ready for release.

For merge conflicts, unless another PR has been messing around with rendering internals as well, I believe there will be very few, as the overwhelming majority of the changes are on new files.

4 Likes

Yes, of course it will need to be integrated in future release. I just was curious about conflicts. Actually the way we work here there is not much difference between updating from v3.7 or from master so whenever you update from master we will know about any conflicts.
I think Riccardo contributed some rendering code to v3.7 (a few thousands lines actually - quite big) so conflicts might occur.

1 Like

Hi @codex.

I recently wanted to test this PR but ran into a small problem; I cannot execute certain classes (examples) since there are objects (classes) that do not exist but are implemented in the example…

By the way, download the full project (zip) from github; Could I be doing something I shouldn’t? :thinking:

1 Like

Hi Swiftwolf, thanks for trying it out!

No, you’re fine. There are several tests that use API that has been deleted, and I haven’t gotten around to fixing those tests up yet. The primary test class I am using is TestShadingModule.java, which should work on the latest commit that I uploaded a few minutes ago.

2 Likes

I understand, thanks for clarifying… as soon as I have a little more time; I would like to do more testing with this new API. :yum:

1 Like

Progress Update

  • FrameGraphs can more easily be constructed in code.
  • Tickets can directly reference each other, so ticket getters/setters are no longer necessary.
  • Tickets are now created once during initialization, instead of at every render setup.
  • Attribute passes allow game logic to communicate with the framegraph.
  • Junction passes allow game logic to alter the layout of the framegraph.
  • All tests under jme3test.renderpath have been passed (with the exception of android tests, which I haven’t tried).
  • FrameGraphs can be loaded from .j3g binary files using the asset manager.
  • Three simple framegraphs have been added under Common/FrameGraphs/ in core.
  • ViewPorts can opt-out of using framegraphs, even if the default framegraph is set (perhaps useful for GUIs).
  • FrameGraph rendering can be profiled.
  • Javadoc and licenses have been added.

Issues

  • Having two framegraph-driven viewports overlaid can often be problematic, depending on how the framegraphs are set up.
  • Deferred and tiled deferred pipelines make background black under certain unknown circumstances.
  • Lighting looks “messy” with deferred and tiled deferred pipelines. See below.

11 Likes