# Material Override

> Tune PBR metallic / roughness on URDF visual meshes without re-exporting DAE — author an inline `<material_override>` element inside any `<visual>`, and let the engine's URDF→USD pipeline patch the converter's defaults post-conversion. Useful for sim-to-real visual fidelity (DAE materials round-trip poorly; Isaac Sim's importer lands every embedded material at roughness=0.5, metallic=0.0 by default). Trigger: When the user asks to "tune material", "change roughness / metallic", "make the gripper shinier", "fix dull PBR", "override material", "PBR override", or any time the simulator looks washed out after a URDF→USD import.

- Skill: `agibottech/material-override` (Agent Skill)
- Install (CLI): `npx skillmds@latest add agibottech/material-override`
- Raw SKILL.md: https://api.skillmd.com/api/skills/agibottech/material-override/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- License: MPL-2.0
- Author: agibottech (https://skillmd.com/u/agibottech)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/agibottech/material-override

---


## When to Use

- Robot or asset visual meshes import with washed-out / flat
  shading after the URDF→USD converter runs.
- User wants to A/B PBR values without re-exporting DAE meshes from
  Blender / Maya.
- Polishing a robot for sim-to-real visual transfer.
- Author of a new URDF (see `add-robot` skill) wants the meshes to
  look right without round-tripping DAE materials.

Do **not** use for:
- Replacing albedo / textures → must be done in the DAE export.
- Per-prim material at runtime → that's a runtime USD edit, not the
  `<material_override>` element.
- Adding a brand-new material — only patches metallic / roughness on
  the embedded one.

## Critical Patterns

1. **Author inside `<visual>`, not on the link.** The override
   auto-scopes to exactly the mesh it sits under. A link with N
   `<visual>` elements just gets N independent overrides.
2. **`urdfdom` / RSP / MoveIt / Isaac's converter all ignore it.**
   `assemble_robot.py` strips the element from the URDF it feeds the
   converter, then re-applies the values to the converted USD via
   `_parse_material_override_blocks` / `_apply_material_overrides`.
3. **Only `roughness` and `metallic` are exposed.** Other UsdPreviewSurface
   inputs (specular, opacity, IOR) are not on the contract.
4. **Range 0..1.** Outside that range the importer warns and clamps.
5. **No attributes needed.** Scoping is positional. Don't try to
   target a sibling visual by name — author one override per visual.

## Schema

```xml
<visual>
  <origin xyz="0 0 0" rpy="0 0 0"/>
  <geometry>
    <mesh filename="package://.../base_link.dae"/>
  </geometry>
  <material_override>
    <roughness>0.45</roughness>
    <metallic>0.85</metallic>
  </material_override>
</visual>
```

Either child is optional — author only what you need. Default for
an absent child is "leave as the converter wrote it" (typically
0.5 / 0.0 for DAE imports).

## PBR cheat-sheet

| Look | `roughness` | `metallic` | Notes |
|---|---|---|---|
| Brushed steel | 0.40 | 0.95 | Most arm shells |
| Anodised aluminium | 0.55 | 0.30 | UR-style structural |
| Polished chrome | 0.05 | 1.00 | Decorative trims, mirror parts |
| Matte plastic | 0.70 | 0.00 | Cable guards, end-stops |
| Rubber pads | 0.85 | 0.00 | Soft contact surfaces |
| Anodised gold (gripper bushings) | 0.30 | 0.90 | Highlights |

These are starting points; A/B against a photograph of the real
robot if you have one.

## Workflow

### Step 1 — Find the visual you want to tune

```bash
# Locate the URDF / xacro under genie_sim_robot_model
grep -nR "<visual>" source/geniesim_ros/src/ros_ws/src/genie_sim_robot_model/robots/ | head
```

### Step 2 — Add the override

Open the xacro, drop `<material_override>` into the `<visual>`
block. Existing reference: aloha arm xacro carries an override on
every visual:

```xml
<visual>
  <origin xyz="0 0 0" rpy="0 0 0" />
  <geometry>
    <mesh filename="${mesh_dir}/base_link.dae" />
  </geometry>
  <material_override><roughness>0.45</roughness><metallic>0.85</metallic></material_override>
</visual>
```

### Step 3 — Rebuild the workspace

```bash
geniesim ros build dev && source devel/setup.bash
```

### Step 4 — Force a USD regenerate

The robot USD is cache-gated by `manifest.json`. Bust the cache:

```bash
rm -rf assets/scenes/<scene>/
# OR pass at launch:
ros2 launch genie_sim_bringup app.launch.py … always_regenerate_robot_usd:=true
```

### Step 5 — Launch and inspect

```bash
ros2 launch genie_sim_bringup app.launch.py \
  scene:=<scene> \
  launcher_config:=launcher_ovrtx_isaac_physx \
  headless:=false   # local workstation with a screen; flip to true on a remote/headless host
```

In the OVRtx viewport, compare against the unmodified baseline.
Iterate values, rebuild, re-launch.

### Step 6 — Verify the converted USD

```bash
grep -n "roughness\|metallic" assets/scenes/<scene>/robot/robot.usda | head
```

You should see the patched values on the relevant material prims.

## Notes

- `assemble_robot.py` walks each `<visual>` in author order; if a
  visual has multiple meshes (rare in our robots), the override
  applies to every embedded material of that visual.
- The override is stripped from the URDF *before* it reaches the
  converter, so MoveIt / RSP / urdfdom never see it. They'll happily
  consume the same xacro.
- For brand-new materials (no DAE-embedded source), prefer authoring
  a real `<material>` block — material_override is patch-only.
- Material is rendered by OVRtx + Isaac Sim. The Newton GL viewer
  uses simple shading and won't reflect roughness / metallic — use
  OVRtx for visual QA.

## Resources

- **Engine source**: [source/geniesim_ros/src/ros_ws/src/genie_sim_engine/scripts/assemble_robot.py](../../src/ros_ws/src/genie_sim_engine/scripts/assemble_robot.py) → `_parse_material_override_blocks` / `_apply_material_overrides`
- **Reference usage**: [source/geniesim_ros/src/ros_ws/src/genie_sim_robot_model/robots/agilex/aloha/aloha.urdf.xacro](../../src/ros_ws/src/genie_sim_robot_model/robots/agilex/aloha/aloha.urdf.xacro)
- **Engine AGENTS.md** → "<material_override>": [source/geniesim_ros/src/ros_ws/src/genie_sim_engine/AGENTS.md](../../src/ros_ws/src/genie_sim_engine/AGENTS.md)
- **Related skills**: `add-robot`, `launch-scene`

