Skip to content

Python plugins for Blender shader nodes - #1732

Open
Speierers wants to merge 1 commit into
masterfrom
blender_shader_node_textures
Open

Python plugins for Blender shader nodes#1732
Speierers wants to merge 1 commit into
masterfrom
blender_shader_node_textures

Conversation

@Speierers

Copy link
Copy Markdown
Member

This PR provides Python texture plugins that should cover most of the Blender shader graph nodes.

Remaining TODOs:

  • Proper testing
  • Add-on code to instanciate those plugins when traversing the shader graph.

@wjakob

wjakob commented Sep 11, 2025

Copy link
Copy Markdown
Member

Hi Sébastien,

these look great, and it would be amazing to merge them into Mitsuba. But as you mentioned, there is no testing infrastructure at all, and that makes it tricky to accept your contribution as-is. Are you planning to work on these remaining TODOs?

Thank you!

ConnorBaker added a commit to ConnorBaker/mitsuba3 that referenced this pull request Sep 3, 2026
Cluster P1 of the hsr/blender-parity feature port (see PORT_LOG.md): the
mitsuba-renderer#1732-derived texture plugin package (29 registered plugins + the
blender_color/blender_hash/blender_math helper modules) and its
registration/reload infrastructure, ported from the fork's mi.Texture world
onto master's Field rework.

What could NOT port verbatim, and what replaced it:

- alias.cpp is deleted upstream; the fork's per-set_variant reload hunk
  becomes an entry in src/python/__init__.py's JIT-variant reload list --
  upstream's own mechanism for ad.integrators/ad.loaders. The
  reload-the-submodule-not-the-parent comment carries over.

- mi.Texture -> mi.Field: new shared TextureBase (plugins/textures/_base.py)
  declares the Color3/Surface/JIT-only contract and is itself reloaded before
  the plugin submodules (it subclasses the variant-specific mi.Field). Per
  plugin, mechanically and audited: class base swap, `def eval` ->
  `def eval_color3` (Field's spectral eval dispatches through out_type to
  eval_color3; the generic `eval` slot now means a flat FloatStorage, so
  keeping the old name would have broken every C++-side evaluation),
  register_texture -> register_field, and udim's issubclass check follows.
  eval_1/eval_3/mean/max/resolution/is_spatially_varying/traverse/
  parameters_changed keep their names -- verified against PyField's ticket
  table, which consults exactly those spellings (including plain
  `resolution` for resolution_2d).

- math -> blender_math (BREAKING for exporters): upstream's C++ expression
  texture owns `math` (mitsuba3#1944) and even shares the input_0/input_1
  property names while requiring `expr`. The RESERVED_BY_CPP guard caught
  this collision live on the first smoke run -- the guard now covers the
  field registry's C++ names (+ constvolume, gridvolume, math, sinusoidal,
  volume) and matches register_field.

- src/python/CMakeLists.txt globs *.npy so the P2 GGX tables install.

Evidence (executed, not read): smoke run against the 0cba523 build with
this tree overlaid on PYTHONPATH, cuda_ad_rgb -- 13/13 checks: registration,
eval_1/eval_3/spectral dispatch, nested-field wrappers (clamp over
blender_math, color_ramp elements path, texture_coordinate's Blender V-flip),
C++ `math` coexistence under its own name, variant-change reload
(cuda_ad_spectral -> cuda_ad_rgb) re-registration, mean/spatially-varying
passthrough. Compile of the installed package happens at the next cluster
build; nothing in this commit touches C++.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PebCbQxKGLJZiynQmV1U44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants