Conversation
Stop stripping mesh.texture when UVs are missing — the texture is kept so that renderers with projected-UV support (triplanar sampling) can use it. The warning is updated to reflect this. When a texture is present, set mesh.color to white (1,1,1) so the texture renders at full brightness. The previous behavior used diffuse_color_constant as a multiplier, which is the untextured fallback in OmniPBR and incorrectly darkened textured surfaces.
When a mesh has a texture but no UV coordinates, sample the texture using triplanar projection — the equivalent of OmniPBR's project_uvw. The new sample_texture_triplanar() function computes the face normal from triangle vertices, transforms the hit point to local object space, samples the texture from 3 axis-aligned planes (YZ, XZ, XY), and blends using abs(face_normal) as weights. This produces seamless results on arbitrarily oriented surfaces without requiring baked UVs. Also reorder the mesh_data_index guard in sample_texture() so that meshes with no mesh data at all (mesh_data_index == -1) fall through to triplanar instead of returning white.
|
📝 WalkthroughWalkthroughThe changes introduce triplanar texture sampling for meshes lacking UV coordinates and update the material import logic to reflect this capability. The texturing system now computes texture coordinates from object-space position and surface normals when UV data is unavailable. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
newton/_src/sensors/warp_raytrace/textures.py (1)
113-126:⚠️ Potential issue | 🔴 CriticalOut-of-bounds array access in
@wp.funckernel—requires guard restructuring.The condition on line 119 is unsafe:
if mesh_data_index < 0 or mesh_data[mesh_data_index].uvs.shape[0] == 0:NVIDIA Warp does not support short-circuit evaluation for boolean operators in
@wp.funckernels (per official documentation and GitHub issue#1329). This means both conditions in theorexpression are always evaluated, even whenmesh_data_index < 0. Accessingmesh_data[mesh_data_index]with a negative index causes out-of-bounds access.Restructure the guard to check
mesh_data_index >= 0independently:if mesh_data_index >= 0 and mesh_data[mesh_data_index].uvs.shape[0] > 0: # Use UV-based sampling else: # Use triplanar (covers both negative index and zero-length UVs cases)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@newton/_src/sensors/warp_raytrace/textures.py` around lines 113 - 126, The current guard in the `@wp.func` kernel uses "if mesh_data_index < 0 or mesh_data[mesh_data_index].uvs.shape[0] == 0" which can still index mesh_data when mesh_data_index is negative (Warp does not short-circuit booleans); change the logic to first test mesh_data_index >= 0 and only then inspect mesh_data[mesh_data_index].uvs.shape to decide which sampler to call — e.g., if mesh_data_index >= 0 and mesh_data[mesh_data_index].uvs.shape[0] > 0 then call sample_texture_mesh(bary_u, bary_v, face_id, mesh_id, mesh_data[mesh_data_index], texture_data[texture_index]) else call sample_texture_triplanar(hit_point, shape_transform, mesh_id, face_id, texture_data[texture_index]) — so mesh_data is never indexed when mesh_data_index is negative.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@newton/_src/sensors/warp_raytrace/textures.py`:
- Around line 113-126: The current guard in the `@wp.func` kernel uses "if
mesh_data_index < 0 or mesh_data[mesh_data_index].uvs.shape[0] == 0" which can
still index mesh_data when mesh_data_index is negative (Warp does not
short-circuit booleans); change the logic to first test mesh_data_index >= 0 and
only then inspect mesh_data[mesh_data_index].uvs.shape to decide which sampler
to call — e.g., if mesh_data_index >= 0 and
mesh_data[mesh_data_index].uvs.shape[0] > 0 then call
sample_texture_mesh(bary_u, bary_v, face_id, mesh_id,
mesh_data[mesh_data_index], texture_data[texture_index]) else call
sample_texture_triplanar(hit_point, shape_transform, mesh_id, face_id,
texture_data[texture_index]) — so mesh_data is never indexed when
mesh_data_index is negative.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: 2c6d023e-85ce-4e06-b9b9-eff6777ee85b
📒 Files selected for processing (2)
newton/_src/sensors/warp_raytrace/textures.pynewton/_src/utils/import_usd.py
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Description
Add triplanar texture projection for meshes without UV coordinates, equivalent to OmniPBR's
project_uvwmode. This enables texture rendering on meshes that rely on runtime UV projection rather than bakedUV maps.
When a mesh has a texture but no UVs,
sample_texture()now callssample_texture_triplanar()which computes the face normal from triangle vertices, samples the texture from 3 axis-aligned planes (YZ, XZ,XY), and blends using
abs(face_normal)as weights. This produces seamless results on arbitrarily oriented surfaces.Also includes a prerequisite change to preserve
mesh.textureduring USD import when UVs are missing (previously the texture was stripped), and setsmesh.colorto white for textured meshes so the texturerenders at full brightness.
Checklist
CHANGELOG.mdhas been updated (if user-facing change)Test plan
Verified end-to-end with a dextrah Kuka-Allegro manipulation scene (64 envs, Newton Warp renderer) containing heterogeneous grasp objects — a mix of meshes with baked UVs and meshes without UVs that rely on
project_uvw=True:sample_texture_meshpath (no change)New feature / API change