Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal : Improvements to double sided surface shading. #2086

Open
ld-kerley opened this issue Oct 25, 2024 · 5 comments
Open

Proposal : Improvements to double sided surface shading. #2086

ld-kerley opened this issue Oct 25, 2024 · 5 comments

Comments

@ld-kerley
Copy link
Contributor

Introduction

This document summarizes a couple of recent conversations surrounding how shading the front and surface of an object might be improved in MaterialX. It’s broken down into a number of separate proposals. One of the benefits of this proposal is that it would allow artists to construct materials with different values or surface shaders on each side of a surface, and use that MaterialX material in USD without requiring changes to USD. To be clear, this proposal does not preclude USD adding support for the backsurfaceshader terminal in the <surfacematerial>, but it would eliminate a potential complication regarding USD supporting MaterialX 1.39 early next year.

Proposal : <frontface> Node

This node accepts no input, returns true if the front surface is being shaded, and false for the back surface. This node will allow the MaterialX graph to make decisions based on which side of the surface is being shaded.

<nodedef name=”ND_frontface_boolean” node=”frontface” type=”boolean”>
  <output name=”out” type=”boolean”
</nodedef>

Questions:

  • Is it also useful to have an integer version of this node that returns 0 and 1? This would make it easier to use as an input to <switch>.

Proposal : <twosides>

This node allows two different input values to be switched between, based on which side of the surface is being shaded. For instance, this node could be used to swap the color of a surface between the front and back sides of a surface.

<nodedef name=”ND_twosides_float` node=”twosides” type=”color3”>
  <input name=”front” type=”float” value=”0”/>
  <input name=”back” type=”float” value=”0”/>
  <output name=”out” type=”float”/>
</nodedef>

Its noted that this node could be implemented as a nodegraph implementation if the proposal for adding the <frontface> node above is accepted.

It is proposed that this node would have node definitions for the following types.

  • float
  • integer
  • color3
  • color4
  • vector2
  • vector3
  • vector4
  • matrix33
  • matrix44
  • surfaceshader

This last type is an important one. It would allow us to address the current conversation surrounding having different shaders on each side of a surface. Allowing two surfaces to be combined into a single port, and then connected to a downstream <surfacematerial> node, this is the critical component to gain the advantage of easier MaterialX 1.39 adoption in USD early next year.

<UsdPreviewSurface name=”frontMtl” type=”surfaceshader”>
  <input name=”diffuseColor” type=”color3” value=”1, 0, 0”/>
  <input name=”metallic” type=”float” value=”1”/>
</UsdPreviewSurface>
<UsdPreviewSurface name=”backMtl” type=”surfaceshader”>
  <input name=”diffuseColor” type=”color3” value=”0, 0, 1”/>
  <input name=”metallic” type=”float” value=”0”/>
</UsdPreviewSurface>
<twosides name=”twosides” type=”surfaceshader”>
  <input name=”front” type=”surfaceshader” nodename=”frontMtl”/>
  <input name=”back” type=”surfaceshader” nodename=”backMtl”/>
</twosides>
<surfacematerial name=”MyMtl” >
  <input name=”surfaceshader” type=”surfaceshader” nodename=”twosides”/>
</surfacematerial>

This proposal is intentionally not taking any stance around considerations for uniform data, to keep the focus on double sided aspect of this proposal. We would expect this twosides node to follow any future introduced conventions to accommodate uniform data.

@flord
Copy link

flord commented Oct 25, 2024

In the name of all artist users, thank you Lee!

@fpliu
Copy link

fpliu commented Oct 25, 2024

q1. I'm fine with it only being boolean. Seems easy enough to covert to int if needed.

@crydalch
Copy link
Contributor

I agree it's not hard to convert' I think more places use integer than boolean (i.e. switch)? That might make it slightly more convenient to output integer; but not hard either way to deal with.

@jstone-lucasfilm
Copy link
Member

I really like the idea of a frontface node, which seems like a clear omission from the MaterialX standard.

Perhaps we should start with this, since more complex nodes such as twosides can easily be expressed as graphs that reference frontface?

As a historical note, we originally had a backfacing node in the MaterialX 1.37 standard, but we needed to remove it when MDL support was first introduced to MaterialX, as MDL was not able to support camera-dependent nodes at that time. I believe this issue in MDL has now been resolved, so we should be in a good position to reintroduce this concept again in MaterialX 1.39.

Here is the relevant section of the MaterialX 1.37 specification, for those interested in the history:

backfacing: Returns true (or 1) if the surface being shaded is seen from the back side
(or the inside of a closed object). Returns false (or 0) if seen from the front or the outside
of a closed object. Output type "boolean", "integer" or "float"; no parameters or inputs.

https://materialx.org/assets/MaterialX.v1.37REV2.PBRSpec.pdf

@ld-kerley
Copy link
Contributor Author

Instead of adding frontface does it feel more natural to just re-introduce the backfacing node that was removed. It would seem to perform a conceptually similar role

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

No branches or pull requests

5 participants