I'm working on a scientific visualization. I had implemented a basic PBR renderer in OpenGL for it, but my renderer still lacks a lot of the features needed for my materials. Filament, by contrast, is very fully-featured and I would love to integrate it.
However, I don't see how I can render my particle system when using Filament. I need to render 10k - 100k particles updated on the CPU. I'm currently using instanced rendering (though I hear vertex-shader based approaches are better). I suppose I could try generating all the geometry on the CPU and updating a filament::VertexBuffer every frame, but I was wondering if there's a better way.
It would be perfectly acceptable (maybe even preferable) if I could make my own OpenGL calls as part of the rendering pass, or even if I could just render into the scene after filament (as long as I have depth information). The particles don't really need a fancy PBR shader, so I don't need a very tight integration.
I don't care about the solution being cross-platform. That would be a bonus, but I just need it to work on Linux/OpenGL.
Do you have any suggestions?
Currently the way to do this is to update a VertexBuffer on every frame, we're however open to suggestions on how to better support the use case of particle systems (it's on our long todo list :). Instanced rendering is also something we'd like to support so this might be a good fit for us.
What we don't want to offer though is a way to run arbitrary OpenGL calls. The main reasons are that our GL code is on a separate thread that we control, that we track the GL state very closely (3p code could lead to subtle issues) and that we also support Vulkan (and potentially other backends in the future).
I'd love to know more about how your particle system currently works to get a better idea of what we could do to support it efficiently.
Note that we do support rendering points, all the necessary attributes are available in GLSL (e.g. point size), so you should already be able to render a bunch of textured points with varying sizes, using a custom material. I'd be curious to see how far one can go.
The particule simulation itself has to be done on the CPU right now. You also need to provide a correct bounding box.
@romainguy, what would you suggest to do if I want to use some 3rd party OpenGL code to draw on top of or behind the filament result? You do something like that with the imgui logic in the samples, so clearly it's possible, but is there a recommended way to hook into the filament drawing loop?
Our ImGui implementation creates Filament objects, it doesn't run custom GL code. Are you doing something on Android or other platforms?
Android, iOS, WebGL, the lot... So I'd preferably find something that doesn't need re-implementing three times.
Filament has the concept of external texture that currently works only on Android but that would be a way. Another solution would be to use a second native GL drawing surface for the other renderer (Filament can render to a transparent surface if you need to draw behind).
I think I have found a workaround for most of the things I need to do. I have one remaining question related to drawing of UI layers. I know I can draw a triangle which sits 'behind' the 3d scene by using a material which has 'blending: opaque' and 'depthCulling: false'. Similarly, I can draw a partially transparent triangle in front of everything else by using 'blending: transparent' and again 'depthCulling: false'. Is there any way in which I can draw a partially transparent quad which is guaranteed to be drawn after a particular set of 3d objects in a scene (set A), but guaranteed to be drawn before another set of 3d objects (setB)? So that my quad always hides things in setA, but never hides things in setB? (it's of course trivial if setB objects are always closer to the camera than setA objects, but they are not).
(To clarify how this relates to my original question: what my original, pre-filament code, did was to first draw objects in setA, then clear the depth buffer, draw the quad, clear the depth buffer again, then draw objects in setB. So I am essentially looking for a way to clear the depth buffer between drawing of two sets of objects).
setBlendOrderAt might be helpful for your issue.
Can any one please tell me, How to make filament view transparent in on windows ? Im trying to readPixels and save a png image. I tried by setting alpha component of view's ClearColor to 0, but this didn't create transparent background for the image.
@Raki When calling Engine::createSwapChain() you can pass flags, and more specifically you can pass SwapChain::CONFIG_TRANSPARENT.
@romainguy Thank you for the reply. I tried with your input
const uint32_t windowFlags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI;
mWindow = SDL_CreateWindow("Hello Filament", x, y, (int)TargetWidth, (int)TargetHeight, windowFlags);
void* nativeWindow = ::getNativeWindow(mWindow);
engine = Engine::create();
swapChain = engine->createSwapChain(nativeWindow, SwapChain::CONFIG_TRANSPARENT);
view = engine->createView();
view->setClearColor({ 0.1, 0.125, 0.25, 0.0 });
but I got image with black background

Am I missing something ?
What are you supposed to see behind? Filament won't make the window itself transparent, only the OpenGL render target.
@romainguy I'm trying to take a screen shot of my current window, so reading pixels from my renderer and saving it as a png image. Im expecting the black area in the attached image to be tranaparent.
I checked our code and unfortunately transparent rendering currently isn't supported on desktop targets, only on Android. Sorry about that :(
@romainguy Thank you for your support. And also thank you so much for bringing Filament for public access. It helped us a lot for PBR on Android.
@prideout Could you tell me in 1 or 2 lines how setBlendOrderAt is supposed to work? What do I feed to primitiveIndex? I was hoping that I would be able to call this once on an entity with associated material that uses shadowMultiplier=true, and once on another unlit shaded entity, and by setting order appropriately determine which one ends up drawn in front. I'm probably missing something, any help is much appreciated.
Closing, we now have point_sprites.cpp in our samples folder to demonstrate how to use point sprites. (We also fixed a bug on desktop platforms that prevented point sprites from being visible.)
Most helpful comment
Closing, we now have
point_sprites.cppin our samples folder to demonstrate how to use point sprites. (We also fixed a bug on desktop platforms that prevented point sprites from being visible.)