I am drawing a 3D surface mesh of human face. Data can be found at https://github.com/Patricklv/Smoothing-3D-surface, where vb.xlsx contains vertices and it.xlsx contains faces.
My R code is as follows:
library(xlsx)
library(rgl)
vb <- read.xlsx("C:\\Users\\<Username>\\Desktop\\vb.xlsx", sheetIndex = 1, header = F)
it <- read.xlsx("C:\\Users\\<Username>\\Desktop\\it.xlsx", sheetIndex = 1, header = F)
vb_mat <- t(as.matrix(vb))
vb_mat <- rbind(vb_mat, 1)
rownames(vb_mat) <- c("xpts", "ypts", "zpts", "")
it_mat <- t(as.matrix(it))
rownames(it_mat) <- NULL
vertices <- c(vb_mat)
indices <- c(it_mat)
try <- tmesh3d(vertices = vertices, indices = indices, homogeneous = TRUE, material = NULL, normals = NULL, texcoords = NULL)
shade3d(try, ambient = "darkgrey", specular = "white")
The resultant 3D surface is as follows: A lot of triangles could be easily seen on the 3D surface mesh. I want to make this surace mesh looks smoother, just like the one shown below:
What should I do in R to smooth the surface mesh so that the mesh looks like the second one, where visible triangular faces are smoothed out? Perhaps Phong model for shading would work through contour3d function in misc3d package. Can anyone show how this function could be applied to my data?
I noted that the plotly package in R has some pretty handy ways to create surface mesh:
library(plotly)
face <- plot_ly(
x = vb[,1], y = vb[,2], z = vb[,3],
type = "mesh3d"
)
face
The resultant facial surface mesh is as below:
The surface mesh is very smooth! But I cannot control the orientation of the plotly.js object when saving it. Neither could I save it as PDF file without additional purchasing. I wish to know how plotly did the magic to create this smooth surface mesh, even when I did not provide face information (it information not provided, only vb provided)? If the magic done by plotly can be done in some other manner in R so that I can customize the orientation when saving pictures and can save it as PDF file without purchasing, while still maintaing such high level of smoothness?
You can use the
rgl::addNormals()
function to make the surface look smoother. Just doand then display
try2
usingshade3d
.What this does is to average the normals to each triangular face that meets at a vertex; then the shading is done smoothly across the face, and you'll get something like one of your other plots. See
example(addNormals)
for a demo.BTW,
rgl
uses Gouraud shading in R, but Phong shading when you userglwidget()
to display the same surface in a browser. They're similar, but Phong looks a bit better.Here's what I get from the example with Gouraud shading:
Here's the same thing with Phong shading from a browser:
Finally, here's what I get for your surface. I changed the display to
and got