Skip to content

Texture and mtl support#20

Merged
pmudry merged 15 commits intomainfrom
Texture-and-MTL-support
Mar 17, 2026
Merged

Texture and mtl support#20
pmudry merged 15 commits intomainfrom
Texture-and-MTL-support

Conversation

@pmudry
Copy link
Copy Markdown
Owner

@pmudry pmudry commented Mar 17, 2026

This branch adds :

  • MTL file support (they come with the OBJ when exported from Blender). This enable multiple material per OBJ and basic color support (which is translated into albedo at the moment)
  • Image texture mapping using UV values from OBJ (which seem to be correct in most cases)
  • Sample scenes to see support

This is not the final implementation but gives the basic integration of texture support in the renderer (only GPU at the moment, using CUDA and OptiX). CPU support is not implemented.

pmudry added 8 commits March 15, 2026 21:03
- MTL loader (mtl_loader.hpp): parse Kd/Ke/Ns/Ni/d/map_Kd, heuristic material
  type assignment (LAMBERTIAN/ROUGH_MIRROR/GLASS/LIGHT/MIRROR)
- Texture loader (texture_loader.cc): stb_image-based RGBA loader, dedup by path
- OBJ loader rewrite: parse mtllib/usemtl, UV indices; calls appropriate
  addTriangle variant (normals+UVs / UVs only / normals / plain)
- scene_description.hpp: TextureDesc struct, textures vector, addTexture(),
  addTriangleWithUVs(), addTriangleWithNormalsAndUVs(), UV fields on triangle
- yaml_scene_loader: material: now optional for OBJ entries (fallback -1);
  texture: key in material definitions
- CUDA backend: UV interpolation in hit_triangle(), tex2D sampling in
  apply_material(), cudaTextureObject upload/cleanup in scene_builder_cuda.cu
- OptiX backend: UV via intersection attributes (numAttributeValues 5),
  texture sampling in __closesthit__ch, d_textures in launch params + cleanup
- CMakeLists: fix OptiX source ordering race (target_sources after find_path);
  add texture_loader.cc to SOURCE_RAYON
- Assets: scripts/generate_grid_texture.py, scripts/generate_uv_models.py,
  resources/textures/grid_512.png, resources/models/{plane,cube,sphere}_uv.obj,
  resources/models/texture_test.mtl, resources/scenes/texture_test.yaml
The YAML parser only recognizes 'camera:' and 'settings:' as top-level section
headers. texture_test.yaml nested its settings under 'scene:' (unrecognized),
so the 'use_bvh: true' key was stored as 'camera.use_bvh', never matching
'settings.use_bvh'. BVH was disabled, causing a linear O(4053) triangle scan
per ray instead of O(log n) BVH traversal.

Fixes:
- texture_test.yaml: use top-level 'camera:' and 'settings:' sections
- yaml_scene_loader.cc: also accept 'scene.use_bvh' as a legacy alias

Result: 1.9M -> 38M rays/sec (20x speedup, 85% of the non-textured baseline)
- Larger grid textures generation script
- Update to Suzanne model
@pmudry pmudry marked this pull request as draft March 17, 2026 09:18
@pmudry pmudry self-assigned this Mar 17, 2026
@pmudry pmudry added the enhancement New feature or request label Mar 17, 2026
@pmudry pmudry requested a review from Copilot March 17, 2026 09:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds first-pass texture + MTL material-library support for OBJ meshes (GPU paths: CUDA + OptiX), along with sample assets/scenes and a milestone-explorer script update to the project docs.

Changes:

  • Add MTL parsing + per-OBJ-group material assignment (mtllib / usemtl), with diffuse color (Kd) and diffuse texture (map_Kd) support.
  • Add texture loading via stb_image, UV propagation through the unified scene → CUDA/OptiX scene transfer, and texture sampling in GPU shaders.
  • Add sample texture scenes/assets and milestone-explorer automation script + docs.

Reviewed changes

