Skip to content

Commit

Permalink
Add naive depth sorting for scatter & text (#3432)
Browse files Browse the repository at this point in the history
* add naive depth sorting for scatter & text

* add depthsorting docs

* update news
  • Loading branch information
ffreyer committed Dec 18, 2023
1 parent 5424a13 commit 64d68b4
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 1 deletion.
1 change: 1 addition & 0 deletions GLMakie/src/drawing_primitives.jl
Expand Up @@ -572,6 +572,7 @@ function draw_atomic(screen::Screen, scene::Scene,
gl_attributes[:distancefield] = get_texture!(atlas)
gl_attributes[:visible] = plot.visible
gl_attributes[:fxaa] = get(plot, :fxaa, Observable(false))
gl_attributes[:depthsorting] = get(plot, :depthsorting, false)
cam = scene.camera
# gl_attributes[:preprojection] = Observable(Mat4f(I))
gl_attributes[:preprojection] = lift(plot, space, markerspace, cam.projectionview, cam.resolution) do s, ms, pv, res
Expand Down
16 changes: 16 additions & 0 deletions GLMakie/src/glshaders/particles.jl
Expand Up @@ -176,6 +176,20 @@ function draw_scatter(screen, (marker, position), data)
rot = vec2quaternion(rot)
delete!(data, :rotation)

if to_value(pop!(data, :depthsorting, false))
data[:indices] = map(
data[:projectionview], data[:preprojection], data[:model],
position
) do pv, pp, m, pos
T = pv * pp * m
depth_vals = map(pos) do p
p4d = T * to_ndim(Point4f, to_ndim(Point3f, p, 0f0), 1f0)
p4d[3] / p4d[4]
end
UInt32.(sortperm(depth_vals, rev = true) .- 1)
end |> indexbuffer
end

@gen_defaults! data begin
shape = Cint(0)
position = position => GLBuffer
Expand All @@ -194,6 +208,7 @@ function draw_scatter(screen, (marker, position), data)
return shape
end
end

@gen_defaults! data begin
quad_offset = Vec2f(0) => GLBuffer
intensity = nothing => GLBuffer
Expand Down Expand Up @@ -226,6 +241,7 @@ function draw_scatter(screen, (marker, position), data)
scale_primitive = true
gl_primitive = GL_POINTS
end

# Exception for intensity, to make it possible to handle intensity with a
# different length compared to position. Intensities will be interpolated in that case
data[:intensity] = intensity_convert(intensity, position)
Expand Down
1 change: 1 addition & 0 deletions NEWS.md
Expand Up @@ -2,6 +2,7 @@

## master

- Add `depthsorting` as a hidden attribute for scatter plots in GLMakie as an alternative fix for outline artifacts. [#3432](https://github.com/MakieOrg/Makie.jl/pull/3432)
- Disable SDF based anti-aliasing in scatter, text and lines plots when `fxaa = true` in GLMakie. This allows removing outline artifacts at the cost of quality. [#3408](https://github.com/MakieOrg/Makie.jl/pull/3408)
- DataInspector Fixes: Fixed depth order, positional labels being in transformed space and `:inspector_clear` not getting called when moving from one plot to another. [#3454](https://github.com/MakieOrg/Makie.jl/pull/3454)
- Fixed bug in GLMakie where the update from a (i, j) sized GPU buffer to a (j, i) sized buffer would fail [#3456](https://github.com/MakieOrg/Makie.jl/pull/3456).
Expand Down
10 changes: 9 additions & 1 deletion docs/reference/plots/scatter.md
Expand Up @@ -378,6 +378,7 @@ Currently there are a few ways to mitigate this problem, but they all come at a
- `fxaa = true` will disable the native anti-aliasing of scatter markers and use fxaa instead. This results in less detailed markers, especially for thin markers like characters.
- `transparency = true` will disable depth testing to a degree, resulting in all markers being rendered without artifacts. However with this markers always have some level of transparency
- `overdraw = true` will disable depth testing entirely (read and write) for the plot, removing artifacts. This will however change the z-order of markers and allow plots rendered later to show up on top of the scatter plot
- `depthsorting = true` will sort markers by depth before rendering to fix the issue. This only works within a plot call, so when other plots are involved the issue may reappear.

\begin{examplefigure}{}
```julia
Expand All @@ -386,15 +387,22 @@ GLMakie.activate!() # hide

ps = rand(Point3f, 500)
cs = rand(500)
f = Figure(size = (600, 650))
f = Figure(size = (900, 650))
Label(f[1, 1], "base", tellwidth = false)
scatter(f[2, 1], ps, color = cs, markersize = 20, fxaa = false)
Label(f[1, 2], "fxaa = true", tellwidth = false)
scatter(f[2, 2], ps, color = cs, markersize = 20, fxaa = true)

Label(f[3, 1], "transparency = true", tellwidth = false)
scatter(f[4, 1], ps, color = cs, markersize = 20, transparency = true)
Label(f[3, 2], "overdraw = true", tellwidth = false)
scatter(f[4, 2], ps, color = cs, markersize = 20, overdraw = true)

Label(f[1, 3], "depthsorting = true", tellwidth = false)
scatter(f[2, 3], ps, color = cs, markersize = 20, depthsorting = true)
Label(f[3, 3], "depthsorting = true", tellwidth = false)
scatter(f[4, 3], ps, color = cs, markersize = 20, depthsorting = true)
mesh!(Rect3f(Point3f(0), Vec3f(0.9, 0.9, 0.9)), color = :orange)
f
```
\end{examplefigure}

0 comments on commit 64d68b4

Please sign in to comment.