3D scenes in GLMakie Glitch out and Slow down after few seconds

I was recently playing around with GLMakie Scenes using the cam3d! camera which works pretty much like plotly() backend on Plots.
I was impressed by the zoom in-out controls. However, after a few seconds of scrolling and panning, the controls slowed down to a crawl until it all came to a hault. Further, scrolling seemed to have caused some weird objects to appear.

using GLMakie

molecule = cumsum(randn(Point3f, 500))

s = Scene(; camera = cam3d!)

meshscatter!(s, molecule, markersize = rand(0.6:0.1:1.5, 500), color = rand(500))


here’s the code snippet

A few more questions that I have about GLMakie… How on earth do I create:

  1. A Unit Circle? The most computationally light way to do it. Is it scatter(, marker=Circle)? Is there any other, better way to define the circle parameters which then I can add to the scene/plot as a normal object?
  2. A Unit Sphere? Basically, the same question. I belive meshscatter! by default creates a sphere but I don’t know about the dimensions. Playing around with it, it seems like it’s not a unit sphere. How do I create a Custom mesh and plot/add it to scene as an object?

Also, how do coordinates in the camera=cam2d and cam3d work? campixel makes sense, but I seem to not understand what is the scaling in cam2d.

Circle and Sphere

using GLMakie

fig= Figure()
ax = LScene(fig[1,1])
lines!(Circle(Point2f(0,0),1); linewidth=5, transparency=true) # origin, radius
mesh!(Sphere(Point3f(0,0,0.5), 0.75); color = :red) # origin, radius

Used it in a scene with cam3D!.. Seems to have a lower resolution sphere as compared to meshscatter!

Although not what I wanted to do, this explains why its a low res and not a perfect sphere… that’s what is used as the mesh skeleton. Any way to change this?

And is cam3d even reliable for prolonged simulations?

Or any way to tweak the radius parameter of meshscatter? (markersize is not in completely perfect correspondence to radius)

And is cam3d even reliable for prolonged simulations?

Yeah it should be, this must be some bug.
I can’t reproduce it, do you have any more pointer on how to reproduce the problem?

(markersize is not in completely perfect correspondence to radius)

It doesn’t? In what way?

Seems to have a lower resolution sphere as compared to meshscatter!

You can use Tesselation for higher res spheres:

using GLMakie, GeometryBasics

molecule = cumsum(randn(Point3f, 500))

s = Scene(; camera = cam3d!)
# Use Tesselation for for a smoother sphere:
sphere = normal_mesh(Tesselation(Sphere(Point3f(0), 1), 100))
meshscatter!(s, molecule, marker=sphere, markersize=rand(0.6:0.1:1.5, 500), color=rand(500))


Ah do you mean scrolling into one direction continuously?

This is not a bug, just not perfect behavior.
The camera has a lookat position and eye position, and when zooming you move the camera closer to lookat. The closer you get the slower it will move, since it moves by a fraction of the distance between those.
This will make the distance between lookat and eyeposition super small:
Which I think will at some point mess up the projection, creating those artifacts.

using GLMakie, GeometryBasics

scene = Scene(camera=cam3d!)
points = Vector{Point2f}()
for i in 0:100
    for j in 0:100
        push!(points, 10*Point2f(-i, j))
dots = meshscatter!(scene, points, markersize = 10, color=:red)

Zoom out of the sphere to get a sense of what the entire grid of spheres is like.
Try zooming in to the centre of the grid. Tried it countless times, every time it just comes to a crawl! And then the entire thing explodes into some weird behaviour.

In terms of the number of vertices.

Thank you! I didn’t know that… I found a more native way to do this too btw…

using GeometryBasics, LinearAlgebra, GLMakie

# Create vertices for a Sphere
r = 0.5f0
n = 30
θ = LinRange(0, pi, n)
φ2 = LinRange(0, 2pi, 2 * n)
x2 = [r * cos(φv) * sin(θv) for θv in θ, φv in φ2]
y2 = [r * sin(φv) * sin(θv) for θv in θ, φv in φ2]
z2 = [r * cos(θv) for θv in θ, φv in 2φ2]
points = vec([Point3f((xv, yv, zv)) for (xv, yv, zv) in zip(x2, y2, z2)])

# The coordinates form a matrix, so to connect neighboring vertices with a face
# we can just use the faces of a rectangle with the same dimension as the matrix:
faces = decompose(QuadFace{GLIndex}, Tesselation(Rect(0, 0, 1, 1), size(z2)))
# Normals of a centered sphere are easy, they're just the vertices normalized.
normals = normalize.(points)
gb_mesh = GeometryBasics.Mesh(meta(points; normals), faces)

scene = Scene(camera=cam3d!)
mesh!(scene, gb_mesh, color=rand(100,100), colormap=:blues)

source: mesh · Makie

btw… do you know any way to have the radius of the meshscatter!() known? I want to make very precise spheres. Say of a unit radius. But keeping 2 meshscatter! spheres at a unit distance don’t Perfectly coincide.

It used to be the same for marker=circle. marker=Circle was precisely a unit circle.

Unfortunately, meshscatter!(marker=Sphere) isn’t a thing tho xD.

Ahhhh I see! So just avoid making stuff so small and/or zooming to close to objects. (Tbh felt like this is close to what Desmos does - an infinite zoom hehe… but its all right. This is good enough!)