Copilot reviewed 28 out of 39 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
src/rayon/scenes/scene_description.hpp Adds texture storage to the unified scene and triangle UV support APIs.
src/rayon/scenes/texture_loader.cc Implements SceneDescription::addTexture() using stb_image.
src/rayon/scenes/mtl_loader.hpp New MTL parser translating MTL entries into MaterialDesc (+ optional map_Kd).
src/rayon/scenes/obj_loader.hpp Extends OBJ loader to read mtllib/usemtl and attach per-group materials + UVs.
src/rayon/scenes/yaml_scene_loader.cc Adds YAML material.texture support and allows OBJ geometry to omit YAML material when using MTL.
src/rayon/gpu_renderers/scene_builder_cuda.cu Uploads textures to CUDA texture objects and forwards triangle UVs.
src/rayon/gpu_renderers/cuda_raytracer.cuh Interpolates triangle UVs and samples textures in material application.
src/rayon/gpu_renderers/optix/* Extends OptiX attributes/SBT data for UVs + texture sampling, plus displaced-sphere support.
resources/scenes/*, resources/models/*, resources/textures/* Adds/updates sample scenes + models + texture for validation.
scripts/* + website/docs/history.md Adds milestone explorer script and documents usage.
CMakeLists.txt Adds texture_loader.cc and adjusts OptiX source inclusion.

You can also share your feedback on Copilot code review. Take the survey.

pmudry and others added 2 commits March 17, 2026 10:28
Hard-coded paths correction

Co-authored-by: Copilot Autofix powered by AI <[email protected]>
@pmudry pmudry marked this pull request as ready for review March 17, 2026 19:42
- Add missing <cmath>/<cctype> headers in mtl_loader.hpp; use std::tolower safely
- Resolve texture paths relative to YAML scene_dir in yaml_scene_loader.cc
- Fix comment/code order mismatch in cuda_raytracer.cuh (texture overwrites pattern)
- Fix cudaArray_t GPU memory leaks in optix_renderer.cu (rebuild + cleanup paths)
- Fix cudaArray_t GPU memory leaks in scene_builder_cuda.cu (freeGPUScene)
- Fix mtl_dir resolved from mtl file path, not OBJ dir in obj_loader.hpp
- Fix OBJ visible flag applied to whole triangle range, not just last triangle
- Document 'stripes' pattern in SCENE_FORMAT.md"
@pmudry
Copy link
Copy Markdown
Owner Author

pmudry commented Mar 17, 2026

Fixed in latest commit

@pmudry pmudry marked this pull request as draft March 17, 2026 19:58
@pmudry pmudry marked this pull request as ready for review March 17, 2026 19:58
@pmudry pmudry marked this pull request as draft March 17, 2026 19:58
@pmudry pmudry requested a review from Copilot March 17, 2026 19:58
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds initial GPU-side texture mapping and OBJ/MTL material support to RayON’s unified scene system, enabling per-face materials and diffuse image textures (CUDA + OptiX), plus sample assets/scenes to exercise the feature.

Changes:

  • Extend scene/mesh pipeline to carry UVs and texture IDs from OBJ/MTL through to CUDA and OptiX shaders.
  • Add stb_image-based texture loading and GPU texture-object creation/freeing for CUDA + OptiX backends.
  • Add/update sample scenes/assets and milestone tooling docs/scripts.

Reviewed changes

Copilot reviewed 28 out of 39 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
website/docs/history.md Documents the Milestone Explorer script usage.
src/rayon/scenes/yaml_scene_loader.cc Adds YAML materials[].texture support; makes OBJ material optional (MTL-only mode); legacy BVH key support; OBJ visibility range handling.
src/rayon/scenes/texture_loader.cc New stb_image-backed SceneDescription::addTexture() implementation.
src/rayon/scenes/scene_description.hpp Adds texture storage, UV fields for triangles, and triangle helpers that accept UVs.
src/rayon/scenes/obj_loader.hpp Adds mtllib/usemtl parsing, lazy MTL→scene material registration, and UV propagation into triangles.
src/rayon/scenes/mtl_loader.hpp New MTL parser mapping Kd/Ke/etc + map_Kd into MaterialDesc (+ diffuse textures).
src/rayon/gpu_renderers/scene_builder_cuda.cu Transfers UVs to GPU geometry; builds/destroys CUDA texture objects and uploads handle arrays.
src/rayon/gpu_renderers/optix/optix_renderer.cu Uploads UVs/material texture IDs; builds/destroys CUDA texture objects for OptiX launch params; updates attribute count.
src/rayon/gpu_renderers/optix/optix_programs.cu Carries UV attributes for triangles; samples textures in closest-hit; ports golf-ball displacement helpers.
src/rayon/gpu_renderers/optix/optix_params.h Extends SBT/material/launch params/PRD to carry UVs and texture handles.
src/rayon/gpu_renderers/cuda_scene.cuh Adds triangle UVs + scene texture handle array to CUDA scene structs.
src/rayon/gpu_renderers/cuda_raytracer.cuh Interpolates triangle UVs; samples CUDA textures in material application.
scripts/milestones/goto_milestone.sh New milestone checkout/build/run automation script.
scripts/generate_uv_models.py Generates UV-mapped OBJ/MTL assets for texture test scenes.
scripts/generate_grid_texture.py Generates grid PNG textures without external deps.
resources/textures/grid_512.png Adds generated reference grid texture.
resources/scenes/pattern_gallery.yaml Updates pattern example to Fibonacci dots (checkerboard removed).
resources/scenes/SCENE_FORMAT.md Updates pattern documentation (removes checkerboard section).
resources/scenes/14_texture_test2.yaml Adds a texture/MTL test scene using an OBJ with MTL materials.
resources/scenes/13_texture_test1.yaml Adds a texture/MTL test scene using generated UV models.
resources/scenes/04_obj_test_scene.yaml Updates OBJ path used in the OBJ test scene.
resources/models/texture_test.mtl Adds MTL file referencing a grid texture for tests.
resources/models/test_scene.mtl Adds Blender-exported MTL file for a test scene.
resources/models/suzanne.mtl Adds Blender-exported MTL stub for Suzanne model.
resources/models/render_sphere.mtl Adds Blender-exported MTL for render_sphere OBJ (multi-material).
resources/models/plane_uv.obj Adds UV-mapped plane OBJ for texture tests.
resources/models/cube_uv.obj Adds UV-mapped cube OBJ for texture tests.
TODOS.md Reorganizes TODOs; marks texture loading as done.
CMakeLists.txt Adds texture_loader.cc; adjusts OptiX source inclusion via target_sources().
.gitignore Ignores docs/ at repo root (in addition to MkDocs output).
Comments suppressed due to low confidence (1)

src/rayon/scenes/yaml_scene_loader.cc:606

  • loadSceneFromYAML() clears materials, geometries, and meshes but does not clear the new scene.textures vector. Loading multiple scenes in one process would keep old textures around, potentially shifting texture IDs and leaking memory. Clear scene.textures alongside the other scene arrays when starting a new load.

You can also share your feedback on Copilot code review. Take the survey.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds Wavefront MTL material loading and UV-based image texture mapping to RayON’s OBJ mesh pipeline, wiring texture data through the unified scene description into the CUDA and OptiX GPU backends, and updating docs + sample scenes/assets accordingly.

Changes:

  • Add texture image loading (stb_image) and a scene-level TextureDesc store with path deduplication.
  • Extend OBJ loading to parse vt UVs, mtllib, usemtl, and translate MTL entries into RayON materials (including map_Kd textures).
  • Upload textures to GPU (CUDA/OptiX) as texture objects and sample them during shading using interpolated per-hit UVs.

Reviewed changes

Copilot reviewed 31 out of 42 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
website/docs/history.md Documents the new milestone covering MTL + textures and adds it to the timeline table.
website/docs/gallery.md Adds new gallery images/captions demonstrating UV mapping and MTL-driven textures.
website/docs/features/scenes.md Updates scene docs: OBJ type string (obj), optional material when using MTL, and adds texture path notes.
website/docs/features/obj-loading.md Expands OBJ docs to cover MTL + UV texture mapping and YAML examples.
src/rayon/scenes/yaml_scene_loader.cc Adds YAML material texture: support and allows OBJ geometry without a YAML material when relying on MTL.
src/rayon/scenes/texture_loader.cc Implements SceneDescription::addTexture() using stb_image with path dedup.
src/rayon/scenes/scene_description.hpp Adds triangle UV storage, TextureDesc storage, and triangle helpers that include UVs.
src/rayon/scenes/obj_loader.hpp Reworks OBJ parser to support vt, mtllib, usemtl, and per-group MTL material resolution + texture hookup.
src/rayon/scenes/mtl_loader.hpp New MTL parser that maps MTL properties (Kd/Ke/Ns/Ni/map_Kd, etc.) to internal materials and textures.
src/rayon/gpu_renderers/scene_builder_cuda.cu Uploads textures as CUDA texture objects and passes texture handle arrays into the CUDA scene.
src/rayon/gpu_renderers/optix/optix_renderer.cu Uploads textures for OptiX, expands attribute count to include UV, and passes textures via launch params.
src/rayon/gpu_renderers/optix/optix_programs.cu Interpolates UVs in triangle intersection attributes and samples textures in closest-hit shading.
src/rayon/gpu_renderers/optix/optix_params.h Adds UV fields to hit data and texture array pointers/count to launch params.
src/rayon/gpu_renderers/cuda_scene.cuh Extends GPU-side triangle geometry to carry UVs and scene to carry texture handles.
src/rayon/gpu_renderers/cuda_raytracer.cuh Interpolates triangle UVs, samples CUDA textures in material application, and plumbs texture arrays through.
scripts/milestones/goto_milestone.sh Improves whitespace filtering by using a more portable regex character class.
scripts/generate_uv_models.py Adds a generator script for UV-mapped OBJ test models + a texture_test MTL.
scripts/generate_grid_texture.py Adds a dependency-free PNG generator for grid textures.
resources/textures/grid_512.png Adds a grid texture asset for validating UV mapping.
resources/scenes/pattern_gallery.yaml Updates pattern gallery example to use fibonacci_dots settings.
resources/scenes/SCENE_FORMAT.md Updates pattern documentation (removes checkerboard example; documents stripes).
resources/scenes/14_texture_test2.yaml Adds a sample scene for a Blender-exported multi-material OBJ/MTL texture test.
resources/scenes/13_texture_test1.yaml Adds a sample scene using generated UV test models and grid texture.
resources/scenes/04_obj_test_scene.yaml Updates OBJ scene to point to render_sphere.obj for testing.
resources/models/texture_test.mtl Adds MTL used by generated UV models to reference the grid texture.
resources/models/test_scene.mtl Adds Blender-exported MTL for a sample OBJ scene (multi-material with textures).
resources/models/suzanne.mtl Adds Blender-exported MTL stub for suzanne asset.
resources/models/render_sphere.mtl Adds Blender-exported MTL for render_sphere.obj materials.
resources/models/plane_uv.obj Adds generated UV test model (plane).
resources/models/cube_uv.obj Adds generated UV test model (cube).
CMakeLists.txt Ensures the new texture_loader.cc builds and OptiX renderer TU is only added when OptiX is found.
TODOS.md Updates TODO structure/status to reflect texture loading and reorganize sections.
.gitignore Adds docs/ to ignored paths.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +33 to +38
* Materials are resolved from the .mtl file referenced by mtllib.
* The caller-supplied @p fallback_mat_id is used only for faces that
* belong to a group with no usemtl directive (or when no .mtl is found).
* Pass -1 for @p fallback_mat_id to require all materials to come from
* the .mtl file (faces without usemtl are then skipped with a warning).
*
Comment on lines +403 to +419
// Destroy texture objects and free the handle array
if (host_scene.d_textures && host_scene.num_textures > 0)
{
std::vector<cudaTextureObject_t> host_tex(static_cast<size_t>(host_scene.num_textures));
cudaMemcpy(host_tex.data(), host_scene.d_textures,
host_scene.num_textures * sizeof(cudaTextureObject_t),
cudaMemcpyDeviceToHost);
for (int i = 0; i < host_scene.num_textures; ++i)
{
if (host_tex[i])
{
cudaResourceDesc rd = {};
cudaGetTextureObjectResourceDesc(&rd, host_tex[i]);
cudaDestroyTextureObject(host_tex[i]);
if (rd.resType == cudaResourceTypeArray && rd.res.array.array)
cudaFreeArray(rd.res.array.array);
}
Comment on lines +52 to +55
def gen_plane(filepath, size=4.0, subdivs=5, mtl_name='textured'):
verts, uvs, norms, faces = [], [], [], []
N = normal = (0, 1, 0)

Comment on lines +136 to +143
// UV coordinates
geom.data.triangle.uv0 = f2(static_cast<float>(desc.data.triangle.uv0.x()),
static_cast<float>(desc.data.triangle.uv0.y()));
geom.data.triangle.uv1 = f2(static_cast<float>(desc.data.triangle.uv1.x()),
static_cast<float>(desc.data.triangle.uv1.y()));
geom.data.triangle.uv2 = f2(static_cast<float>(desc.data.triangle.uv2.x()),
static_cast<float>(desc.data.triangle.uv2.y()));
geom.data.triangle.has_uvs = desc.data.triangle.has_uvs;
Comment on lines 601 to 610
void addTriangle(const Vec3& v0, const Vec3& v1, const Vec3& v2, int mat_id) {
GeometryDesc geom;
geom.type = GeometryType::TRIANGLE;
geom.material_id = mat_id;
geom.data.triangle.v0 = v0;
geom.data.triangle.v1 = v1;
geom.data.triangle.v2 = v2;
geom.data.triangle.has_normals = false;
geom.data.triangle.has_uvs = false;

Co-authored-by: Copilot Autofix powered by AI <[email protected]>
@pmudry
Copy link
Copy Markdown
Owner Author

pmudry commented Mar 17, 2026

@copilot open a new pull request to apply changes based on the comments in this thread

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 17, 2026

@pmudry I've opened a new pull request, #24, to work on those changes. Once the pull request is ready, I'll request review from you.

…ng, and unused alias (#24)

* Initial plan

* fix: address unresolved review comments (UV init, CUDA_CHECK, warning, unused var)

Co-authored-by: pmudry <[email protected]>

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: pmudry <[email protected]>
@pmudry pmudry marked this pull request as ready for review March 17, 2026 20:54
@pmudry pmudry merged commit 387ca14 into main Mar 17, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants