In plotting discrete 3D arrays using Makie, how can one modify the lighting and smoothness properties?

Here is an example of a thick, extruded cross geometry constructed as a binary 3D array. (Figure on left) The lighting on the horizontal slab, the vertical slab, and along the slab thickness is very different. How can this be made more consistent?

(Figure on right) There is also some surface roughness, although this is only obvious when zooming in and less of an issue.

I am plotting these binary 3D arrays with the volume call and isovalue = 1.0 property.

I notice that when plotting analytical 3D data, the lighting and surface roughness issues are gone. Below is an example of a Schwarz â€śGâ€ť surface, also plotted with the volume and isovalue calls, similar to the Makie gallery example here.

To make the lighting smoother, you may want to change the light position (by the keyword light = Vec3f0(1, 2, 3)) or disable shading entirely (shading = false).

If you want smooth normals you may want to use MarchingTetrahedra() rather than MarchingCubes(). I havenâ€™t tested Meshing on Boolean arrays, so I am not sure what the expected behavior should be, but it should still work.

using Meshing
using GeometryTypes
gyroid(v) = cos(v[1])*sin(v[2])+cos(v[2])*sin(v[3])+cos(v[3])*sin(v[1])
gyroid_shell(v) = max(gyroid(v)-0.4,-gyroid(v)-0.4)
xr,yr,zr = ntuple(_->LinRange(0,pi*4,50),3)
A = [gyroid_shell((x,y,z)) for x in xr, y in yr, z in zr]
A[1,:,:] .= 1e10
A[:,1,:] .= 1e10
A[:,:,1] .= 1e10
A[end,:,:] .= 1e10
A[:,end,:] .= 1e10
A[:,:,end] .= 1e10
gy_mesh = GLNormalMesh(A, MarchingCubes())
# view with Makie
import Makie
using LinearAlgebra
Makie.mesh(gy_mesh, color=[norm(v) for v in gy_mesh.vertices])

Last time I tried this kind of thing I found that interpolating the underlying isosurface to generate the normals using Interpolations.gradient worked better than relying on the normals generated by GLNormalMesh (which are based on the intermediate mesh).