tylermorganwall / rayrender

A pathtracer for R. Build and render complex scenes and 3D data visualizations directly from R
http://www.rayrender.net
622 stars 42 forks source link

How to load obj file texture? #15

Closed trevorld closed 4 years ago

trevorld commented 4 years ago

Hi,

The documentation for obj_model suggests it can read obj model textures. Is there some trick to do so? I've tried three different ways to do so without success:

library("grid")
library("png")
library("rayrender")

# minimal quad example
png("texture.png", width=2, height=1, units="in", res=72)
grid.rect(x = c(0.25, 0.75), width=0.5, gp = gpar(fill = c("blue", "red")))
grid.text(c("F", "B"), x = c(0.25, 0.75), gp = gpar(col = "white", fontsize = 48))
dev.off()

"mtllib rect.mtl
v -1 1 0.125
v -1 -1 0.125
v 1 -1 0.125
v 1 1 0.125
vt 0 1
vt 0 0
vt 0.5 0
vt 0.5 1
f 1/1 2/2 3/3 4/4
" %>% writeLines("rect.obj")

writeLines("map_Kd texture.png", "rect.mtl")

ia <- png::readPNG("texture.png")

Attempts 1 and 2 get a black render:

png("attempt1.png")
obj_model("rect.obj", texture = TRUE) %>% render_scene()
dev.off()

png("attempt2.png")
obj_model("rect.obj", texture = TRUE, material = diffuse(image_array = ia)) %>% render_scene()
dev.off()

attempt1

Attempt 3 gets an incorrect color render:

png("attempt3.png")
obj_model("rect.obj", texture = FALSE, material = diffuse(image_array = ia)) %>% render_scene()
dev.off()

attempt3

For reference this is how meshlab renders rect.obj:

snapshot00

I've also tried various ways of writing rect.obj (i.e. explicitly including vector normals etc.) but get the same results either way.

Thanks for the awesome package!

trevorld commented 4 years ago

Nevermind. I was able to modify my minimal OBJ example so that approach 1 (and 2) now works. It seems tinyobjloader needs a "usemtl" statement in the OBJ file and "newmtl" statement in the associated MTL file in order to correctly import a texture.

"mtllib rect.mtl
v -1 1 0.125
v -1 -1 0.125
v 1 -1 0.125
v 1 1 0.125
vt 0 1
vt 0 0
vt 0.5 0
vt 0.5 1
usemtl material_0
f 1/1 2/2 3/3 4/4
" %>% writeLines("rect.obj")

"newmtl material_0
map_Kd texture.png
" %>% writeLines("rect.mtl")