# Visualizing a 3D volume in Makie: Lighting, smoothness

**URL:** <https://discourse.julialang.org/t/visualizing-a-3d-volume-in-makie-lighting-smoothness/35263>\
**Category:** Visualization\
**Tags:** question, plotting, makie\
**Created:** [February 27, 2020, 11:10pm UTC](https://discourse.julialang.org/t/visualizing-a-3d-volume-in-makie-lighting-smoothness/35263 "2020-02-27T23:10:38Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![dalarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dalarev/32/9881_2.png) [@dalarev](https://discourse.julialang.org/u/dalarev)\
**Post date:** [February 27, 2020, 11:10pm UTC](https://discourse.julialang.org/t/visualizing-a-3d-volume-in-makie-lighting-smoothness/35263/1 "2020-02-27T23:10:38Z")

</div>

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.

 ![Picture1](https://global.discourse-cdn.com/julialang/original/3X/2/e/2ecf6ea699091d7ae414811beb60aa267fa0bc37.png)  
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](http://juliaplots.org/MakieReferenceImages/gallery//test_1/index.html).

 ![Capture2](https://global.discourse-cdn.com/julialang/original/3X/8/5/85549d8b14930ce7f89b8360e9fa9ef08c03162e.png)

I am open to using Plots or other packages, but I’ve not found a better solution than Makie.

Thanks!

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [February 28, 2020, 4:07pm UTC](https://discourse.julialang.org/t/visualizing-a-3d-volume-in-makie-lighting-smoothness/35263/2 "2020-02-28T16:07:01Z")

</div>

The roughness is almost unavoidable - or you can just trade it in with other artifacts.  
You can also try to visualize it as a mesh, which should have sharp edges:  
[https://juliageometry.github.io/Meshing.jl/stable/api/#GeometryTypes-1](https://juliageometry.github.io/Meshing.jl/stable/api/#GeometryTypes-1)

---

<div class="post-metadata">

**Author:** ![asinghvi17](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/asinghvi17/32/8272_2.png) [@asinghvi17](https://discourse.julialang.org/u/asinghvi17)\
**Post date:** [February 28, 2020, 4:25pm UTC](https://discourse.julialang.org/t/visualizing-a-3d-volume-in-makie-lighting-smoothness/35263/3 "2020-02-28T16:25:39Z")

</div>

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`).

---

<div class="post-metadata">

**Author:** ![dalarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dalarev/32/9881_2.png) [@dalarev](https://discourse.julialang.org/u/dalarev)\
**Post date:** [February 28, 2020, 5:44pm UTC](https://discourse.julialang.org/t/visualizing-a-3d-volume-in-makie-lighting-smoothness/35263/4 "2020-02-28T17:44:55Z")

</div>

`shading` changes nothing in my volume plot, perhaps because it is not a mesh.

Is the `light` keyword part of the `volume` call or something else? I input several different values for the light vector and it produces no change.

---

<div class="post-metadata">

**Author:** ![sjkelly](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sjkelly/32/9280_2.png) [@sjkelly](https://discourse.julialang.org/u/sjkelly)\
**Post date:** [February 28, 2020, 6:39pm UTC](https://discourse.julialang.org/t/visualizing-a-3d-volume-in-makie-lighting-smoothness/35263/5 "2020-02-28T18:39:34Z")

</div>

I’ve added an example in the latest docs for direct function meshing. [Examples · Meshing](https://juliageometry.github.io/Meshing.jl/dev/examples/#Functions-1)

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.

---

<div class="post-metadata">

**Author:** ![dalarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dalarev/32/9881_2.png) [@dalarev](https://discourse.julialang.org/u/dalarev)\
**Post date:** [February 28, 2020, 7:49pm UTC](https://discourse.julialang.org/t/visualizing-a-3d-volume-in-makie-lighting-smoothness/35263/6 "2020-02-28T19:49:43Z")

</div>

The issue with visualizing a mesh is missing ends or “isocaps”.

This results from meshing a binary array (0’s and 1’s) and using `iso = 0.5` in the `MarchingTetrahedra` call.

![image](https://global.discourse-cdn.com/julialang/original/3X/0/7/070ea65f0ad4fb35252156f89221c501723ae510.png)

---

<div class="post-metadata">

**Author:** ![sjkelly](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sjkelly/32/9280_2.png) [@sjkelly](https://discourse.julialang.org/u/sjkelly)\
**Post date:** [March 8, 2020, 12:01am UTC](https://discourse.julialang.org/t/visualizing-a-3d-volume-in-makie-lighting-smoothness/35263/7 "2020-03-08T00:01:40Z")

</div>

Here is a hackish example which gives Isocaps:

```julia
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])

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/1/1/115d5d42a0f5bd7231715fb431713e6b76813f1a.png)

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [March 8, 2020, 3:38am UTC](https://discourse.julialang.org/t/visualizing-a-3d-volume-in-makie-lighting-smoothness/35263/8 "2020-03-08T03:38:43Z")

</div>

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).

For code, see the example I posted here:

> [@ANN: Meshing 0.5.0](https://discourse.julialang.org/t/ann-meshing-0-5-0/29034/2):
>
> I thought I’d post here to say that I’ve just used this for some testing and I really appreciated how easy it was to use with Makie and how fast it was at generating isosurfaces. Here’s a pretty picture: (script at this gist [Makie.jl based visualization of 3D 1/f noise · GitHub](https://gist.github.com/c42f/454c1cbaed66354b77912a1cf41a0d96))

(code available at [Makie.jl based visualization of 3D 1/f noise · GitHub](https://gist.github.com/c42f/454c1cbaed66354b77912a1cf41a0d96))
