Display png or jpeg on plane in Isaac Sim 4.5

Isaac Sim Version

4.5.0

Operating System

Ubuntu 22.04

GPU Information

  • Model:
  • Driver Version:

Topic Description

Detailed Description

Essentially, I would like to overlay an image file onto a plane. Generally, I would like to create a material from an image file that I could apply to any object.

Our use case for this is to plot the path of multiple robots and display it on a plane. While a trail is useful in 3D, the 2D image should help with an easy visual. The approach we were taking was to save the plot as a png that will be overwritten during planned intervals, link it to a material in Isaac Sim, and reload the link every frame.

Bonus: if it’s possible to connect a figure earlier and take out the png file middleman, then this could be sped up. How I envision this to work would be directly write to the diffuseTexture using the matplotlib figure. While this isn’t an expected functionality, if this is possible, I would prefer to handle it this way.

Code Snippet

This is our current approach for creating a plane and attaching an image. There’s a bit more to the code we use and I can provide a more complete example if needed, but this is ultimately based on approaches discussed in here ( How can I import a plain PNG image on Isaac Sim? - #4 by fig_kim ). There was a broken link in there.

import isaacsim
from isaacsim import SimulationApp
import omni

simulation_app = SimulationApp({"headless": False})

import omni.usd
from omni.isaac.core.utils.stage import add_reference_to_stage
from pxr import Usd, UsdShade, Sdf, Vt

#NOTE: The World (env) and the Plane are handled by one of our own helper functions

# Create a plane
plane = Plane(name = "Plane", env = env)
plane_prim = env.stage.GetPrimAtPath(plane.prim_path)

# Create a material and assign image
material_path = plane.prim_path + "/Looks/PlaneMaterial"
image_path = "/image/filepath"
material = UsdShade.Material.Define(env.stage, material_path)

# Create a shader
shader = UsdShade.Shader.Define(env.stage, material_path + "/Shader")
shader.CreateIdAttr("UsdPreviewSurface")
shader.CreateInput("roughness", Sdf.ValueTypeNames.Float).Set(0)
shader.CreateInput("metallic", Sdf.ValueTypeNames.Float).Set(0)
shader.CreateInput("ior", Sdf.ValueTypeNames.Float).Set(1.0)
shader.CreateInput("opacity", Sdf.ValueTypeNames.Float).Set(1.0)
color_array = Vt.Vec3fArray([1.0, 1.0, 1.0])
shader.CreateInput("diffuseColor", Sdf.ValueTypeNames.Vector3fArray).Set(color_array)

# Connect the shader to the material's surface output
material.GetSurfaceOutput().ConnectToSource(shader.ConnectableAPI(), "surface")

# Add st reader
st_reader = UsdShade.Shader.Define(env.stage, material_path + "/st_reader")
st_reader.CreateIdAttr("UsdPrimvarReader_float2")
st_reader.CreateInput("varname", Sdf.ValueTypeNames.Token).Set("st")

# Add diffuse texture
diffuseTextureSampler = UsdShade.Shader.Define(env.stage, material_path + "/diffuseTexture")
diffuseTextureSampler.CreateIdAttr("UsdUVTexture")
diffuseTextureSampler.CreateInput("file", Sdf.ValueTypeNames.Asset).Set(image_path)
diffuseTextureSampler.CreateInput("st", Sdf.ValueTypeNames.Float2).ConnectToSource(st_reader.ConnectableAPI(), "result")
diffuseTextureSampler.CreateOutput("rgb", Sdf.ValueTypeNames.Float3)
shader.CreateInput("diffuseColor", Sdf.ValueTypeNames.Color3f).ConnectToSource(diffuseTextureSampler.ConnectableAPI(), "rgb")

# Bind the material the plane
UsdShade.MaterialBindingAPI(plane_prim).Bind(material)

Issue

While there is no direct error message the above, it looks like the image overlaid onto the plane is being sampled from one pixel of the source image rather than using the full image.

I’ve read that this may be due to the lack of a PrimvarReader or UVs not being handled correctly, but the st_reader should be doing the job from my understanding.

Screenshots or Videos

NOTE: When making the post, I had issues with pasting in images. Will append with a comment if they do not show

When using an image that is primarily white.

When using a multi-color image (using Van Gogh’s Starry Night as an example here)

@malam1 i tried to repro what you are seeing because the snippet you posted should work. the only thing i can do to make this happen is if the st_reader result is not connected to the st input of the diffuseTexture node. below are the comparison:

texture used (just a random google street view):

when st_Reader is disconnected:

and when it’s connected:

i do want to clarify that i didn’t run these tests as simulationapp. but you can find my snippet below (with a plane already created in stage) for your benefit:

from pxr import Usd, Sdf, UsdShade, Vt

# Get plane prim
stage = omni.usd.get_context().get_stage()
plane_prim = stage.GetPrimAtPath("/World/Plane")

# Create a material and assign image
material_path = Sdf.Path("/World/Looks/PlaneMaterial")
image_path = "/image/filepath"
material = UsdShade.Material.Define(stage, material_path)

# Create a shader
shader = UsdShade.Shader.Define(stage, material_path.AppendPath("Shader"))
shader.CreateIdAttr("UsdPreviewSurface")
shader.CreateInput("roughness", Sdf.ValueTypeNames.Float).Set(0.0)
shader.CreateInput("metallic", Sdf.ValueTypeNames.Float).Set(0.0)
shader.CreateInput("ior", Sdf.ValueTypeNames.Float).Set(1.0)
shader.CreateInput("opacity", Sdf.ValueTypeNames.Float).Set(1.0)
color_array = Vt.Vec3fArray([1.0, 1.0, 1.0])
shader.CreateInput("diffuseColor", Sdf.ValueTypeNames.Vector3fArray).Set(color_array)

# Connect the shader to the material's surface output
material.CreateSurfaceOutput().ConnectToSource(shader.ConnectableAPI(), "surface")

# Add st reader
st_Reader = UsdShade.Shader.Define(stage, material_path.AppendPath('st_Reader'))
st_Reader.CreateIdAttr('UsdPrimvarReader_float2')
st_Reader.CreateInput("varname", Sdf.ValueTypeNames.Token).Set("st")

# Add diffuse texture
diffuseTextureSampler = UsdShade.Shader.Define(stage,material_path.AppendPath("diffuseTexture"))
diffuseTextureSampler.CreateIdAttr('UsdUVTexture')
diffuseTextureSampler.CreateInput('file', Sdf.ValueTypeNames.Asset).Set(image_path)
diffuseTextureSampler.CreateInput("st", Sdf.ValueTypeNames.Float2).ConnectToSource(st_Reader.ConnectableAPI(), 'result')
diffuseTextureSampler.CreateOutput('rgb', Sdf.ValueTypeNames.Float3)
shader.CreateInput("diffuseColor", Sdf.ValueTypeNames.Color3f).ConnectToSource(diffuseTextureSampler.ConnectableAPI(), 'rgb')

# Bind the material the plane
UsdShade.MaterialBindingAPI(plane_prim).Bind(material)

is there a way that you can check the MDL graph and see if this is the case you are seeing?

@Simplychenable , thanks for the reply! I modified my code to match your snippet, which didn’t change too much for me. I then dove into the material graph to see if the st input of the diffuseTexture was disconnected, but from below it looks like it’s connected from the start.

To replicate what you did, how would I do this without the simulation app? Ideally, we would like to do it with the sim app open.

By the way, my test image was this:

Additional note: I will be attempting to upgrade to 5.0.0 shortly to see if that solves my issue.

to do it via GUI in 4.5, i simply created a plane prim in stage, copied the code snippet and changed the path to the image file on Ln 9 before executing the script.

if we can narrow down whether it’s Simapp that’s causing the issue by testing it with GUI, that’ll hopefully point us in the right direction on what to do next. i also like where your head’s at with trying the newer version out in case it’s a known bug in 4.5.

Worked in the GUI just fine. It possibly is something with the Simapp. Haven’t been able to setup 5.0.0 yet. Will add to the post when I do.

sounds good. hopefully the devs/mods will be able to offer some additional insight as well.

Hi @malam1! Sorry to follow up with you late. Do you still need more help on this topic?

Hello!

We noticed that this topic hasn’t received any recent updates from anyone reporting this issue, so we are closing it for now to help keep the forum organized.

If you are still experiencing this issue or have related questions, please create a GitHub Discussion or Issue in the Isaac Sim repository and include a link to this topic along with updated details. Mentioning or linking to this original topic provides helpful context and makes it easier for others to assist you.

Thank you for being part of the NVIDIA Isaac Sim community.

Best regards,
The NVIDIA Isaac Sim Forum Team