Skip to content

Updates to Support PhysicallyBased V2 : Part I.#37

Merged
kwokcb merged 9 commits intomainfrom
pb_v2_translation_fixes
Mar 4, 2026
Merged

Updates to Support PhysicallyBased V2 : Part I.#37
kwokcb merged 9 commits intomainfrom
pb_v2_translation_fixes

Conversation

@kwokcb
Copy link
Copy Markdown
Owner

@kwokcb kwokcb commented Mar 3, 2026

Changes

  • Handle color and specular color JSON changes in V2. Including specular_color format, and colorspace additions.
  • Choose F82 correct specular color format for glTF vs SS vs OPBR. Default of Gulbrandsen is used for Standard Surface. This would also work for Disney and USDPreview if conversion support were to be added .
  • Re-run translation for each shading model. Basically no change except colorspace is made explicit now. i.e. all color inputs set lin_rec709.
  • Update physically_based nodedef and translation graphs. Note that some parameters are bypassed since the parameters have different formats for different materials. To be addressed on input data side.

Example Output:

SS Cobalt: (explicit linear colorspace, Gulbrandsen format for specular color)

<standard_surface name="Cobalt_SS_SHD_PBM" type="surfaceshader" uiname="Cobalt" uifolder="Metal" doc="Reference: https://raw.githubusercontent.com/AntonPalmqvist/physically-based-api/main/images/renders/cycles/300/cobalt.avif">
    <input name="base_color" type="color3" value="0.699, 0.704, 0.671" colorspace="lin_rec709" />
    <input name="metalness" type="float" value="1" />
    <input name="specular_color" type="color3" value="0.731, 0.775, 0.715" colorspace="lin_rec709" doc="Format: Gulbrandsen" />
    <input name="specular_roughness" type="float" value="0" />
  </standard_surface>

OpenPBR Cobalt: (explicit linear colorspace, F82 format for specular color)

  <open_pbr_surface name="Cobalt_OPBR_SHD_PBM" type="surfaceshader" uiname="Cobalt" uifolder="Metal" doc="Reference: https://raw.githubusercontent.com/AntonPalmqvist/physically-based-api/main/images/renders/cycles/300/cobalt.avif">
    <input name="base_color" type="color3" value="0.699,0.704,0.671" />
    <input name="base_metalness" type="float" value="1" />
    <input name="specular_color" type="color3" value="0.727,0.772,0.823" doc="Format: F82" />
    <input name="specular_roughness" type="float" value="0" />
  </open_pbr_surface>

glTF Cobalt: (explicit linear colorspace, F82 format for specular color)

  <gltf_pbr name="Cobalt_GLTF_SHD_PBM" type="surfaceshader" uiname="Cobalt" uifolder="Metal" doc="Reference: https://raw.githubusercontent.com/AntonPalmqvist/physically-based-api/main/images/renders/cycles/300/cobalt.avif">
    <input name="base_color" type="color3" value="0.699, 0.704, 0.671" colorspace="lin_rec709" />
    <input name="metallic" type="float" value="1" />
    <input name="specular_color" type="color3" value="0.727, 0.772, 0.823" colorspace="lin_rec709" doc="Format: F82" />
    <input name="roughness" type="float" value="0" />
  </gltf_pbr>

AntonPalmqvist and others added 6 commits February 28, 2026 09:28
…lorspace and format (for specular) is to take the first entry which

preserves the previous values but now with proper colorspace tagging.
…iseny and USDPreview are not currently supported

but the default is Gulbrandsen. There is no BSDF for Lama nodes but the default should work there as well.
- Fix colorspace specification. It was being used for all inputs instead of just ones where specifeid.
- Fix transmission color colorspace setting.
- Rerun translation for each shading model.
…r does not write lin_rec709 unless specified by option.
@kwokcb kwokcb requested a review from AntonPalmqvist March 3, 2026 19:09
Copy link
Copy Markdown
Collaborator

@AntonPalmqvist AntonPalmqvist left a comment

Choose a reason for hiding this comment

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

OpenPBR assumes ACEScg by default , so the color space needs to specifically be set to lin_rec709 when using that color space. For ACEScg it can be left empty.

StandardSurface doesn't seem to have a default color space, so the color space should always be set explicitly there.

@kwokcb
Copy link
Copy Markdown
Owner Author

kwokcb commented Mar 3, 2026

OpenPBR assumes ACEScg by default , so the color space needs to specifically be set to lin_rec709 when using that color space. For ACEScg it can be left empty.

StandardSurface doesn't seem to have a default color space, so the color space should always be set explicitly there.

I've made colorspace always explicit.
OpenPBR in MaterialX never specifies a default colorspace. The only nodes that do so are Lama nodes.

I have patched custom phybased definition but it won't work since there is no 1 interface that can be used for multiple targets. i.e. you can't store 1 value when different values are required per backend.

colorspace = ''
input_doc = ''

if key in ['viscosity', 'density', 'thinFilmThickness']:
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

The format for these differs between materials now. No idea how to map to a single definition input. Sometimes it is float, vec2, or vec3.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I can appreciate this causes some friction.

I wanted to give every implementer a chance to display the value they think is most useful, or all values if they prefer that. However in the case of MaterialX, only one value can be used of course.

For example, the Thin Film Thickness for Soap Bubble can be between 10-1000, with 500 being the most common thickness.
I would check if [2] in the array is present, and if not, choose either [1] or [0]. You could also calculate the average of [0] and [1] and use that.

Hope it makes sense.

Copy link
Copy Markdown
Owner Author

@kwokcb kwokcb Mar 4, 2026

Choose a reason for hiding this comment

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

For the nodedef, this can't be dynamic as there is only 1 definition not a definition per material.

So if a parameter can be specified with 1, 2 or 3 values, then if the parameter is specified with the highest ordinal, the assigned value would have to have "dummy" values added
to "pad" it.

The current possible validation errors are as follows, without "padding"

Invalid value: <input name="viscosity" type="vector3" value="1.7">
Invalid value: <input name="viscosity" type="vector3" value="46">
Invalid value: <input name="viscosity" type="vector3" value="0.6">
Invalid value: <input name="viscosity" type="vector3" value="1.552">
Invalid value: <input name="viscosity" type="vector3" value="2">
Invalid value: <input name="thinFilmThickness" type="vector3" value="20, 300">
Invalid value: <input name="viscosity" type="vector3" value="1.002">

@kwokcb kwokcb changed the title More Updates for PhysicallyBased V2 Updates to Support PhysicallyBased V2 Mar 3, 2026
@kwokcb kwokcb changed the title Updates to Support PhysicallyBased V2 Updates to Support PhysicallyBased V2 : Part I. Mar 4, 2026
@kwokcb kwokcb requested a review from AntonPalmqvist March 4, 2026 04:00
Copy link
Copy Markdown
Collaborator

@AntonPalmqvist AntonPalmqvist left a comment

Choose a reason for hiding this comment

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

I've tested the different .mtlx outputs in both MaterialXViewer and Unreal Engine 5.7 without issues.

@kwokcb kwokcb merged commit c8f0d9c into main Mar 4, 2026
@kwokcb kwokcb deleted the pb_v2_translation_fixes branch March 4, 2026 04:56
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