diff --git a/javascript/MaterialXView/index.ejs b/javascript/MaterialXView/index.ejs index 3d898899c2..8f278051af 100644 --- a/javascript/MaterialXView/index.ejs +++ b/javascript/MaterialXView/index.ejs @@ -19,6 +19,13 @@ .peditorfolder { background-color: #333333; } + + .peditor_material_assigned { + background-color: #006cb8; + } + .peditor_material_assigned:hover { + background-color: #32adff; + } diff --git a/javascript/MaterialXView/public/shader_ball.svg b/javascript/MaterialXView/public/shader_ball.svg new file mode 100644 index 0000000000..2b51705a42 --- /dev/null +++ b/javascript/MaterialXView/public/shader_ball.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/javascript/MaterialXView/public/shader_ball2.svg b/javascript/MaterialXView/public/shader_ball2.svg new file mode 100644 index 0000000000..62907b5df8 --- /dev/null +++ b/javascript/MaterialXView/public/shader_ball2.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/javascript/MaterialXView/source/index.js b/javascript/MaterialXView/source/index.js index ddd1ec8ffc..d11ba9691e 100644 --- a/javascript/MaterialXView/source/index.js +++ b/javascript/MaterialXView/source/index.js @@ -62,6 +62,13 @@ function init() // Set up renderer renderer = new THREE.WebGLRenderer({ canvas, context }); renderer.setSize(window.innerWidth, window.innerHeight); + // Disable introspection for shader debugging for deployment. + // - The code associated with getting program information can be very slow when + // dealing with shaders with lots of input uniforms (such as standard surface, openpbr shading models) + // as each call is blocking. + // - Adding this avoids the chess set scene from "hanging" the Chrome browser on Windows to a few second load. + // - Documentation for this flag: https://threejs.org/docs/index.html#api/en/renderers/WebGLRenderer.debug + renderer.debug.checkShaderErrors = false; composer = new EffectComposer(renderer); const renderPass = new RenderPass(scene.getScene(), scene.getCamera()); diff --git a/javascript/MaterialXView/source/viewer.js b/javascript/MaterialXView/source/viewer.js index 50e51b67c0..9992dd6985 100644 --- a/javascript/MaterialXView/source/viewer.js +++ b/javascript/MaterialXView/source/viewer.js @@ -111,7 +111,8 @@ export class Scene console.log("Total geometry load time: ", performance.now() - startTime, " ms."); - viewer.getMaterial().updateMaterialAssignments(viewer); + viewer.getMaterial().clearSoloMaterialUI(); + viewer.getMaterial().updateMaterialAssignments(viewer, ""); this.setUpdateTransforms(); } @@ -303,13 +304,16 @@ export class Scene } else { - const paths = geometry.split(','); - for (let path of paths) + if (geometry != NO_GEOMETRY_SPECIFIER) { - if (dagPath.match(path)) + const paths = geometry.split(','); + for (let path of paths) { - matches = true; - break; + if (dagPath.match(path)) + { + matches = true; + break; + } } } } @@ -460,6 +464,17 @@ class MaterialAssign this._geometry = geometry; this._collection = collection; this._shader = null; + this._materialUI = null; + } + + setMaterialUI(value) + { + this._materialUI = value; + } + + getMaterialUI() + { + return this._materialUI; } setShader(shader) @@ -482,6 +497,11 @@ class MaterialAssign return this._geometry; } + setGeometry(value) + { + this._geometry = value; + } + getCollection() { return this._collection; @@ -506,19 +526,44 @@ export class Material { this._materials = []; this._defaultMaterial = null; + this._soloMaterial = ""; + } + + clearMaterials() + { + this._materials.length = 0; + this._defaultMaterial = null; + this._soloMaterial = ""; + } + + setSoloMaterial(value) + { + this._soloMaterial = value; + } + + getSoloMaterial() + { + return this._soloMaterial; } // If no material file is selected, we programmatically create a default material as a fallback static createFallbackMaterial(doc) { - const ssName = 'SR_default'; - const ssNode = doc.addChildOfCategory('standard_surface', ssName); + let ssNode = doc.getChild('Generated_Default_Shader'); + if (ssNode) + { + return ssNode; + } + const ssName = 'Generated_Default_Shader'; + ssNode = doc.addChildOfCategory('standard_surface', ssName); ssNode.setType('surfaceshader'); const smNode = doc.addChildOfCategory('surfacematerial', 'Default'); smNode.setType('material'); const shaderElement = smNode.addInput('surfaceshader'); shaderElement.setType('surfaceshader'); shaderElement.setNodeName(ssName); + + return ssNode; } async loadMaterialFile(loader, materialFilename) @@ -565,11 +610,10 @@ export class Material // Check if there are any looks defined in the document // If so then traverse the looks for all material assignments. // Generate code and compile for any associated surface shader - // and assign to the associatged geometry. If there are no looks + // and assign to the associated geometry. If there are no looks // then the first material is found and assignment to all the - // geometry. - this._materials.length = 0; - this._defaultMaterial = null; + // geometry. + this.clearMaterials(); var looks = doc.getLooks(); if (looks.length) { @@ -610,7 +654,7 @@ export class Material } else { - newAssignment = new MaterialAssign(shader, NO_GEOMETRY_SPECIFIER); + newAssignment = new MaterialAssign(shader, NO_GEOMETRY_SPECIFIER, null); } if (newAssignment) @@ -623,14 +667,109 @@ export class Material } else { - // Search for any surface shader. It + // Search for any surface shaders. The first found // is assumed to be assigned to the entire scene // The identifier used is "*" to mean the entire scene. - let elem = mx.findRenderableElement(doc); - if (elem) + const materialNodes = doc.getMaterialNodes(); + let shaderList = []; + let foundRenderable = false; + for (let i=0; i 0) + { + let shaderNodePath = shaderNodes[0].getNamePath() + if (!shaderList.includes(shaderNodePath)) + { + let assignment = NO_GEOMETRY_SPECIFIER; + if (foundRenderable == false) + { + assignment = ALL_GEOMETRY_SPECIFIER; + foundRenderable = true; + } + console.log('-- add shader: ', shaderNodePath); + shaderList.push(shaderNodePath); + this._materials.push(new MaterialAssign(shaderNodes[0], assignment)); + } + } + } } + const nodeGraphs = doc.getNodeGraphs(); + for (let i=0; i 0) + { + continue + } + let outputs = nodeGraph.getOutputs(); + for (let j=0; j" + elem.getNamePath(); + let img = matTitle.getElementsByTagName('img')[0]; + if (img) + { + // Add event listener to icon to call updateSoloMaterial function + img.addEventListener('click', function(event) + { + Material.updateSoloMaterial(viewer, elemPath, materials,event); + }); + } + if (closeUI) { matUI.close(); - } + } const uniformBlocks = Object.values(shader.getStage('pixel').getUniformBlocks()); var uniformToUpdate; const ignoreList = ['u_envRadianceMips', 'u_envRadianceSamples', 'u_alphaThreshold']; @@ -1116,9 +1350,13 @@ export class Material case 'filename': break; case 'string': - uniformToUpdate = material.uniforms[name]; - if (uniformToUpdate && value != null) { - item = currentFolder.add(material.uniforms[name], 'value'); + console.log('String: ', name); + if (value != null) { + var dummy = + { + thevalue: value + } + let item = currentFolder.add(dummy, 'thevalue'); item.name(path); item.disable(true); item.domElement.classList.add('peditoritem'); diff --git a/source/JsMaterialX/JsMaterialXCore/JsNode.cpp b/source/JsMaterialX/JsMaterialXCore/JsNode.cpp index 8878a219f5..fae1bcba5d 100644 --- a/source/JsMaterialX/JsMaterialXCore/JsNode.cpp +++ b/source/JsMaterialX/JsMaterialXCore/JsNode.cpp @@ -57,6 +57,7 @@ EMSCRIPTEN_BINDINGS(node) .function("setNodeDef", &mx::NodeGraph::setNodeDef) .function("getNodeDef", &mx::NodeGraph::getNodeDef) .function("getImplementation", &mx::NodeGraph::getImplementation) + .function("getDownstreamPorts", &mx::NodeGraph::getDownstreamPorts) .function("addInterfaceName", &mx::NodeGraph::addInterfaceName) .function("removeInterfaceName", &mx::NodeGraph::removeInterfaceName) .function("modifyInterfaceName", &mx::NodeGraph::modifyInterfaceName)