dmurdoch / rgl

rgl is a 3D visualization system based on OpenGL. It provides a medium to high level interface for use in R, currently modelled on classic R graphics, with extensions to allow for interaction.
https://dmurdoch.github.io/rgl/
GNU General Public License v2.0
85 stars 20 forks source link

Apply texture to a Shade3d object such as Cube3d #298

Closed duckt14 closed 1 year ago

duckt14 commented 1 year ago

Hi, I'm trying to apply a texture image to a Cube3d, but in the renderer window the cube hasn't texture and it appears black on all faces. I'm using these two different ways:

texture <- here("3D/texture/txt.png") shade3d(cube3d(), texture = texture) or shade3d(cube3d(texture = texture))

But it doesn't work. With the Sphere3d it works well. Is there any solution? Very thanks, Enrico

dmurdoch commented 1 year ago

On 25/01/2023 10:06 a.m., duckt14 wrote:

Hi, I'm trying to apply a texture image to a Cube3d, but in the renderer window the cube hasn't texture and it appears black on all faces. I'm using these two different ways:

|texture <- here("3D/texture/txt.png")| |shade3d(cube3d(), texture = texture)| or |shade3d(cube3d(texture = texture))|

But it doesn't work. With the Sphere3d it works well. Is there any solution?

You need to set col = "white" as well. By default the color of the cube is black, and textures modify it multiplicatively.

It might make sense to change this, but it's been like that for a very long time, so it would cause some disruption.

Duncan Murdoch

duckt14 commented 1 year ago

Okay, I've tested using this line shade3d(cube3d(texture = texture, col = "white")) and I attach you the results. With sphere works correctly and with the cube I've obtained only a colored mesh. Perhaps, I need to add some settings; I've tried follow the reference about material but I'm not able to showing the texture on cube. :-/

This is the texture:

legno-2

These are the results:

Cube3D Cube_Sphere

dmurdoch commented 1 year ago

It looks as though you have specified texture coordinates on the sphere but not on the cube. You can see what the space coordinates of the cube are by running cube3d()$vb. Those are homogeneous coordinates, one vertex per column. You need to choose where each vertex should show up in the texture. Here's one example:

cube <- cube3d(texcoords = cbind(vb[1,] + vb[2,] + vb[3,],
                                 vb[1,] - vb[2,] + 2*vb[3,]), 
               col = "white",
               texture = system.file("textures/rgl2.png", package="rgl"))
shade3d(cube)

This gives this image:

Screen Shot 2023-01-25 at 2 51 41 PM

One problem you'll have if you try to put a texture on a cube is that texture coordinates map to vertices, which means you get the same texture coordinate at the vertex on all three faces that meet there; it's not like drawing a PNG file on each face. To do that, you would need to plot 6 quads (with a total of 24 vertices and 24 texture coordinate pairs). This does that:

id <- shade3d(cube, meshColor = "faces")
vertices <- rgl.attrib(id, "vertices")
open3d()
quads3d(vertices, col = "white", 
        texcoords = cbind(rep(c(0, 0, 1, 1), 6), 
                          rep(c(0, 1, 1, 0), 6)), 
        texture = system.file("textures/rgl2.png", package="rgl"))

Screen Shot 2023-01-25 at 3 02 46 PM

duckt14 commented 1 year ago

It works!! Really many thanks Duncan for the help and for your work. 🙏❣️

duckt14 commented 1 year ago

@dmurdoch is there a solution to apply different texture on each cube faces?

dmurdoch commented 1 year ago

On 26/01/2023 5:00 a.m., duckt14 wrote:

@dmurdoch https://github.com/dmurdoch is there a solution to apply different texture on each cube faces?

You can only have one texture per object, so there are two possible solutions:

Duncan Murdoch