-
-
Notifications
You must be signed in to change notification settings - Fork 315
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor (GLMakie) render order (experimental) #4150
base: master
Are you sure you want to change the base?
Conversation
Compile Times benchmarkNote, that these numbers may fluctuate on the CI servers, so take them with a grain of salt. All benchmark results are based on the mean time and negative percent mean faster than the base branch. Note, that GLMakie + WGLMakie run on an emulated GPU, so the runtime benchmark is much slower. Results are from running: using_time = @ctime using Backend
# Compile time
create_time = @ctime fig = scatter(1:4; color=1:4, colormap=:turbo, markersize=20, visible=true)
display_time = @ctime Makie.colorbuffer(display(fig))
# Runtime
create_time = @benchmark fig = scatter(1:4; color=1:4, colormap=:turbo, markersize=20, visible=true)
display_time = @benchmark Makie.colorbuffer(fig)
|
|
||
# Holds the (temporary) render of a scene | ||
color_buffer = Texture( | ||
RGBA{N0f8}, fb_size, minfilter = :nearest, x_repeat = :clamp_to_edge |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean that GLMakie can support transparent backgrounds? Or would that need improvements to the shader / OIT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In saved images with some more fixes yes, more or less
begin
scene = Scene(backgroundcolor = (:orange, 0.3), clear = true)
s1 = Scene(scene, Rect2f(100, 100, 100, 100), backgroundcolor = (:cyan, 0.3), clear = true);
s2 = Scene(scene, Rect2f(300, 100, 100, 100), backgroundcolor = (:purple, 0.3), clear = true);
scatter!(scene, rand(10), rand(10))
screen = display(scene)
end
The main thing that's clashing with transparent backgrounds here is FXAA. It requires opaque pixels to do it's thing which you don't have in a transparent render. And also not in a transparent subscene.
Another annoyance is that you can't work with the usual (c.a * c.rgb + (1-c.a) * background.rgb), 1)
blending because it assumes the background is opaque. I think with two transparent colors you have to do (c1.a * c1.rgb + (1-c1.a) * c2.a * c2.rgb, (1-c1.a) * (1-c2.a))
and do the final background blend as (composed.rgb + composed.a * background.rgb, 1)
.
But OIT doesn't care. Plot rendering doesn't care. SSAO I haven't tested but it also shouldn't care.
(Transparent windows I assume aren't possible from a GLFW/OS side but I haven't checked.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, I guess we could always turn FXAA off in the short term though.
What I meant was having a completely transparent background - at which point I guess you don't need a final blend. (Motivation was finally finishing that CairoMakie PR that allows rendering from other backends natively)
glfw/glfw#197 seems to indicate that GLFW supports transparent framebuffers and windows via a window hint.
# Holds the (temporary) render of a scene | ||
color_buffer = Texture( | ||
RGBA{N0f8}, fb_size, minfilter = :nearest, x_repeat = :clamp_to_edge | ||
) | ||
# Order Independent Transparency | ||
HDR_color_buffer = Texture( | ||
RGBA{Float16}, fb_size, minfilter = :linear, x_repeat = :clamp_to_edge |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be returned by colorbuffer
as well somehow? Might be useful for people who want more precise renders / colors...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not right now. I'm also not sure what you mean with precise renders...
As it is now, every scene effectively clears a section of this buffer, then does all the rendering on it and runs all the post processors with it. So it's the same as colorbuffer(detached_sub_scene)
after that scene is done rendering, except with a bunch of old junk around it. At the end of a frame it maybe overwritten by another scene.
I could add a colorbuffer(screen, scene)
that only renders a selected scene if that's what you want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The colorbuffer(screen, scene)
thing is exactly what I need for CairoMakie :D since cropping the scene by its bbox also includes axis artifacts, etc.
|
||
# Holds the (temporary) render of a scene | ||
color_buffer = Texture( | ||
RGBA{N0f8}, fb_size, minfilter = :nearest, x_repeat = :clamp_to_edge |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, I guess we could always turn FXAA off in the short term though.
What I meant was having a completely transparent background - at which point I guess you don't need a final blend. (Motivation was finally finishing that CairoMakie PR that allows rendering from other backends natively)
glfw/glfw#197 seems to indicate that GLFW supports transparent framebuffers and windows via a window hint.
Benchmark ResultsSHA: 99f7f36c1aba9c45648e66df3c67d7adb7ad6bc9 Warning These results are subject to substantial noise because GitHub's CI runs on shared machines that are not ideally suited for benchmarking. |
Description
Goals
The goal of this pr is to render scenes one by one in a depth-first order (render scene, then go deeper). This aims to:
scene.clear = true
work again (clear a section of the screen for the clearing scene)scene.children
into normal scenes and overlay scenes to make this usable)Related Issues
Related issues:
Fixed unreported (?) issues:
Empty scenes do not render if added after display
Scene order depends on (plot) insertion order
Changes
This pr mainly changes the scene/plot/renderobject storage infrastructure to more closely represent the scene tree from Makie and allow for rendering to follow a depth-first order.
Changes in more detail
On master scenes, plots and renderobjects are managed by the following fields in
Screen
.These are replaced by a
scene_tree::GLSceneTree
which contains scene representatives holding on to rendering relevant information and the render objects corresponding to the scenes plots.
To keep the GLSceneTree in sync with Makie scenes, they now notify the backend via
push!(::Scene, ::Scene) -> insert!(screen, scene, parent, index)
. The index is the index intoscene.children
where the scene is inserted. Most of the insertion and deletion logic is inGLScene.jl
.In terms of rendering things look more different than they actually are. Previously we effectively had
And now we have:
Plots/Renderobjects are still rendered in the same order, except that they are split up by scene. The post processors and buffers have changed a little bit to accommodate a transparent color buffer. Specifically the default blending operation of
has been replaced as it assumes the dst to be opaque. To figure out what it should be we can consider two transparent blends (c1, c2) onto an opaque color (c0) via the above. This gives us:
This mean we want to have the destination color in a
dst.a * dst.rgb, (1 - dst.a)
format. The blending rules then become:TODO
robj2plot
handling (global + per-scene vs just global)haskey
,get
,isempty
, etc)scene.children
colorbuffer(screen, scene)
clear = false
and consider also preserving depthFor the future
Some things I want to change but probably not in this pr so that it does not become overwhelmingly big
translate!
when possible but not requiredType of change
Checklist