Skip to content

Commit

Permalink
Updated customized_visualization tutorial (#2982)
Browse files Browse the repository at this point in the history
Added a new section applying texture maps to objects.
  • Loading branch information
ClarytyLLC authored Feb 17, 2023
1 parent bbae9e3 commit 8553725
Showing 1 changed file with 67 additions and 0 deletions.
67 changes: 67 additions & 0 deletions docs/tutorial/visualization/customized_visualization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,70 @@ The captured depth sequence:

.. image:: ../../_static/visualization/customized_visualization/depth_small.gif
:width: 400px


Applying texture maps to objects
`````````````````````````````````````````````````
This example function uses the ``rendering`` class to load an object apply texture maps to it. This example can apply any of the albedo, normal, ao, metallic, and roughness textures present in the object directory.

This function takes the object model directory as the input and loads the object from the directory. It then looks for the available textures in the diretory and applies them to the object.

Before you apply a texture, you must ensure that the texture has the expected properties as supported by the `defaultLit` shader:

* albedo: This must be a 3 or 4 channel image, where the RGB components are the albedo. If there is a 4th channel, then it is the alpha channel for transparency. The `defaultLit` does not support transparency. You must use `defaultLitTransparency` instead of `defaultLit` to use transparency, that is similar to `defaultLit` except that it used alpha channel for transparency.
* normal: This must be a 3 channel image, where RGB components represent the normal in tangent space at each pixel.
* roughness: This can be 1, 2, 3, or 4 channel image. However, only the 1st channel (Red) is used and indicates the applicable roughness. The value ranges from 0, smooth and highly glossy, to 1, very rough and diffuse.
* metallic: This can be 1, 2,3 , or 4 channel image. However, only the 1st channel (Red) is used and indicates the applicable metallic finish. The value ranges from 0, non-metallic, to 1, metallic. Note that the values in between are generally not physically realistic.
* ao: This can be 1, 2 ,3, or 4 channel image. However, only the 1st channel (Red) is used and indicates the ambient occlusion. The value ranges from 0, indicating all pixels are fully shadowed and not exposed to indirect lighting, to 1, indicating all pixels are fully lit by the indirect lighting.
* reflectance: This can be 1, 2 ,3, or 4 channel image. However, only the 1st channel (Red) is used and indicates the reflectance or refraction of the image. The value ranges from 0, indicating not reflective, to 1, indicating highly-reflective. Generally, physically accurate materials do not have a value below 0.35.
* anisotropy: This can be 1, 2 ,3, or 4 channel image. However, only the 1st channel (Red) is used and indicates the anistropic reflectance or refraction of the image. This is used to simulate materials with anisotropic reflectance like brushed metal.
* ao_rough_metal: This must be a 3 channel image. If this is set then `roughness`, `metallic`, and `ao` texture maps are ignored. Instead, the the ao_rough_metal is used where the Red channel has the ao map, the Green channel has the roughness map, and the Blue channel has the metallic map.
* anisotropy: This can be 1, 2 ,3, or 4 channel image. However, only the 1st channel (Red) is used to simulate materials with anisotropic reflectance like a brushed metal.

Below is a sample python code that derives a texture path, checks if a texture is available, and then loads the texture.

.. code-block:: python
import open3d as o3d
import open3d.visualization.gui as gui
import open3d.visualization.rendering as rendering
import sys, os
def main():
if len(sys.argv) < 2:
print ("Usage: texture-model.py [model directory]\n\t This example will load [model directory].obj and any of albedo, normal, ao, metallic and roughness textures present.")
exit()
# Derive the object path set the model, material, and shader
model_dir = sys.argv[1]
model_name = os.path.join(model_dir, os.path.basename(model_dir) + ".obj")
model = o3d.io.read_triangle_mesh(model_name)
material = o3d.visualization.rendering.Material()
material.shader = "defaultLit"
# Derive the texture paths
albedo_name = os.path.join(model_dir, "albedo.png")
normal_name = os.path.join(model_dir, "normal.png")
ao_name = os.path.join(model_dir, "ao.png")
metallic_name = os.path.join(model_dir, "metallic.png")
roughness_name = os.path.join(model_dir, "roughness.png")
# Check if the textures are available and loads the texture. For example, if metallic exists then load metallic texture
if os.path.exists(albedo_name):
material.albedo_img = o3d.io.read_image(albedo_name)
if os.path.exists(normal_name):
material.normal_img = o3d.io.read_image(normal_name)
if os.path.exists(ao_name):
material.ao_img = o3d.io.read_image(ao_name)
if os.path.exists(metallic_name):
material.base_metallic = 1.0
material.metallic_img = o3d.io.read_image(metallic_name)
if os.path.exists(roughness_name):
material.roughness_img = o3d.io.read_image(roughness_name)
# Draw an object named cube using the available model and texture
o3d.visualization.draw([{"name": "cube", "geometry": model, "material": material}])
if __name__ == "__main__":
main()

0 comments on commit 8553725

Please sign in to comment.