Add OpenPBR version conversion tool (1.1 <-> 1.2)#307
Open
portsmouth wants to merge 3 commits into
Open
Conversation
Adds versioning/, a tool that converts an OpenPBR Surface parameter set between specification versions, choosing the parameter correspondence that yields the closest match of the resulting appearance. Changes are classified as: A. Exactly invertible reparametrizations (applied) B. Lossy / bounded maps (applied + warned where they diverge) C. Internal BSDF / MaterialX-graph fixes (no remap; reported as notes) 1.1 <-> 1.2 mapping: - emission_weight (AcademySoftwareFoundation#231) + emission_luminance default 0->1000: exact fold - transmission_scatter coefficient<->albedo (AcademySoftwareFoundation#286): Omega = -S/ln(T) - specular_weight refraction decoupling (AcademySoftwareFoundation#247): passthrough + warn - specular_haze (AcademySoftwareFoundation#254) / specular_retroreflectivity (AcademySoftwareFoundation#255): inert at default Architecture: a linear version ladder with a registry of adjacent migrations; multi-version conversions (e.g. 1.1->1.3) compose automatically. Adding 1.3 is a localized change (see VERSIONING.md). - openpbr_version.py: dependency-free dict core + MaterialX .mtlx wrapper + CLI - test_openpbr_version.py: 32 numeric tests (maps, round-trips, chaining) - VERSIONING.md: logic reference + "adding a new version" checklist Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The value-only core cannot see node-connected inputs, so when emission_luminance is texture-driven (rather than a literal value) the 1.1 -> 1.2 upgrade previously left emission_weight unauthored, defaulting it to 0 and silently zeroing the textured emission. The MaterialX wrapper now detects a connected emission_luminance and authors the constant emission_weight = 1 (exact, since 1.2 emission is weight * color * luminance), with a warning. The valued case is unchanged (handled by the core). Adds wrapper tests (skipped when MaterialX is absent) and documents the valued-vs-connected distinction and the remaining application-owned coupled case (transmission_scatter when transmission_color is textured) in VERSIONING.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds VERSIONING.md section 4 as the source of truth for renderer/DCC plugin
authors (Arnold mtoa/htoa, etc.) implementing version migration natively.
Reframes a migration as a per-parameter transform with two realizations: fold
to a constant when the input is valued, or insert an equivalent node network
when the input is connected to an upstream output (value known only at render
time). Documents:
- the five operation kinds (PASS / SET_CONST / TRANSFORM / DROP / RENAME)
- the full 1.1 <-> 1.2 operation table, flagging which maps need a network
- the exact MaterialX node networks for the TRANSFORM cases
(transmission_scatter both directions; emission_luminance downgrade),
including the T -> 1 singularity guard
- that for connected inputs, Class-B author-time warnings degrade to
in-graph clamps
The "adding a new version" checklist now points maintainers to document any
new TRANSFORM map's network in section 4.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
versioning/, a tool that converts an OpenPBR Surface parameter set between specification versions, in either direction, choosing the parameter correspondence that yields the closest match of the resulting appearance.It is both a Python API and a CLI, and is architected so each future release (1.3, …) is added as a single adjacent migration step — multi-version conversions then compose automatically.
The closest-match philosophy
A version converter only changes parameters, so it can compensate only for differences that are themselves parameterized. Every 1.1↔1.2 difference is classified as:
A warning-free, note-free result means the conversion is exact for that material.
The 1.1 ↔ 1.2 mapping (derived by diffing the
v1.1tag against the 1.2 spec)Four parameters were added in 1.2 and none removed; two shared parameters were reinterpreted; one default changed.
emission_weight(#231) +emission_luminancedefault 0→1000emission_weight=1; down:emission_luminance ← weight×luminance, drop weighttransmission_scattercoefficient↔albedo (#286)Ω = −S/ln T↔S = −Ω·ln Tper channel; clamp+warn in the grey-shift / dark-color / no-extinction regimesspecular_weightrefraction decoupling (#247)≠1and transmission activespecular_haze(#254) /specular_retroreflectivity(#255)Architecture
A linear
VERSION_ORDERladder plus a registry of adjacentMigrations (each holding an upgrade and downgrade rule).convert_paramswalks the ladder and composes adjacent steps, so e.g.1.1→1.3runs1.1→1.2then1.2→1.3. Adding 1.3 is a localized change — see the checklist inVERSIONING.md.Two layers:
convert_params(params, from_version, to_version)— dependency-free dict core (stdlib only), embeddable in any app/renderer.convert(input_path/input_string, …)— MaterialX.mtlxwrapper (requires theMaterialXpackage; otherwise self-contained). Touches only the inputs the conversion changed.Contents
versioning/openpbr_version.py— core + MaterialX wrapper + CLIversioning/test_openpbr_version.py— 32 numeric tests (closed-form maps, both round-trips, bounded-loss edge cases, and the chaining architecture via a synthetic 1.3). All passing; no rendering, no MaterialX dependency.versioning/VERSIONING.md— logic reference + "adding a new version" checklistTesting
CLI
🤖 Generated with Claude Code