-
-
Notifications
You must be signed in to change notification settings - Fork 35.5k
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
Nodes: MaterialX Noise Functions Lib #24504
Conversation
This is looking great! |
Thanks! |
/fyi @jstone-lucasfilm |
This looks really promising, thanks @sunag and @mrdoob. Over time, I wonder if we might be able to increase the degree of code sharing between the MaterialX and three.js codebases, so that future refinements to core shading code (e.g. noise functions such as Based on work that was started at Autodesk, we have early JavaScript bindings for MaterialX libraries such as MaterialXGenGlsl, so one option would be to determine what's missing from those bindings that would be needed for three.js to call into this library directly, generating the required GLSL code when a MaterialX node (e.g. None of these considerations should block the great work that I'm seeing in progress, but it seems worthwhile to consider them for the future. |
Thanks for the pointers!
That would be great indeed! Maybe a npm package with all the snippets? |
@mrdoob That's a really good suggestion. We currently package MaterialX-generated shader snippets for OSL in this way, allowing them to be individually accessed in tools that perform their own final shader generation. It should be straightforward to extend this to GLSL in the future, and the results could indeed be shared directly through For the formatting of this shader snippet library, would it be reasonable to have a separate GLSL file for each MaterialX node, including the definition of that node plus file references to any shared GLSL libraries upon which it depends? That's the pattern we currently use for OSL, so it would likely be the most straightforward starting point for GLSL and other languages. |
@sunag what do you think? |
Thanksss @jstone-lucasfilm :) . Soon after reading the comment I thought of making a live example using MaterialX, and it worked perfectly with the GLSL code already in the MaterialX repository. Live Code import { MeshPhysicalNodeMaterial, code, fn } from 'three-nodes/Nodes.js';
const mxNoiseURL = "https://raw.githubusercontent.com/AcademySoftwareFoundation/MaterialX/main/libraries/stdlib/genglsl/lib/mx_noise.glsl";
const mxNoiseLive = await fetch( mxNoiseURL );
const mxNoise = code( await mxNoiseLive.text() );
const mxIncludes = [ mxNoise ];
const mx_perlin_noise_float = fn( 'float mx_perlin_noise_float( vec3 p )', mxIncludes );
//..
const material = new MeshPhysicalNodeMaterial();
material.colorNode = mx_perlin_noise_float( someCoordNode ); Using interfaces to identify the signature of the functions we can refine the code at will, including the dependencies. In a way this is already possible without much effort, of course we can do something more organized creating a npm package if needed or create only one build in the MaterialX repo itself for this purpose, but I think the idea of @jstone-lucasfilm is very good. |
In the npm ecosystem, the path an end-user imports is abtracted from the files on disk. Separate files for each node would be completely fine, there just needs to be something (usually a // index.js
export * from './nodes/a.js';
export * from './nodes/b.js';
export * from './nodes/c.js';
// ... Those files may in turn import from any shared GLSL libraries they require. The end-user only sees something like this: import { b } from '@materialx/glsl'; Happy to help with the scaffolding if MaterialX wants to go in that direction! |
@donmccurdy I made a draft here a few days ago but I think about doing a PR after the name of the nodes becomes more mature in the context of three.js. Anyway, I also think that would be the better way too. |
@jstone-lucasfilm have you ever thought of putting an attribute of canvas position XY in For example: <texcoord name="texcoord1" type="vector2" posx="100" posy="50" /> This would represent a node in the editor at position |
@sunag Although they're not yet leveraged in production tools, there are actually https://materialx.org/assets/MaterialX.v1.38.Spec.pdf#page=42 We're planning to support this feature in the upcoming Open MaterialX Graph Editor, which is scheduled to appear on GitHub later this year: https://materialx.org/assets/ASWF_OSD2022_MaterialX_OSL_Final.pdf#page=26 One caveat is that the |
Ohh... Amazing!! Certainly |
@jstone-lucasfilm Any plans on generating wgsl files too? https://www.w3.org/TR/WGSL/ |
@mrdoob Not yet, though if there's a good case to be made for direct generation of WGSL, I believe that would be a straightforward feature to add. What are your thoughts on the benefits this would bring? |
@jstone-lucasfilm I don't know if MrDoob sees the same thing, but as we are developing |
* add includes for constructor argument * add support to array for function call * add function interface * convert to nodeObjects function call parameters and includes * add fn * add materialx noise functions example * adjust scale to better visual
* add includes for constructor argument * add support to array for function call * add function interface * convert to nodeObjects function call parameters and includes * add fn * add materialx noise functions example * adjust scale to better visual
Related issue: #20541
Description
This is an early part of the implementation.
NodeMaterial
functional interface
toGLSLNodeFunction
.nodeObjects
function call parameters and includesShaderNode
fn
method to create function using backend shader language. commitExample
webgl_nodes_materialx_noise
commithttps://raw.githack.com/sunag/three.js/dev-materialx-functions-lib/examples/webgl_nodes_materialx_noise.html
This contribution is funded by Google via Igalia