@unikia/upe-renderer 0.186.110 → 0.187.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -7
- package/UPSTREAM.md +4 -4
- package/build/three.core.js +853 -277
- package/build/three.module.js +1098 -1280
- package/build/three.tsl.js +41938 -686
- package/build/three.webgpu.js +10604 -49055
- package/build/three.webgpu.nodes.js +9249 -5788
- package/examples/jsm/Addons.js +2 -0
- package/examples/jsm/animation/CCDIKSolver.js +17 -5
- package/examples/jsm/controls/FirstPersonControls.js +1 -1
- package/examples/jsm/controls/OrbitControls.js +27 -14
- package/examples/jsm/csm/CSMShader.js +74 -3
- package/examples/jsm/curves/CurveExtras.js +4 -4
- package/examples/jsm/curves/NURBSCurve.js +14 -0
- package/examples/jsm/exporters/EXRExporter.js +673 -16
- package/examples/jsm/exporters/GLTFExporter.js +4 -4
- package/examples/jsm/exporters/KTX2Exporter.js +1 -1
- package/examples/jsm/exporters/OBJExporter.js +48 -5
- package/examples/jsm/exporters/PLYExporter.js +22 -11
- package/examples/jsm/generators/CityGenerator.js +3 -2
- package/examples/jsm/generators/city/SkyscraperGenerator.js +63 -21
- package/examples/jsm/gpgpu/BitonicSort.js +30 -23
- package/examples/jsm/helpers/VertexTangentsHelper.js +1 -1
- package/examples/jsm/inspector/Extension.js +1 -1
- package/examples/jsm/inspector/Inspector.js +6 -46
- package/examples/jsm/inspector/RendererInspector.js +43 -8
- package/examples/jsm/inspector/Storage.js +49 -0
- package/examples/jsm/inspector/extensions/color-grading/ColorGrading.js +32 -27
- package/examples/jsm/inspector/tabs/Parameters.js +5 -1
- package/examples/jsm/inspector/tabs/Performance.js +22 -7
- package/examples/jsm/inspector/tabs/Settings.js +1 -1
- package/examples/jsm/inspector/tabs/Timeline.js +83 -7
- package/examples/jsm/inspector/tabs/Viewer.js +25 -10
- package/examples/jsm/inspector/ui/Profiler.js +1 -1
- package/examples/jsm/inspector/ui/Style.js +21 -53
- package/examples/jsm/inspector/ui/Values.js +28 -3
- package/examples/jsm/libs/fflate.module.js +83 -56
- package/examples/jsm/libs/mikktspace.README.md +27 -0
- package/examples/jsm/libs/mikktspace.module.js +721 -109
- package/examples/jsm/lighting/ClusteredLighting.js +100 -2
- package/examples/jsm/lighting/LightMapper.js +295 -0
- package/examples/jsm/lighting/LightProbeGrid.js +242 -139
- package/examples/jsm/lighting/LightProbeGridWebGL.js +30 -14
- package/examples/jsm/lighting/vxgi/VXGIConeTracer.js +54 -5
- package/examples/jsm/lighting/vxgi/VXGIIrradiance.js +43 -0
- package/examples/jsm/lighting/vxgi/VXGINode.js +13 -56
- package/examples/jsm/lighting/vxgi/VXGISceneCollector.js +316 -1
- package/examples/jsm/lighting/vxgi/VXGIVolume.js +69 -59
- package/examples/jsm/lights/SunLight.js +9 -4
- package/examples/jsm/lights/SunLightNode.js +3 -3
- package/examples/jsm/lines/LineMaterial.js +26 -10
- package/examples/jsm/loaders/3DMLoader.js +10 -1
- package/examples/jsm/loaders/3MFLoader.js +5 -1
- package/examples/jsm/loaders/AMFLoader.js +2 -0
- package/examples/jsm/loaders/BVHLoader.js +2 -0
- package/examples/jsm/loaders/ColladaLoader.js +8 -0
- package/examples/jsm/loaders/DDSLoader.js +1 -1
- package/examples/jsm/loaders/DRACOLoader.js +5 -1
- package/examples/jsm/loaders/EXRLoader.js +120 -104
- package/examples/jsm/loaders/FBXLoader.js +4 -0
- package/examples/jsm/loaders/FontLoader.js +2 -0
- package/examples/jsm/loaders/GCodeLoader.js +5 -9
- package/examples/jsm/loaders/GLTFLoader.js +112 -31
- package/examples/jsm/loaders/GaussianSplatPLYLoader.js +2 -0
- package/examples/jsm/loaders/HDRCubeTextureLoader.js +3 -0
- package/examples/jsm/loaders/IESLoader.js +46 -12
- package/examples/jsm/loaders/JXLLoader.js +159 -0
- package/examples/jsm/loaders/KMZLoader.js +6 -0
- package/examples/jsm/loaders/KSPLATLoader.js +2 -0
- package/examples/jsm/loaders/KTX2Loader.js +49 -4
- package/examples/jsm/loaders/KTXLoader.js +5 -3
- package/examples/jsm/loaders/LDrawLoader.js +15 -22
- package/examples/jsm/loaders/LUT3dlLoader.js +5 -1
- package/examples/jsm/loaders/LUTCubeLoader.js +6 -2
- package/examples/jsm/loaders/LUTImageLoader.js +2 -0
- package/examples/jsm/loaders/LWOLoader.js +6 -0
- package/examples/jsm/loaders/MD2Loader.js +2 -0
- package/examples/jsm/loaders/MDDLoader.js +4 -0
- package/examples/jsm/loaders/MTLLoader.js +8 -0
- package/examples/jsm/loaders/MaterialXLoader.js +57 -5
- package/examples/jsm/loaders/NRRDLoader.js +4 -2
- package/examples/jsm/loaders/OBJLoader.js +10 -4
- package/examples/jsm/loaders/PCDLoader.js +6 -2
- package/examples/jsm/loaders/PDBLoader.js +5 -3
- package/examples/jsm/loaders/PLYLoader.js +39 -15
- package/examples/jsm/loaders/PVRLoader.js +2 -2
- package/examples/jsm/loaders/SPLATLoader.js +2 -0
- package/examples/jsm/loaders/SPZLoader.js +2 -0
- package/examples/jsm/loaders/STLLoader.js +3 -1
- package/examples/jsm/loaders/SVGLoader.js +27 -49
- package/examples/jsm/loaders/TDSLoader.js +4 -0
- package/examples/jsm/loaders/TGALoader.js +6 -5
- package/examples/jsm/loaders/TTFLoader.js +2 -0
- package/examples/jsm/loaders/USDLoader.js +14 -0
- package/examples/jsm/loaders/UltraHDRLoader.js +2 -0
- package/examples/jsm/loaders/VOXLoader.js +3 -0
- package/examples/jsm/loaders/VRMLLoader.js +4 -0
- package/examples/jsm/loaders/VTKLoader.js +2 -0
- package/examples/jsm/loaders/XYZLoader.js +2 -0
- package/examples/jsm/loaders/collada/ColladaComposer.js +15 -8
- package/examples/jsm/loaders/materialx/MaterialXDocument.js +610 -138
- package/examples/jsm/loaders/materialx/MaterialXInterfaceValidation.js +12 -95
- package/examples/jsm/loaders/materialx/MaterialXLog.js +4 -0
- package/examples/jsm/loaders/materialx/MaterialXNodeDefs.js +99 -0
- package/examples/jsm/loaders/materialx/MaterialXNodeInterfaceRegistry.js +760 -1
- package/examples/jsm/loaders/materialx/MaterialXNodeLibrary.js +222 -372
- package/examples/jsm/loaders/materialx/MaterialXSurfaceMappings.js +163 -259
- package/examples/jsm/loaders/materialx/MaterialXUtils.js +25 -0
- package/examples/jsm/loaders/materialx/compile/MaterialXCompileRegistry.js +161 -159
- package/examples/jsm/loaders/usd/USDAParser.js +56 -47
- package/examples/jsm/loaders/usd/USDComposer.js +25 -30
- package/examples/jsm/math/ColorConverter.js +7 -3
- package/examples/jsm/math/Lut.js +2 -2
- package/examples/jsm/math/OBB.js +3 -3
- package/examples/jsm/math/Octree.js +20 -17
- package/examples/jsm/objects/GaussianSplat.js +5 -4
- package/examples/jsm/objects/Reflector.js +5 -0
- package/examples/jsm/objects/SkyMesh.js +14 -7
- package/examples/jsm/objects/Water2Mesh.js +2 -2
- package/examples/jsm/physics/RapierPhysics.js +2 -2
- package/examples/jsm/pipelines/MeshletDrawingPipeline.js +5571 -0
- package/examples/jsm/pipelines/VisibilityBufferDrawingPipeline.js +954 -0
- package/examples/jsm/postprocessing/BokehPass.js +1 -1
- package/examples/jsm/postprocessing/GTAOPass.js +26 -18
- package/examples/jsm/renderers/SVGRenderer.js +3 -2
- package/examples/jsm/shaders/GTAOShader.js +7 -4
- package/examples/jsm/shaders/PoissonDenoiseShader.js +1 -10
- package/examples/jsm/tsl/WebGLNodesHandler.js +21 -9
- package/examples/jsm/tsl/display/AfterImageNode.js +3 -3
- package/examples/jsm/tsl/display/BilateralBlurNode.js +3 -3
- package/examples/jsm/tsl/display/BloomNode.js +3 -3
- package/examples/jsm/tsl/display/ChromaticAberrationNode.js +8 -19
- package/examples/jsm/tsl/display/DenoiseNode.js +5 -5
- package/examples/jsm/tsl/display/DepthOfFieldNode.js +3 -3
- package/examples/jsm/tsl/display/DotScreenNode.js +3 -3
- package/examples/jsm/tsl/display/FSR1Node.js +3 -3
- package/examples/jsm/tsl/display/FXAANode.js +3 -10
- package/examples/jsm/tsl/display/FilmNode.js +3 -3
- package/examples/jsm/tsl/display/GTAONode.js +33 -25
- package/examples/jsm/tsl/display/GaussianBlurNode.js +3 -3
- package/examples/jsm/tsl/display/GodraysNode.js +5 -19
- package/examples/jsm/tsl/display/ImportanceSampledEnvironment.js +8 -4
- package/examples/jsm/tsl/display/LensflareNode.js +3 -3
- package/examples/jsm/tsl/display/Lut3DNode.js +3 -3
- package/examples/jsm/tsl/display/OITPassNode.js +0 -11
- package/examples/jsm/tsl/display/OutlineNode.js +107 -5
- package/examples/jsm/tsl/display/PixelationPassNode.js +85 -193
- package/examples/jsm/tsl/display/RGBShiftNode.js +3 -3
- package/examples/jsm/tsl/display/RecurrentDenoiseNode.js +23 -126
- package/examples/jsm/tsl/display/SMAANode.js +3 -3
- package/examples/jsm/tsl/display/SSAONode.js +6 -20
- package/examples/jsm/tsl/display/SSGINode.js +36 -29
- package/examples/jsm/tsl/display/SSRNode.js +135 -63
- package/examples/jsm/tsl/display/SSSNode.js +6 -20
- package/examples/jsm/tsl/display/SharpenNode.js +3 -3
- package/examples/jsm/tsl/display/SobelOperatorNode.js +3 -3
- package/examples/jsm/tsl/display/TAAUNode.js +10 -42
- package/examples/jsm/tsl/display/TRAANode.js +11 -43
- package/examples/jsm/tsl/display/TemporalReprojectNode.js +42 -47
- package/examples/jsm/tsl/display/TransitionNode.js +3 -3
- package/examples/jsm/tsl/display/lensDirt.js +30 -0
- package/examples/jsm/tsl/lighting/ClusteredLightsNode.js +482 -121
- package/examples/jsm/tsl/lighting/DynamicLightsNode.js +41 -140
- package/examples/jsm/tsl/lighting/LightProbeGridNode.js +72 -25
- package/examples/jsm/tsl/lighting/data/AmbientLightDataNode.js +6 -0
- package/examples/jsm/tsl/lighting/data/DirectionalLightDataNode.js +6 -0
- package/examples/jsm/tsl/lighting/data/HemisphereLightDataNode.js +6 -0
- package/examples/jsm/tsl/lighting/data/PointLightDataNode.js +6 -0
- package/examples/jsm/tsl/lighting/data/SpotLightDataNode.js +6 -0
- package/examples/jsm/tsl/shadows/TileShadowNode.js +102 -14
- package/examples/jsm/tsl/utils/Raymarching.js +1 -1
- package/examples/jsm/tsl/utils/SoftParticles.js +5 -12
- package/examples/jsm/tsl/utils/SpecularHelpers.js +47 -70
- package/examples/jsm/tsl/utils/TAAUtils.js +6 -17
- package/examples/jsm/utils/BufferGeometryUtils.js +110 -88
- package/examples/jsm/utils/MeshletGeometryUtils.js +417 -0
- package/examples/jsm/utils/SceneOptimizer.js +2 -1
- package/examples/jsm/utils/SceneUtils.js +1 -1
- package/examples/jsm/utils/unwrapUVs.js +865 -0
- package/examples/jsm/webxr/XREstimatedLight.js +11 -4
- package/package.json +3 -3
- package/src/Three.TSL.js +2 -683
- package/src/Three.WebGPU.Nodes.js +2 -1
- package/src/Three.WebGPU.js +2 -1
- package/src/animation/AnimationAction.js +1 -1
- package/src/animation/AnimationUtils.js +1 -3
- package/src/animation/KeyframeTrack.js +19 -0
- package/src/cameras/ArrayCamera.js +12 -0
- package/src/cameras/CubeCamera.js +3 -3
- package/src/constants.js +1 -9
- package/src/core/BufferAttribute.js +57 -21
- package/src/core/BufferGeometry.js +5 -13
- package/src/core/Clock.js +1 -1
- package/src/core/InterleavedBuffer.js +28 -18
- package/src/core/InterleavedBufferAttribute.js +54 -20
- package/src/core/Object3D.js +19 -9
- package/src/core/Raycaster.js +2 -0
- package/src/core/RenderTarget.js +11 -5
- package/src/core/UniformsGroup.js +7 -3
- package/src/extras/PMREMGenerator.js +392 -685
- package/src/extras/core/Curve.js +4 -0
- package/src/extras/core/CurvePath.js +13 -0
- package/src/extras/core/ShapePath.js +1 -1
- package/src/geometries/EdgesGeometry.js +12 -10
- package/src/geometries/LatheGeometry.js +2 -0
- package/src/helpers/PolarGridHelper.js +1 -1
- package/src/lights/Light.js +11 -0
- package/src/lights/LightProbe.js +2 -0
- package/src/lights/LightShadow.js +2 -0
- package/src/loaders/AnimationLoader.js +2 -0
- package/src/loaders/AudioLoader.js +2 -0
- package/src/loaders/BufferGeometryLoader.js +2 -0
- package/src/loaders/CompressedTextureLoader.js +2 -0
- package/src/loaders/CubeTextureLoader.js +2 -0
- package/src/loaders/DataTextureLoader.js +2 -0
- package/src/loaders/FileLoader.js +2 -0
- package/src/loaders/ImageBitmapLoader.js +3 -1
- package/src/loaders/ImageLoader.js +1 -0
- package/src/loaders/Loader.js +47 -0
- package/src/loaders/MaterialLoader.js +2 -0
- package/src/loaders/ObjectLoader.js +27 -8
- package/src/loaders/TextureLoader.js +5 -3
- package/src/loaders/nodes/NodeLoader.js +2 -0
- package/src/materials/Material.js +21 -2
- package/src/materials/MeshDepthMaterial.js +1 -1
- package/src/materials/MeshDistanceMaterial.js +1 -1
- package/src/materials/MeshLambertMaterial.js +1 -1
- package/src/materials/MeshMatcapMaterial.js +1 -1
- package/src/materials/MeshNormalMaterial.js +1 -1
- package/src/materials/MeshPhongMaterial.js +1 -1
- package/src/materials/MeshPhysicalMaterial.js +90 -11
- package/src/materials/MeshStandardMaterial.js +1 -1
- package/src/materials/MeshToonMaterial.js +1 -1
- package/src/materials/nodes/Line2NodeMaterial.js +32 -10
- package/src/materials/nodes/MeshLambertNodeMaterial.js +13 -0
- package/src/materials/nodes/MeshPhongNodeMaterial.js +13 -0
- package/src/materials/nodes/MeshPhysicalNodeMaterial.js +40 -5
- package/src/materials/nodes/MeshToonNodeMaterial.js +13 -0
- package/src/materials/nodes/NodeMaterial.js +36 -16
- package/src/materials/nodes/NodeMaterialInstance.js +193 -0
- package/src/materials/nodes/NodeMaterials.js +1 -0
- package/src/materials/nodes/PointsNodeMaterial.js +1 -1
- package/src/materials/nodes/SpriteNodeMaterial.js +3 -3
- package/src/materials/nodes/manager/NodeMaterialObserver.js +191 -22
- package/src/math/Box3.js +2 -2
- package/src/math/Color.js +8 -8
- package/src/math/ColorManagement.js +2 -21
- package/src/math/FrustumArray.js +12 -0
- package/src/math/Interpolant.js +1 -1
- package/src/math/Line3.js +2 -4
- package/src/math/MathUtils.js +33 -46
- package/src/math/Matrix2.js +1 -1
- package/src/math/Matrix3.js +1 -1
- package/src/math/Matrix4.js +1 -1
- package/src/math/Triangle.js +2 -1
- package/src/math/Vector2.js +1 -1
- package/src/math/Vector3.js +1 -1
- package/src/math/Vector4.js +1 -1
- package/src/nodes/Nodes.js +1 -0
- package/src/nodes/TSL.js +2 -0
- package/src/nodes/accessors/Arrays.js +1 -1
- package/src/nodes/accessors/Batch.js +29 -23
- package/src/nodes/accessors/BufferAttributeNode.js +21 -1
- package/src/nodes/accessors/BuiltinNode.js +6 -0
- package/src/nodes/accessors/Camera.js +100 -93
- package/src/nodes/accessors/ClippingNode.js +17 -6
- package/src/nodes/accessors/CubeTextureNode.js +12 -24
- package/src/nodes/accessors/Instance.js +198 -160
- package/src/nodes/accessors/Lights.js +19 -6
- package/src/nodes/accessors/MaterialNode.js +33 -4
- package/src/nodes/accessors/Morph.js +81 -22
- package/src/nodes/accessors/Normal.js +0 -42
- package/src/nodes/accessors/Object3DNode.js +6 -0
- package/src/nodes/accessors/PointUVNode.js +6 -0
- package/src/nodes/accessors/ReferenceAttributeNode.js +279 -0
- package/src/nodes/accessors/ReferenceBaseNode.js +6 -0
- package/src/nodes/accessors/ReferenceNode.js +6 -0
- package/src/nodes/accessors/Skinning.js +57 -52
- package/src/nodes/accessors/StorageBufferNode.js +3 -12
- package/src/nodes/accessors/TextureBicubic.js +30 -27
- package/src/nodes/accessors/TextureNode.js +164 -78
- package/src/nodes/accessors/TextureSizeNode.js +6 -0
- package/src/nodes/accessors/UniformArrayNode.js +8 -15
- package/src/nodes/accessors/VelocityNode.js +13 -8
- package/src/nodes/code/CodeNode.js +6 -0
- package/src/nodes/code/ExpressionNode.js +6 -0
- package/src/nodes/code/FunctionCallNode.js +3 -3
- package/src/nodes/code/FunctionNode.js +15 -13
- package/src/nodes/core/ArrayNode.js +3 -3
- package/src/nodes/core/AssignNode.js +10 -9
- package/src/nodes/core/AttributeNode.js +39 -0
- package/src/nodes/core/BypassNode.js +6 -0
- package/src/nodes/core/ConstNode.js +31 -1
- package/src/nodes/core/ContextNode.js +11 -6
- package/src/nodes/core/IndexNode.js +6 -0
- package/src/nodes/core/InputNode.js +6 -0
- package/src/nodes/core/InspectorNode.js +17 -31
- package/src/nodes/core/IsolateNode.js +8 -0
- package/src/nodes/core/Node.js +367 -67
- package/src/nodes/core/NodeBuilder.js +664 -222
- package/src/nodes/core/NodeUtils.js +25 -0
- package/src/nodes/core/NodeVar.js +10 -1
- package/src/nodes/core/OutputStructNode.js +6 -0
- package/src/nodes/core/OverrideContextNode.js +38 -37
- package/src/nodes/core/PropertyNode.js +14 -0
- package/src/nodes/core/StackNode.js +33 -21
- package/src/nodes/core/StructNode.js +6 -0
- package/src/nodes/core/StructTypeNode.js +6 -0
- package/src/nodes/core/SubBuildNode.js +8 -0
- package/src/nodes/core/TempNode.js +10 -35
- package/src/nodes/core/UniformGroupNode.js +6 -0
- package/src/nodes/core/VarNode.js +43 -135
- package/src/nodes/core/VaryingNode.js +33 -2
- package/src/nodes/display/BlendModes.js +5 -40
- package/src/nodes/display/BumpMapNode.js +17 -7
- package/src/nodes/display/ColorAdjustment.js +22 -10
- package/src/nodes/display/ColorSpaceFunctions.js +2 -14
- package/src/nodes/display/ColorSpaceNode.js +3 -3
- package/src/nodes/display/FrontFacingNode.js +6 -0
- package/src/nodes/display/NormalMapNode.js +3 -3
- package/src/nodes/display/PassNode.js +75 -16
- package/src/nodes/display/RenderOutputNode.js +22 -5
- package/src/nodes/display/ScreenNode.js +6 -0
- package/src/nodes/display/ToneMappingFunctions.js +9 -51
- package/src/nodes/display/ToneMappingNode.js +3 -3
- package/src/nodes/display/ToonOutlinePassNode.js +66 -2
- package/src/nodes/display/ViewportDepthNode.js +34 -4
- package/src/nodes/functions/BSDF/BRDF_EON.js +65 -0
- package/src/nodes/functions/BSDF/BRDF_GGX.js +5 -3
- package/src/nodes/functions/BSDF/BRDF_Sheen.js +2 -16
- package/src/nodes/functions/BSDF/D_GGX.js +1 -8
- package/src/nodes/functions/BSDF/D_GGX_Anisotropic.js +7 -10
- package/src/nodes/functions/BSDF/LTC.js +20 -47
- package/src/nodes/functions/BSDF/Schlick_to_F0.js +1 -9
- package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.js +1 -9
- package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +10 -13
- package/src/nodes/functions/PhysicalLightingModel.js +84 -51
- package/src/nodes/functions/VolumetricLightingModel.js +1 -1
- package/src/nodes/functions/material/getAlphaHashThreshold.js +3 -9
- package/src/nodes/functions/material/getParallaxCorrectNormal.js +10 -11
- package/src/nodes/functions/material/getRoughness.js +3 -1
- package/src/nodes/geometry/RangeNode.js +52 -69
- package/src/nodes/gpgpu/AtomicFunctionNode.js +11 -6
- package/src/nodes/gpgpu/BarrierNode.js +6 -0
- package/src/nodes/gpgpu/ComputeBuiltinNode.js +6 -0
- package/src/nodes/gpgpu/ComputeNode.js +6 -0
- package/src/nodes/gpgpu/SubgroupFunctionNode.js +38 -29
- package/src/nodes/gpgpu/WorkgroupInfoNode.js +6 -0
- package/src/nodes/lighting/AnalyticLightNode.js +7 -14
- package/src/nodes/lighting/BasicEnvironmentNode.js +5 -1
- package/src/nodes/lighting/EnvironmentNode.js +58 -8
- package/src/nodes/lighting/IESSpotLightNode.js +19 -4
- package/src/nodes/lighting/LightProbeNode.js +2 -1
- package/src/nodes/lighting/LightUtils.js +2 -2
- package/src/nodes/lighting/LightingNode.js +6 -0
- package/src/nodes/lighting/LightsNode.js +26 -32
- package/src/nodes/lighting/PointShadowNode.js +92 -48
- package/src/nodes/lighting/ProjectorLightNode.js +1 -1
- package/src/nodes/lighting/RectAreaLightNode.js +13 -14
- package/src/nodes/lighting/ShadowBaseNode.js +9 -17
- package/src/nodes/lighting/ShadowFilterNode.js +26 -3
- package/src/nodes/lighting/ShadowNode.js +13 -11
- package/src/nodes/materialx/MaterialXColor.js +2 -14
- package/src/nodes/materialx/MaterialXColorTransform.js +1 -7
- package/src/nodes/materialx/MaterialXNodes.js +8 -11
- package/src/nodes/materialx/MaterialXNoise.js +195 -454
- package/src/nodes/math/BitcastNode.js +5 -5
- package/src/nodes/math/BitcountNode.js +18 -46
- package/src/nodes/math/ConditionalNode.js +92 -22
- package/src/nodes/math/Hash.js +1 -1
- package/src/nodes/math/MathNode.js +86 -64
- package/src/nodes/math/MathUtils.js +2 -2
- package/src/nodes/math/OperatorNode.js +42 -59
- package/src/nodes/math/PackFloatNode.js +9 -9
- package/src/nodes/math/Packed4x8IntegerNode.js +20 -52
- package/src/nodes/math/TriNoise3D.js +3 -23
- package/src/nodes/math/UnpackFloatNode.js +9 -9
- package/src/nodes/pmrem/PMREMNode.js +38 -75
- package/src/nodes/pmrem/PMREMUtils.js +108 -272
- package/src/nodes/procedural/Checker.js +1 -1
- package/src/nodes/tsl/TSLCore.js +199 -74
- package/src/nodes/utils/ArrayElementNode.js +19 -1
- package/src/nodes/utils/CubeMapNode.js +3 -3
- package/src/nodes/utils/DebugNode.js +2 -2
- package/src/nodes/utils/EventNode.js +6 -0
- package/src/nodes/utils/FlipNode.js +3 -3
- package/src/nodes/utils/FunctionOverloadingNode.js +7 -1
- package/src/nodes/utils/JoinNode.js +3 -3
- package/src/nodes/utils/LoopNode.js +14 -9
- package/src/nodes/utils/MemberNode.js +18 -0
- package/src/nodes/utils/PostProcessingUtils.js +20 -25
- package/src/nodes/utils/RTTNode.js +2 -0
- package/src/nodes/utils/ReflectorNode.js +24 -0
- package/src/nodes/utils/RotateNode.js +3 -3
- package/src/nodes/utils/SampleNode.js +6 -0
- package/src/nodes/utils/SetNode.js +3 -3
- package/src/nodes/utils/SplitNode.js +6 -0
- package/src/nodes/utils/UVUtils.js +2 -2
- package/src/objects/BatchedMesh.js +146 -15
- package/src/objects/InstancedMesh.js +12 -4
- package/src/objects/Line.js +20 -0
- package/src/objects/Mesh.js +8 -0
- package/src/objects/Points.js +20 -0
- package/src/objects/Skeleton.js +26 -0
- package/src/objects/SkinnedMesh.js +3 -3
- package/src/objects/Sprite.js +10 -0
- package/src/renderers/WebGLRenderer.js +104 -70
- package/src/renderers/common/Animation.js +5 -1
- package/src/renderers/common/Attributes.js +67 -57
- package/src/renderers/common/Backend.js +78 -3
- package/src/renderers/common/BindGroup.js +11 -0
- package/src/renderers/common/Binding.js +0 -11
- package/src/renderers/common/Bindings.js +116 -10
- package/src/renderers/common/Buffer.js +1 -1
- package/src/renderers/common/ClippingContext.js +12 -1
- package/src/renderers/common/ComputePipeline.js +17 -1
- package/src/renderers/common/DirectRenderPipeline.js +7 -3
- package/src/renderers/common/Geometries.js +170 -132
- package/src/renderers/common/Info.js +1 -1
- package/src/renderers/common/InspectorBase.js +5 -5
- package/src/renderers/common/Lighting.js +59 -0
- package/src/renderers/common/Pipelines.js +26 -12
- package/src/renderers/common/ProgrammableStage.js +1 -17
- package/src/renderers/common/RenderContext.js +21 -0
- package/src/renderers/common/RenderContexts.js +13 -4
- package/src/renderers/common/RenderObject.js +111 -35
- package/src/renderers/common/RenderObjects.js +37 -19
- package/src/renderers/common/Renderer.js +537 -295
- package/src/renderers/common/RendererUtils.js +15 -0
- package/src/renderers/common/StandardDrawingPipeline.js +343 -0
- package/src/renderers/common/Storage3DTexture.js +11 -0
- package/src/renderers/common/StorageArrayTexture.js +10 -0
- package/src/renderers/common/StorageTexture.js +0 -9
- package/src/renderers/common/Textures.js +144 -37
- package/src/renderers/common/UniformsGroup.js +19 -0
- package/src/renderers/common/XRManager.js +10 -91
- package/src/renderers/common/extras/PMREMGenerator.js +298 -576
- package/src/renderers/common/nodes/NodeBuilderState.js +7 -5
- package/src/renderers/common/nodes/NodeLibrary.js +11 -35
- package/src/renderers/common/nodes/NodeManager.js +80 -31
- package/src/renderers/common/nodes/NodeSampledTexture.js +14 -0
- package/src/renderers/common/nodes/NodeSampler.js +14 -0
- package/src/renderers/common/nodes/NodeStorageBuffer.js +1 -1
- package/src/renderers/common/nodes/NodeUniformBuffer.js +1 -14
- package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +13 -4
- package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +8 -8
- package/src/renderers/shaders/ShaderChunk/lightprobes_pars_fragment.glsl.js +23 -11
- package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +21 -2
- package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +18 -2
- package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +104 -7
- package/src/renderers/shaders/ShaderChunk/morphcolor_vertex.glsl.js +11 -2
- package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +36 -20
- package/src/renderers/shaders/ShaderChunk/uv_pars_fragment.glsl.js +5 -0
- package/src/renderers/shaders/ShaderChunk/uv_pars_vertex.glsl.js +6 -0
- package/src/renderers/shaders/ShaderChunk/uv_vertex.glsl.js +5 -0
- package/src/renderers/shaders/ShaderChunk.js +0 -2
- package/src/renderers/shaders/ShaderLib/backgroundCube.glsl.js +4 -18
- package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +0 -1
- package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +0 -1
- package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +8 -1
- package/src/renderers/shaders/ShaderLib.js +3 -0
- package/src/renderers/shaders/UniformsLib.js +4 -5
- package/src/renderers/webgl/WebGLBackground.js +3 -3
- package/src/renderers/webgl/WebGLBindingStates.js +4 -2
- package/src/renderers/webgl/WebGLCapabilities.js +7 -1
- package/src/renderers/webgl/WebGLEnvironments.js +2 -2
- package/src/renderers/webgl/WebGLGeometries.js +42 -14
- package/src/renderers/webgl/WebGLMaterials.js +15 -2
- package/src/renderers/webgl/WebGLOutput.js +37 -1
- package/src/renderers/webgl/WebGLProgram.js +13 -54
- package/src/renderers/webgl/WebGLPrograms.js +22 -8
- package/src/renderers/webgl/WebGLRenderStates.js +11 -8
- package/src/renderers/webgl/WebGLShadowMap.js +6 -4
- package/src/renderers/webgl/WebGLState.js +10 -6
- package/src/renderers/webgl/WebGLTextures.js +129 -77
- package/src/renderers/webgl/WebGLUniforms.js +44 -6
- package/src/renderers/webgl/WebGLUniformsGroups.js +75 -69
- package/src/renderers/webgl-fallback/WebGLBackend.js +206 -278
- package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +154 -20
- package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +45 -42
- package/src/renderers/webgl-fallback/utils/WebGLState.js +29 -4
- package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +129 -49
- package/src/renderers/webgl-fallback/utils/WebGLVertexArrayUtils.js +346 -0
- package/src/renderers/webgpu/WebGPUBackend.js +140 -82
- package/src/renderers/webgpu/WebGPURenderer.js +1 -1
- package/src/renderers/webgpu/nodes/BasicNodeLibrary.js +10 -10
- package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +10 -10
- package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +135 -60
- package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +128 -55
- package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +1 -1
- package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +15 -12
- package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +55 -19
- package/src/renderers/webgpu/utils/WebGPUUtils.js +20 -3
- package/src/renderers/webxr/WebXRController.js +3 -3
- package/src/renderers/webxr/WebXRManager.js +5 -90
- package/src/scenes/Scene.js +4 -4
- package/src/textures/CompressedTexture.js +2 -2
- package/src/textures/DepthTexture.js +2 -2
- package/src/textures/FramebufferTexture.js +11 -0
- package/src/textures/Texture.js +29 -1
- package/src/textures/TextureSource.js +1 -1
- package/src/upe.js +1 -1
- package/src/utils.js +4 -4
- package/examples/jsm/libs/surfaceNet.js +0 -201
- package/src/renderers/shaders/ShaderChunk/cube_uv_reflection_fragment.glsl.js +0 -186
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Texture,
|
|
3
|
-
RepeatWrapping,
|
|
4
|
-
ClampToEdgeWrapping,
|
|
5
|
-
MirroredRepeatWrapping,
|
|
6
3
|
ImageLoader,
|
|
7
4
|
ImageBitmapLoader,
|
|
5
|
+
LoaderUtils,
|
|
8
6
|
Matrix3,
|
|
9
7
|
Matrix4,
|
|
10
8
|
MeshBasicNodeMaterial,
|
|
@@ -13,6 +11,7 @@ import {
|
|
|
13
11
|
|
|
14
12
|
import {
|
|
15
13
|
float,
|
|
14
|
+
texture,
|
|
16
15
|
int,
|
|
17
16
|
bool,
|
|
18
17
|
sub,
|
|
@@ -26,6 +25,14 @@ import {
|
|
|
26
25
|
element,
|
|
27
26
|
mx_transform_uv,
|
|
28
27
|
mx_srgb_texture_to_lin_rec709,
|
|
28
|
+
positionLocal,
|
|
29
|
+
positionWorld,
|
|
30
|
+
normalLocal,
|
|
31
|
+
normalWorld,
|
|
32
|
+
tangentLocal,
|
|
33
|
+
tangentWorld,
|
|
34
|
+
bitangentLocal,
|
|
35
|
+
bitangentWorld,
|
|
29
36
|
} from 'three/tsl';
|
|
30
37
|
|
|
31
38
|
import { MaterialXLogCodes } from './MaterialXLog.js';
|
|
@@ -33,8 +40,9 @@ import { createMaterialXCompileRegistry, compileNodeFromRegistry } from './compi
|
|
|
33
40
|
import { parseMaterialXNodeTree, parseMaterialXText } from './parse/MaterialXParser.js';
|
|
34
41
|
import { getSurfaceMapper } from './MaterialXSurfaceMappings.js';
|
|
35
42
|
import { MtlXLibrary } from './MaterialXNodeLibrary.js';
|
|
43
|
+
import { resolveNodeDef } from './MaterialXNodeDefs.js';
|
|
36
44
|
import { mxHextileCoord, mxHextileComputeBlendWeights } from './MaterialXHextile.js';
|
|
37
|
-
import { toBooleanNode } from './MaterialXUtils.js';
|
|
45
|
+
import { resolveTextureAddressMode, TEXTURE_ADDRESS_MODE_WRAPPING, toBooleanNode } from './MaterialXUtils.js';
|
|
38
46
|
|
|
39
47
|
const colorSpaceLib = {
|
|
40
48
|
mx_srgb_texture_to_lin_rec709,
|
|
@@ -45,12 +53,6 @@ const IDENTITY_MAT3_VALUES = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ];
|
|
|
45
53
|
const IDENTITY_MAT4_VALUES = [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ];
|
|
46
54
|
const MATRIX_INVERSE_EPSILON = 1e-8;
|
|
47
55
|
const COMPILE_REGISTRY = createMaterialXCompileRegistry();
|
|
48
|
-
const TEXTURE_ADDRESS_MODE_WRAPPING = {
|
|
49
|
-
constant: ClampToEdgeWrapping,
|
|
50
|
-
clamp: ClampToEdgeWrapping,
|
|
51
|
-
periodic: RepeatWrapping,
|
|
52
|
-
mirror: MirroredRepeatWrapping,
|
|
53
|
-
};
|
|
54
56
|
const NODE_CLASS_BY_TYPE = {
|
|
55
57
|
integer: int,
|
|
56
58
|
float,
|
|
@@ -63,6 +65,84 @@ const NODE_CLASS_BY_TYPE = {
|
|
|
63
65
|
matrix33: mat3,
|
|
64
66
|
matrix44: mat4,
|
|
65
67
|
};
|
|
68
|
+
// Geometric properties a nodedef input can default to via `defaultgeomprop`.
|
|
69
|
+
const GEOMPROP_NODES = {
|
|
70
|
+
Pobject: positionLocal,
|
|
71
|
+
Pworld: positionWorld,
|
|
72
|
+
Nobject: normalLocal,
|
|
73
|
+
Nworld: normalWorld,
|
|
74
|
+
Tobject: tangentLocal,
|
|
75
|
+
Tworld: tangentWorld,
|
|
76
|
+
Bobject: bitangentLocal,
|
|
77
|
+
Bworld: bitangentWorld,
|
|
78
|
+
Vworld: MtlXLibrary.viewdirection.nodeFunc( 'world' ),
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
function parseValueVector( value ) {
|
|
82
|
+
|
|
83
|
+
const vector = [];
|
|
84
|
+
for ( const val of value.split( /[,|\s]/ ) ) {
|
|
85
|
+
|
|
86
|
+
if ( val !== '' ) vector.push( Number( val.trim() ) );
|
|
87
|
+
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return vector;
|
|
91
|
+
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function createMatrixNode( size, vector ) {
|
|
95
|
+
|
|
96
|
+
const expectedLength = size * size;
|
|
97
|
+
if ( vector.length !== expectedLength ) return null;
|
|
98
|
+
|
|
99
|
+
// MaterialX matrix values are serialized in column-major order.
|
|
100
|
+
// Reorder to row-major before constructing TSL matrix nodes so
|
|
101
|
+
// transformmatrix semantics match MaterialXJS and MaterialXView.
|
|
102
|
+
const reordered = [];
|
|
103
|
+
for ( let row = 0; row < size; row += 1 ) {
|
|
104
|
+
|
|
105
|
+
for ( let column = 0; column < size; column += 1 ) {
|
|
106
|
+
|
|
107
|
+
reordered.push( vector[ column * size + row ] );
|
|
108
|
+
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return size === 3 ? mat3( ...reordered ) : mat4( ...reordered );
|
|
114
|
+
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Empty strings are valid string defaults, but an empty filename means "no texture".
|
|
118
|
+
function hasDefaultValue( input ) {
|
|
119
|
+
|
|
120
|
+
if ( input.value === undefined ) return false;
|
|
121
|
+
return input.value !== '' || input.type === 'string';
|
|
122
|
+
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// string values stay strings so the compiler can read e.g. space names
|
|
126
|
+
function createValueNode( type, value ) {
|
|
127
|
+
|
|
128
|
+
const trimmed = value.trim();
|
|
129
|
+
|
|
130
|
+
if ( type === 'boolean' ) {
|
|
131
|
+
|
|
132
|
+
const normalized = trimmed.toLowerCase();
|
|
133
|
+
return bool( normalized === 'true' || normalized === '1' );
|
|
134
|
+
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if ( type === 'matrix33' ) return createMatrixNode( 3, parseValueVector( trimmed ) ) || mat3( ...IDENTITY_MAT3_VALUES );
|
|
138
|
+
if ( type === 'matrix44' ) return createMatrixNode( 4, parseValueVector( trimmed ) ) || mat4( ...IDENTITY_MAT4_VALUES );
|
|
139
|
+
if ( type === 'string' || type === 'filename' ) return trimmed;
|
|
140
|
+
|
|
141
|
+
const nodeClass = NODE_CLASS_BY_TYPE[ type ];
|
|
142
|
+
return nodeClass ? nodeClass( ...parseValueVector( trimmed ) ) : float( 0 );
|
|
143
|
+
|
|
144
|
+
}
|
|
145
|
+
|
|
66
146
|
const OUTPUT_CHANNELS = {
|
|
67
147
|
outx: 0,
|
|
68
148
|
outr: 0,
|
|
@@ -111,15 +191,6 @@ function isSvgUri( uri ) {
|
|
|
111
191
|
|
|
112
192
|
}
|
|
113
193
|
|
|
114
|
-
function normalizeTextureAddressMode( value ) {
|
|
115
|
-
|
|
116
|
-
if ( value === null || value === undefined || value === '' ) return 'periodic';
|
|
117
|
-
|
|
118
|
-
const mode = value.trim().toLowerCase();
|
|
119
|
-
return mode in TEXTURE_ADDRESS_MODE_WRAPPING ? mode : null;
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
|
|
123
194
|
function invertConstantMatrixValues( values, size ) {
|
|
124
195
|
|
|
125
196
|
if ( ! Array.isArray( values ) || values.length !== size * size ) return null;
|
|
@@ -170,6 +241,7 @@ class MaterialXNode {
|
|
|
170
241
|
this.parent = null;
|
|
171
242
|
this.node = null;
|
|
172
243
|
this.children = [];
|
|
244
|
+
this._nodeDef = undefined;
|
|
173
245
|
|
|
174
246
|
}
|
|
175
247
|
|
|
@@ -273,6 +345,19 @@ class MaterialXNode {
|
|
|
273
345
|
|
|
274
346
|
return this.referencePath !== null;
|
|
275
347
|
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
getReferencedNode() {
|
|
351
|
+
|
|
352
|
+
if ( this.nodeGraph !== null ) {
|
|
353
|
+
|
|
354
|
+
const graph = this.materialX.getMaterialXNode( this.nodeGraph );
|
|
355
|
+
return graph ? this.output !== null ? graph.getChildByName( this.output ) || null : graph.children.find( ( child ) => child.element === 'output' ) || null : null;
|
|
356
|
+
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
return this.hasReference ? this.materialX.getMaterialXNode( this.referencePath ) || null : null;
|
|
360
|
+
|
|
276
361
|
}
|
|
277
362
|
get isConst() {
|
|
278
363
|
|
|
@@ -280,9 +365,65 @@ class MaterialXNode {
|
|
|
280
365
|
|
|
281
366
|
}
|
|
282
367
|
|
|
368
|
+
/**
|
|
369
|
+
* The stdlib or document nodedef this node instance resolves to, or `null` when the category is unknown.
|
|
370
|
+
*
|
|
371
|
+
* @type {?Object}
|
|
372
|
+
*/
|
|
373
|
+
get nodeDef() {
|
|
374
|
+
|
|
375
|
+
if ( this._nodeDef === undefined ) this._nodeDef = resolveNodeDef( this );
|
|
376
|
+
return this._nodeDef;
|
|
377
|
+
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
hasDeclaredOutput( name ) {
|
|
381
|
+
|
|
382
|
+
return this.nodeDef !== null && name in this.nodeDef.outputs;
|
|
383
|
+
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// The declared type of a nodedef input, or `null` when the nodedef does not declare it.
|
|
387
|
+
getNodeDefInputType( name ) {
|
|
388
|
+
|
|
389
|
+
const input = this.nodeDef ? this.nodeDef.inputs[ name ] : undefined;
|
|
390
|
+
return input ? input.type : null;
|
|
391
|
+
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// `undefined` when the nodedef declares no default (e.g. filenames)
|
|
395
|
+
getDefaultInputNode( name ) {
|
|
396
|
+
|
|
397
|
+
const input = this.nodeDef ? this.nodeDef.inputs[ name ] : undefined;
|
|
398
|
+
if ( ! input ) return undefined;
|
|
399
|
+
|
|
400
|
+
if ( input.defaultgeomprop ) return this.materialX.compileContext.getGeomPropNode( input.defaultgeomprop );
|
|
401
|
+
if ( ! hasDefaultValue( input ) ) return undefined;
|
|
402
|
+
|
|
403
|
+
return createValueNode( input.type, input.value );
|
|
404
|
+
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// geometric defaults are left out so surface mappers can tell an authored normal from the default
|
|
408
|
+
getDefaultInputNodes() {
|
|
409
|
+
|
|
410
|
+
const nodes = {};
|
|
411
|
+
if ( this.nodeDef === null ) return nodes;
|
|
412
|
+
|
|
413
|
+
for ( const [ name, input ] of Object.entries( this.nodeDef.inputs ) ) {
|
|
414
|
+
|
|
415
|
+
if ( input.defaultgeomprop || ! hasDefaultValue( input ) ) continue;
|
|
416
|
+
nodes[ name ] = createValueNode( input.type, input.value );
|
|
417
|
+
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
return nodes;
|
|
421
|
+
|
|
422
|
+
}
|
|
423
|
+
|
|
283
424
|
getColorSpaceNode() {
|
|
284
425
|
|
|
285
|
-
const csSource = this.getAttribute( 'colorspace' );
|
|
426
|
+
const csSource = this.getValueInput().getAttribute( 'colorspace' ) || this.getAttribute( 'colorspace' );
|
|
286
427
|
const csTarget = this.getRoot().getAttribute( 'colorspace' );
|
|
287
428
|
if ( ! csSource || ! csTarget ) return null;
|
|
288
429
|
const nodeName = `mx_${csSource}_to_${csTarget}`;
|
|
@@ -290,10 +431,23 @@ class MaterialXNode {
|
|
|
290
431
|
|
|
291
432
|
}
|
|
292
433
|
|
|
434
|
+
logUnsupportedNode() {
|
|
435
|
+
|
|
436
|
+
this.materialX.log.add(
|
|
437
|
+
MaterialXLogCodes.UNSUPPORTED_NODE,
|
|
438
|
+
`Unsupported MaterialX node category "${this.element}" on "${this.name}".`,
|
|
439
|
+
this.name,
|
|
440
|
+
);
|
|
441
|
+
|
|
442
|
+
}
|
|
443
|
+
|
|
293
444
|
getTextureAddressMode( inputName ) {
|
|
294
445
|
|
|
295
|
-
|
|
296
|
-
|
|
446
|
+
// e.g. tiledimage, which samples with the image node's default addressing.
|
|
447
|
+
if ( this.declaresInput( inputName ) === false ) return 'periodic';
|
|
448
|
+
|
|
449
|
+
const rawMode = this.getNodeByName( inputName );
|
|
450
|
+
const mode = resolveTextureAddressMode( rawMode );
|
|
297
451
|
if ( mode ) return mode;
|
|
298
452
|
|
|
299
453
|
this.materialX.log.add(
|
|
@@ -314,10 +468,22 @@ class MaterialXNode {
|
|
|
314
468
|
|
|
315
469
|
}
|
|
316
470
|
|
|
471
|
+
// Follow an interfacename binding to its source input.
|
|
472
|
+
getValueInput() {
|
|
473
|
+
|
|
474
|
+
if ( this.interfaceName === null ) return this;
|
|
475
|
+
const boundInput = this.materialX.getInterfaceInput( this );
|
|
476
|
+
return boundInput !== null ? boundInput : this;
|
|
477
|
+
|
|
478
|
+
}
|
|
479
|
+
|
|
317
480
|
getTexture() {
|
|
318
481
|
|
|
319
|
-
const
|
|
320
|
-
|
|
482
|
+
const valueInput = this.getValueInput();
|
|
483
|
+
if ( valueInput.getValue() === '' ) return null;
|
|
484
|
+
|
|
485
|
+
const filePrefix = valueInput.getRecursiveAttribute( 'fileprefix' ) || '';
|
|
486
|
+
const sourceURI = filePrefix + valueInput.value;
|
|
321
487
|
const resolvedURI = this.materialX.resolveTextureURI( sourceURI );
|
|
322
488
|
const svgTexture = isSvgUri( resolvedURI );
|
|
323
489
|
const textureSourceNode = this.parent && typeof this.parent.getTextureAddressModes === 'function' ? this.parent : this;
|
|
@@ -331,29 +497,66 @@ class MaterialXNode {
|
|
|
331
497
|
}
|
|
332
498
|
|
|
333
499
|
let loader = svgTexture ? this.materialX.imageLoader : this.materialX.textureLoader;
|
|
500
|
+
let textureURL = resolvedURI;
|
|
334
501
|
if ( resolvedURI && ! svgTexture ) {
|
|
335
502
|
|
|
336
503
|
const handler = this.materialX.manager.getHandler( resolvedURI );
|
|
337
|
-
if ( handler !== null )
|
|
504
|
+
if ( handler !== null ) {
|
|
505
|
+
|
|
506
|
+
// The built-in loaders carry the document path; handlers do not.
|
|
507
|
+
loader = handler;
|
|
508
|
+
textureURL = LoaderUtils.resolveURL( resolvedURI, this.materialX.path );
|
|
509
|
+
|
|
510
|
+
}
|
|
338
511
|
|
|
339
512
|
}
|
|
340
513
|
|
|
341
|
-
const textureNode = new Texture();
|
|
342
|
-
textureNode.wrapS = TEXTURE_ADDRESS_MODE_WRAPPING[ addressModes.u ];
|
|
343
|
-
textureNode.wrapT = TEXTURE_ADDRESS_MODE_WRAPPING[ addressModes.v ];
|
|
344
|
-
textureNode.flipY = false;
|
|
514
|
+
const textureNode = texture( new Texture() );
|
|
515
|
+
textureNode.value.wrapS = TEXTURE_ADDRESS_MODE_WRAPPING[ addressModes.u ];
|
|
516
|
+
textureNode.value.wrapT = TEXTURE_ADDRESS_MODE_WRAPPING[ addressModes.v ];
|
|
517
|
+
textureNode.value.flipY = false;
|
|
345
518
|
this.materialX.textureCache.set( textureCacheKey, textureNode );
|
|
346
519
|
|
|
347
|
-
|
|
520
|
+
const nodeName = this.name;
|
|
521
|
+
const materialX = this.materialX;
|
|
522
|
+
|
|
523
|
+
materialX.pendingResources.push( new Promise( ( resolveLoad ) => {
|
|
524
|
+
|
|
525
|
+
loader.load( textureURL, ( imageData ) => {
|
|
348
526
|
|
|
349
|
-
|
|
350
|
-
textureNode.needsUpdate = true;
|
|
527
|
+
if ( imageData.isTexture ) {
|
|
351
528
|
|
|
352
|
-
|
|
529
|
+
// Clone so the wrapping and orientation set below don't modify the handler's texture.
|
|
530
|
+
textureNode.value = imageData.clone();
|
|
531
|
+
textureNode.value.wrapS = TEXTURE_ADDRESS_MODE_WRAPPING[ addressModes.u ];
|
|
532
|
+
textureNode.value.wrapT = TEXTURE_ADDRESS_MODE_WRAPPING[ addressModes.v ];
|
|
353
533
|
|
|
354
|
-
|
|
534
|
+
// MaterialXLoader keeps textures top-first. Loaders such as EXRLoader store rows
|
|
535
|
+
// bottom-first (flipY = false), so invert the loader's orientation to match.
|
|
536
|
+
// flipY has no meaning for compressed textures.
|
|
537
|
+
if ( imageData.isCompressedTexture !== true ) textureNode.value.flipY = ! imageData.flipY;
|
|
355
538
|
|
|
356
|
-
|
|
539
|
+
} else {
|
|
540
|
+
|
|
541
|
+
textureNode.value.image = imageData;
|
|
542
|
+
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
textureNode.value.needsUpdate = true;
|
|
546
|
+
resolveLoad();
|
|
547
|
+
|
|
548
|
+
}, undefined, () => {
|
|
549
|
+
|
|
550
|
+
materialX.log.add(
|
|
551
|
+
MaterialXLogCodes.TEXTURE_LOAD_FAILED,
|
|
552
|
+
`Failed to load texture "${resolvedURI}".`,
|
|
553
|
+
nodeName,
|
|
554
|
+
);
|
|
555
|
+
resolveLoad();
|
|
556
|
+
|
|
557
|
+
} );
|
|
558
|
+
|
|
559
|
+
} ) );
|
|
357
560
|
|
|
358
561
|
return textureNode;
|
|
359
562
|
|
|
@@ -373,12 +576,17 @@ class MaterialXNode {
|
|
|
373
576
|
|
|
374
577
|
getNode( out = null ) {
|
|
375
578
|
|
|
376
|
-
|
|
579
|
+
// A named output must not replace the cached default output.
|
|
580
|
+
const cacheDefaultOutput = out === null;
|
|
581
|
+
const cachedNode = this.materialX.getCachedNode( this );
|
|
582
|
+
if ( cachedNode !== null && cacheDefaultOutput ) return cachedNode;
|
|
377
583
|
|
|
378
584
|
let node;
|
|
585
|
+
let implemented = false;
|
|
379
586
|
|
|
380
587
|
|
|
381
|
-
|
|
588
|
+
// A connection that names no output reads the first one, as in MaterialX.
|
|
589
|
+
if ( this.element === 'separate2' || this.element === 'separate3' || this.element === 'separate4' ) {
|
|
382
590
|
|
|
383
591
|
const inNode = this.getNodeByName( 'in' );
|
|
384
592
|
return element( inNode, getOutputChannel( out ) );
|
|
@@ -386,33 +594,12 @@ class MaterialXNode {
|
|
|
386
594
|
}
|
|
387
595
|
|
|
388
596
|
const type = this.type;
|
|
389
|
-
|
|
597
|
+
// Channel suffixes (outr, outy, ...) extract a component unless the nodedef declares an output of that name.
|
|
598
|
+
const channelRequested = this.element !== 'input' && isChannelOutput( out ) && this.hasDeclaredOutput( out ) === false;
|
|
390
599
|
|
|
391
600
|
if ( this.isConst ) {
|
|
392
601
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
const normalized = this.getValue().trim().toLowerCase();
|
|
396
|
-
node = bool( normalized === 'true' || normalized === '1' );
|
|
397
|
-
|
|
398
|
-
} else if ( type === 'matrix33' ) {
|
|
399
|
-
|
|
400
|
-
node = this.getMatrix( 3 ) || mat3( 1, 0, 0, 0, 1, 0, 0, 0, 1 );
|
|
401
|
-
|
|
402
|
-
} else if ( type === 'matrix44' ) {
|
|
403
|
-
|
|
404
|
-
node = this.getMatrix( 4 ) || mat4( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 );
|
|
405
|
-
|
|
406
|
-
} else if ( type === 'string' ) {
|
|
407
|
-
|
|
408
|
-
node = this.getValue();
|
|
409
|
-
|
|
410
|
-
} else {
|
|
411
|
-
|
|
412
|
-
const nodeClass = this.getClassFromType( type );
|
|
413
|
-
node = nodeClass ? nodeClass( ...this.getVector() ) : float( 0 );
|
|
414
|
-
|
|
415
|
-
}
|
|
602
|
+
node = createValueNode( type, this.getValue() );
|
|
416
603
|
|
|
417
604
|
} else if ( this.hasReference ) {
|
|
418
605
|
|
|
@@ -426,9 +613,14 @@ class MaterialXNode {
|
|
|
426
613
|
|
|
427
614
|
}
|
|
428
615
|
|
|
429
|
-
const
|
|
616
|
+
const interfaceNode = this.interfaceName !== null ? this.materialX.getInterfaceNode( this ) : null;
|
|
617
|
+
const referenceNode = interfaceNode === null ? this.materialX.getMaterialXNode( this.referencePath ) : null;
|
|
618
|
+
|
|
619
|
+
if ( interfaceNode !== null ) {
|
|
430
620
|
|
|
431
|
-
|
|
621
|
+
node = interfaceNode;
|
|
622
|
+
|
|
623
|
+
} else if ( referenceNode ) {
|
|
432
624
|
|
|
433
625
|
node = referenceNode.getNode( requestedOutput );
|
|
434
626
|
|
|
@@ -443,31 +635,22 @@ class MaterialXNode {
|
|
|
443
635
|
|
|
444
636
|
}
|
|
445
637
|
|
|
446
|
-
} else if ( this.element === 'input' && this.
|
|
447
|
-
|
|
448
|
-
let index = 0;
|
|
449
|
-
const defaultGeomProp = this.getAttribute( 'defaultgeomprop' );
|
|
450
|
-
if ( defaultGeomProp && /^UV(\d+)$/.test( defaultGeomProp ) ) {
|
|
638
|
+
} else if ( this.element === 'input' && this.getAttribute( 'defaultgeomprop' ) !== null ) {
|
|
451
639
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
node = this.materialX.compileContext.mxToBottomLeftUvSpace( uv( index ) );
|
|
640
|
+
// An unconnected interface input takes its value from its declared geometric property.
|
|
641
|
+
node = this.materialX.compileContext.getGeomPropNode( this.getAttribute( 'defaultgeomprop' ) );
|
|
457
642
|
|
|
458
643
|
} else {
|
|
459
644
|
|
|
460
|
-
|
|
645
|
+
const resolvedNode = this.materialX.nodeResolver !== null ? this.materialX.nodeResolver( this, out ) : null;
|
|
646
|
+
implemented = ( resolvedNode === null || resolvedNode === undefined ) && this.materialX.getScope( this ) !== null;
|
|
647
|
+
node = resolvedNode !== null && resolvedNode !== undefined ? resolvedNode : implemented ? this.materialX.compileImplementation( this, channelRequested ? null : out ) : compileNodeFromRegistry( this, out, this.materialX.compileContext );
|
|
461
648
|
|
|
462
649
|
}
|
|
463
650
|
|
|
464
651
|
if ( node === null || node === undefined ) {
|
|
465
652
|
|
|
466
|
-
this.
|
|
467
|
-
MaterialXLogCodes.UNSUPPORTED_NODE,
|
|
468
|
-
`Unsupported MaterialX node category "${this.element}" on "${this.name}".`,
|
|
469
|
-
this.name,
|
|
470
|
-
);
|
|
653
|
+
this.logUnsupportedNode();
|
|
471
654
|
node = float( 0 );
|
|
472
655
|
|
|
473
656
|
}
|
|
@@ -515,7 +698,7 @@ class MaterialXNode {
|
|
|
515
698
|
|
|
516
699
|
}
|
|
517
700
|
|
|
518
|
-
this.
|
|
701
|
+
if ( cacheDefaultOutput ) this.materialX.setCachedNode( this, node );
|
|
519
702
|
return node;
|
|
520
703
|
|
|
521
704
|
}
|
|
@@ -544,17 +727,43 @@ class MaterialXNode {
|
|
|
544
727
|
|
|
545
728
|
}
|
|
546
729
|
|
|
547
|
-
|
|
730
|
+
getInputTypes() {
|
|
548
731
|
|
|
549
|
-
const
|
|
550
|
-
|
|
732
|
+
const types = {};
|
|
733
|
+
for ( const input of this.children ) {
|
|
734
|
+
|
|
735
|
+
types[ input.name ] = input.type;
|
|
736
|
+
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
return types;
|
|
740
|
+
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
// nodes without a nodedef (e.g. from a host node resolver) accept any input
|
|
744
|
+
declaresInput( name ) {
|
|
745
|
+
|
|
746
|
+
return this.getChildByName( name ) !== undefined || this.nodeDef === null || name in this.nodeDef.inputs;
|
|
551
747
|
|
|
552
748
|
}
|
|
553
749
|
|
|
554
|
-
|
|
750
|
+
getNodeByName( name ) {
|
|
555
751
|
|
|
556
752
|
const child = this.getChildByName( name );
|
|
557
|
-
|
|
753
|
+
if ( child ) return child.getNode( child.output );
|
|
754
|
+
|
|
755
|
+
if ( this.declaresInput( name ) === false ) {
|
|
756
|
+
|
|
757
|
+
this.materialX.log.add(
|
|
758
|
+
MaterialXLogCodes.UNKNOWN_INPUT,
|
|
759
|
+
`"${this.element}" reads input "${name}", which nodedef "${this.nodeDef.name}" does not declare. Using fallback 0.`,
|
|
760
|
+
this.name,
|
|
761
|
+
);
|
|
762
|
+
return float( 0 );
|
|
763
|
+
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
return this.getDefaultInputNode( name );
|
|
558
767
|
|
|
559
768
|
}
|
|
560
769
|
|
|
@@ -580,37 +789,7 @@ class MaterialXNode {
|
|
|
580
789
|
|
|
581
790
|
getVector() {
|
|
582
791
|
|
|
583
|
-
|
|
584
|
-
for ( const val of this.getValue().split( /[,|\s]/ ) ) {
|
|
585
|
-
|
|
586
|
-
if ( val !== '' ) vector.push( Number( val.trim() ) );
|
|
587
|
-
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
return vector;
|
|
591
|
-
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
getMatrix( size ) {
|
|
595
|
-
|
|
596
|
-
const vector = this.getVector();
|
|
597
|
-
const expectedLength = size * size;
|
|
598
|
-
if ( vector.length !== expectedLength ) return null;
|
|
599
|
-
// MaterialX matrix values are serialized in column-major order.
|
|
600
|
-
// Reorder to row-major before constructing TSL matrix nodes so
|
|
601
|
-
// transformmatrix semantics match MaterialXJS and MaterialXView.
|
|
602
|
-
const reordered = [];
|
|
603
|
-
for ( let row = 0; row < size; row += 1 ) {
|
|
604
|
-
|
|
605
|
-
for ( let column = 0; column < size; column += 1 ) {
|
|
606
|
-
|
|
607
|
-
reordered.push( vector[ column * size + row ] );
|
|
608
|
-
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
return size === 3 ? mat3( ...reordered ) : mat4( ...reordered );
|
|
792
|
+
return parseValueVector( this.getValue() );
|
|
614
793
|
|
|
615
794
|
}
|
|
616
795
|
|
|
@@ -640,26 +819,33 @@ class MaterialXNode {
|
|
|
640
819
|
|
|
641
820
|
}
|
|
642
821
|
|
|
643
|
-
setMaterial( material ) {
|
|
822
|
+
setMaterial( material, out = null ) {
|
|
823
|
+
|
|
824
|
+
if ( this.element === 'input' || this.element === 'output' ) {
|
|
825
|
+
|
|
826
|
+
const shader = this.getReferencedNode();
|
|
827
|
+
if ( shader !== null ) shader.setMaterial( material, this.nodeGraph !== null ? null : this.output || out );
|
|
828
|
+
return;
|
|
829
|
+
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
if ( this.materialX.setImplementationMaterial( this, material, out ) ) return;
|
|
644
833
|
|
|
645
834
|
const mapper = getSurfaceMapper( this.element );
|
|
646
835
|
if ( mapper ) {
|
|
647
836
|
|
|
648
|
-
|
|
837
|
+
const authored = this.getNodes();
|
|
838
|
+
mapper.apply( material, { ...this.getDefaultInputNodes(), ...authored }, this.materialX.log, this.name, authored, this.getInputTypes() );
|
|
649
839
|
|
|
650
840
|
} else {
|
|
651
841
|
|
|
652
|
-
this.
|
|
653
|
-
MaterialXLogCodes.UNSUPPORTED_NODE,
|
|
654
|
-
`Unsupported MaterialX node category "${this.element}" on "${this.name}".`,
|
|
655
|
-
this.name,
|
|
656
|
-
);
|
|
842
|
+
this.logUnsupportedNode();
|
|
657
843
|
|
|
658
844
|
}
|
|
659
845
|
|
|
660
846
|
}
|
|
661
847
|
|
|
662
|
-
|
|
848
|
+
toNodeGraphMaterial() {
|
|
663
849
|
|
|
664
850
|
const material = new MeshBasicNodeMaterial();
|
|
665
851
|
material.name = this.name;
|
|
@@ -681,29 +867,49 @@ class MaterialXNode {
|
|
|
681
867
|
|
|
682
868
|
resolveSurfaceShaderNode( nodeX ) {
|
|
683
869
|
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
870
|
+
const visited = new Set();
|
|
871
|
+
let shader = nodeX || null;
|
|
872
|
+
let out = null;
|
|
687
873
|
|
|
688
|
-
|
|
874
|
+
while ( shader !== null && ( shader.element === 'input' || shader.element === 'output' ) ) {
|
|
689
875
|
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
876
|
+
if ( visited.has( shader ) ) return null;
|
|
877
|
+
visited.add( shader );
|
|
878
|
+
out = shader.nodeGraph !== null ? null : shader.output;
|
|
879
|
+
shader = shader.getReferencedNode();
|
|
693
880
|
|
|
694
881
|
}
|
|
695
882
|
|
|
696
|
-
return null;
|
|
883
|
+
return shader !== null ? this.materialX.resolveImplementationShader( shader, out ) : null;
|
|
697
884
|
|
|
698
885
|
}
|
|
699
886
|
|
|
700
|
-
|
|
887
|
+
toSurfaceMaterial() {
|
|
701
888
|
|
|
702
|
-
const
|
|
889
|
+
const surfaceShader = this.resolveSurfaceShaderNode( this.getChildByName( 'surfaceshader' ) );
|
|
890
|
+
const material = surfaceShader?.nodeDef?.name === 'ND_surface_unlit' ? new MeshBasicNodeMaterial() : new MeshPhysicalNodeMaterial();
|
|
703
891
|
material.name = this.name;
|
|
704
892
|
|
|
705
893
|
for ( const nodeX of this.children ) {
|
|
706
894
|
|
|
895
|
+
if ( nodeX.name === 'backsurfaceshader' ) {
|
|
896
|
+
|
|
897
|
+
// MaterialX supports separate back-surface shaders. Their use in practice
|
|
898
|
+
// is unclear; translating them per face is left for future work.
|
|
899
|
+
if ( nodeX.hasReference || nodeX.nodeGraph !== null ) {
|
|
900
|
+
|
|
901
|
+
this.materialX.log.add(
|
|
902
|
+
MaterialXLogCodes.IGNORED_SURFACE_INPUT,
|
|
903
|
+
'surfacematerial input "backsurfaceshader" is currently ignored in MaterialX translation.',
|
|
904
|
+
this.name,
|
|
905
|
+
);
|
|
906
|
+
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
continue;
|
|
910
|
+
|
|
911
|
+
}
|
|
912
|
+
|
|
707
913
|
const shaderProperties = this.resolveSurfaceShaderNode( nodeX );
|
|
708
914
|
if ( shaderProperties === null ) {
|
|
709
915
|
|
|
@@ -716,7 +922,7 @@ class MaterialXNode {
|
|
|
716
922
|
|
|
717
923
|
}
|
|
718
924
|
|
|
719
|
-
|
|
925
|
+
nodeX.setMaterial( material );
|
|
720
926
|
|
|
721
927
|
}
|
|
722
928
|
|
|
@@ -747,7 +953,7 @@ class MaterialXNode {
|
|
|
747
953
|
|
|
748
954
|
for ( const nodeX of selectedSurfaceMaterials ) {
|
|
749
955
|
|
|
750
|
-
const material = nodeX.
|
|
956
|
+
const material = nodeX.toSurfaceMaterial();
|
|
751
957
|
materials[ material.name ] = material;
|
|
752
958
|
|
|
753
959
|
}
|
|
@@ -756,9 +962,10 @@ class MaterialXNode {
|
|
|
756
962
|
|
|
757
963
|
for ( const nodeX of this.children ) {
|
|
758
964
|
|
|
759
|
-
|
|
965
|
+
// Only standalone nodegraphs should create preview materials.
|
|
966
|
+
if ( nodeX.element === 'nodegraph' && nodeX.getAttribute( 'nodedef' ) === null && this.materialX.implementationGraphNodes.has( nodeX ) === false ) {
|
|
760
967
|
|
|
761
|
-
const material = nodeX.
|
|
968
|
+
const material = nodeX.toNodeGraphMaterial();
|
|
762
969
|
materials[ material.name ] = material;
|
|
763
970
|
|
|
764
971
|
}
|
|
@@ -797,12 +1004,28 @@ class MaterialXDocument {
|
|
|
797
1004
|
this.textureLoader.setOptions( { imageOrientation: 'none' } );
|
|
798
1005
|
this.textureLoader.setPath( path );
|
|
799
1006
|
this.textureCache = new Map();
|
|
1007
|
+
this.pendingResources = [];
|
|
1008
|
+
this.nodeResolver = null;
|
|
1009
|
+
this.documentNodeDefs = null;
|
|
1010
|
+
|
|
1011
|
+
this.implementationGraphs = new Map();
|
|
1012
|
+
this.implementationGraphNodes = new Set();
|
|
1013
|
+
this.scope = null;
|
|
1014
|
+
this.rootScopes = new Map();
|
|
800
1015
|
const bottomLeftUvSpaceHelpers = getBottomLeftUvSpaceHelpers( this.uvSpace );
|
|
801
1016
|
|
|
802
1017
|
this.compileContext = {
|
|
803
1018
|
compileRegistry: COMPILE_REGISTRY,
|
|
804
1019
|
nodeLibrary: MtlXLibrary,
|
|
805
1020
|
...bottomLeftUvSpaceHelpers,
|
|
1021
|
+
getTexcoordNode: ( index = 0 ) => bottomLeftUvSpaceHelpers.mxToBottomLeftUvSpace( uv( index ) ),
|
|
1022
|
+
getGeomPropNode: ( name ) => {
|
|
1023
|
+
|
|
1024
|
+
const uvMatch = /^UV(\d+)$/.exec( name );
|
|
1025
|
+
if ( uvMatch ) return bottomLeftUvSpaceHelpers.mxToBottomLeftUvSpace( uv( parseInt( uvMatch[ 1 ], 10 ) ) );
|
|
1026
|
+
return GEOMPROP_NODES[ name ];
|
|
1027
|
+
|
|
1028
|
+
},
|
|
806
1029
|
mxTransformUv: mx_transform_uv,
|
|
807
1030
|
mxHextileCoord,
|
|
808
1031
|
mxHextileComputeBlendWeights,
|
|
@@ -826,6 +1049,207 @@ class MaterialXDocument {
|
|
|
826
1049
|
|
|
827
1050
|
}
|
|
828
1051
|
|
|
1052
|
+
indexImplementations( rootNode ) {
|
|
1053
|
+
|
|
1054
|
+
for ( const nodeX of rootNode.children ) {
|
|
1055
|
+
|
|
1056
|
+
const nodeDefName = nodeX.getAttribute( 'nodedef' );
|
|
1057
|
+
const graphName = nodeX.element === 'implementation' ? nodeX.getAttribute( 'nodegraph' ) : null;
|
|
1058
|
+
const graph = nodeX.element === 'nodegraph' && nodeDefName !== null ? nodeX : graphName !== null ? this.getMaterialXNode( graphName ) : undefined;
|
|
1059
|
+
if ( graph === undefined ) continue;
|
|
1060
|
+
|
|
1061
|
+
this.implementationGraphNodes.add( graph );
|
|
1062
|
+
if ( this.implementationGraphs.has( nodeDefName ) === false ) this.implementationGraphs.set( nodeDefName, graph );
|
|
1063
|
+
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
// Each custom node instance needs its own inputs and cached TSL nodes.
|
|
1069
|
+
getScope( materialXNode ) {
|
|
1070
|
+
|
|
1071
|
+
const nodeDef = materialXNode.nodeDef;
|
|
1072
|
+
const graph = nodeDef !== null ? this.implementationGraphs.get( nodeDef.name ) : undefined;
|
|
1073
|
+
if ( graph === undefined ) return null;
|
|
1074
|
+
|
|
1075
|
+
for ( let parent = this.scope; parent !== null; parent = parent.parent ) {
|
|
1076
|
+
|
|
1077
|
+
if ( parent.graph === graph ) {
|
|
1078
|
+
|
|
1079
|
+
this.log.add(
|
|
1080
|
+
MaterialXLogCodes.INVALID_VALUE,
|
|
1081
|
+
`The nodegraph of "${ materialXNode.element }" uses the node it implements.`,
|
|
1082
|
+
materialXNode.name,
|
|
1083
|
+
);
|
|
1084
|
+
return null;
|
|
1085
|
+
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
const scopes = this.scope !== null ? this.scope.childScopes : this.rootScopes;
|
|
1091
|
+
let scope = scopes.get( materialXNode );
|
|
1092
|
+
|
|
1093
|
+
if ( scope === undefined ) {
|
|
1094
|
+
|
|
1095
|
+
scope = { instance: materialXNode, nodeDef, graph, parent: this.scope, nodes: new Map(), childScopes: new Map() };
|
|
1096
|
+
scopes.set( materialXNode, scope );
|
|
1097
|
+
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
return scope;
|
|
1101
|
+
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
withScope( scope, callback ) {
|
|
1105
|
+
|
|
1106
|
+
const previous = this.scope;
|
|
1107
|
+
this.scope = scope;
|
|
1108
|
+
|
|
1109
|
+
try {
|
|
1110
|
+
|
|
1111
|
+
return callback();
|
|
1112
|
+
|
|
1113
|
+
} finally {
|
|
1114
|
+
|
|
1115
|
+
this.scope = previous;
|
|
1116
|
+
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
isInScope( materialXNode ) {
|
|
1122
|
+
|
|
1123
|
+
if ( this.scope === null ) return false;
|
|
1124
|
+
|
|
1125
|
+
for ( let parent = materialXNode.parent; parent !== null; parent = parent.parent ) {
|
|
1126
|
+
|
|
1127
|
+
if ( parent === this.scope.graph ) return true;
|
|
1128
|
+
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
return false;
|
|
1132
|
+
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
getCachedNode( materialXNode ) {
|
|
1136
|
+
|
|
1137
|
+
if ( this.isInScope( materialXNode ) ) return this.scope.nodes.get( materialXNode ) ?? null;
|
|
1138
|
+
return materialXNode.node;
|
|
1139
|
+
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
setCachedNode( materialXNode, node ) {
|
|
1143
|
+
|
|
1144
|
+
if ( this.isInScope( materialXNode ) ) this.scope.nodes.set( materialXNode, node );
|
|
1145
|
+
else materialXNode.node = node;
|
|
1146
|
+
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
getGraphOutput( scope, out ) {
|
|
1150
|
+
|
|
1151
|
+
// An omitted selector uses the first output declared by the nodedef.
|
|
1152
|
+
const name = out === null ? Object.keys( scope.nodeDef.outputs )[ 0 ] : out;
|
|
1153
|
+
return scope.graph.children.find( ( child ) => child.element === 'output' && child.name === name ) || null;
|
|
1154
|
+
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
compileImplementation( materialXNode, out ) {
|
|
1158
|
+
|
|
1159
|
+
const scope = this.getScope( materialXNode );
|
|
1160
|
+
if ( scope === null ) return null;
|
|
1161
|
+
|
|
1162
|
+
const output = this.getGraphOutput( scope, out );
|
|
1163
|
+
if ( output === null ) {
|
|
1164
|
+
|
|
1165
|
+
this.log.add(
|
|
1166
|
+
MaterialXLogCodes.MISSING_REFERENCE,
|
|
1167
|
+
`Missing output "${ out || 'out' }" in the nodegraph of "${ materialXNode.name }".`,
|
|
1168
|
+
materialXNode.name,
|
|
1169
|
+
);
|
|
1170
|
+
return float( 0 );
|
|
1171
|
+
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
// Use the output selector stored on the graph output.
|
|
1175
|
+
return this.withScope( scope, () => output.getNode() );
|
|
1176
|
+
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
setImplementationMaterial( materialXNode, material, out ) {
|
|
1180
|
+
|
|
1181
|
+
const scope = this.getScope( materialXNode );
|
|
1182
|
+
if ( scope === null ) return false;
|
|
1183
|
+
|
|
1184
|
+
const output = this.getGraphOutput( scope, out );
|
|
1185
|
+
const shaderNode = output !== null && output.hasReference ? this.getMaterialXNode( output.referencePath ) : undefined;
|
|
1186
|
+
if ( shaderNode === undefined ) {
|
|
1187
|
+
|
|
1188
|
+
this.log.add(
|
|
1189
|
+
MaterialXLogCodes.MISSING_REFERENCE,
|
|
1190
|
+
`Missing shader output "${ out || 'out' }" in the nodegraph of "${ materialXNode.name }".`,
|
|
1191
|
+
materialXNode.name,
|
|
1192
|
+
);
|
|
1193
|
+
return true;
|
|
1194
|
+
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
this.withScope( scope, () => shaderNode.setMaterial( material, output.output ) );
|
|
1198
|
+
return true;
|
|
1199
|
+
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
resolveImplementationShader( materialXNode, out ) {
|
|
1203
|
+
|
|
1204
|
+
const scope = this.getScope( materialXNode );
|
|
1205
|
+
if ( scope === null ) return materialXNode;
|
|
1206
|
+
|
|
1207
|
+
const output = this.getGraphOutput( scope, out );
|
|
1208
|
+
return this.withScope( scope, () => materialXNode.resolveSurfaceShaderNode( output ) );
|
|
1209
|
+
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
// Resolve interfacename to the node instance's input.
|
|
1213
|
+
// If that input is omitted, use the nodedef default.
|
|
1214
|
+
getInterfaceInput( materialXNode ) {
|
|
1215
|
+
|
|
1216
|
+
// Regular nodegraphs bind to their own inputs.
|
|
1217
|
+
if ( ! this.isInScope( materialXNode ) ) {
|
|
1218
|
+
|
|
1219
|
+
const graphInput = this.getMaterialXNode( materialXNode.referencePath );
|
|
1220
|
+
return graphInput !== undefined && graphInput !== materialXNode ? graphInput : null;
|
|
1221
|
+
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
const scope = this.scope;
|
|
1225
|
+
const name = materialXNode.interfaceName;
|
|
1226
|
+
const input = scope.instance.getChildByName( name );
|
|
1227
|
+
if ( input !== undefined ) return this.withScope( scope.parent, () => input.getValueInput() );
|
|
1228
|
+
const declaration = this.getMaterialXNode( scope.nodeDef.name );
|
|
1229
|
+
return declaration ? declaration.getChildByName( name ) ?? null : null;
|
|
1230
|
+
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
getInterfaceNode( materialXNode ) {
|
|
1234
|
+
|
|
1235
|
+
if ( ! this.isInScope( materialXNode ) ) return null;
|
|
1236
|
+
|
|
1237
|
+
const scope = this.scope;
|
|
1238
|
+
const name = materialXNode.interfaceName;
|
|
1239
|
+
const input = scope.instance.getChildByName( name );
|
|
1240
|
+
// Evaluate the instance input in the parent scope to resolve nested interface bindings.
|
|
1241
|
+
if ( input !== undefined ) return this.withScope( scope.parent, () => input.getNode( input.output ) );
|
|
1242
|
+
|
|
1243
|
+
return this.withScope( null, () => scope.instance.getDefaultInputNode( name ) ?? null );
|
|
1244
|
+
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
waitForResources() {
|
|
1248
|
+
|
|
1249
|
+
return Promise.all( this.pendingResources ).then( () => undefined );
|
|
1250
|
+
|
|
1251
|
+
}
|
|
1252
|
+
|
|
829
1253
|
addMaterialXNode( materialXNode ) {
|
|
830
1254
|
|
|
831
1255
|
this.nodesXLib.set( materialXNode.nodePath, materialXNode );
|
|
@@ -838,6 +1262,49 @@ class MaterialXDocument {
|
|
|
838
1262
|
|
|
839
1263
|
}
|
|
840
1264
|
|
|
1265
|
+
// Convert document nodedefs to the format used by the stdlib registry.
|
|
1266
|
+
getDocumentNodeDefs() {
|
|
1267
|
+
|
|
1268
|
+
if ( this.documentNodeDefs !== null ) return this.documentNodeDefs;
|
|
1269
|
+
|
|
1270
|
+
this.documentNodeDefs = {};
|
|
1271
|
+
|
|
1272
|
+
for ( const nodeX of this.nodesXLib.values() ) {
|
|
1273
|
+
|
|
1274
|
+
if ( nodeX.element !== 'nodedef' ) continue;
|
|
1275
|
+
|
|
1276
|
+
const nodedef = { node: nodeX.getAttribute( 'node' ), inputs: {}, outputs: {} };
|
|
1277
|
+
const version = nodeX.getAttribute( 'version' );
|
|
1278
|
+
if ( version ) nodedef.version = version;
|
|
1279
|
+
if ( nodeX.getAttribute( 'isdefaultversion' ) === 'true' ) nodedef.isdefaultversion = true;
|
|
1280
|
+
if ( nodeX.type && nodeX.type !== 'multioutput' ) nodedef.outputs.out = nodeX.type;
|
|
1281
|
+
|
|
1282
|
+
for ( const child of nodeX.children ) {
|
|
1283
|
+
|
|
1284
|
+
if ( child.element === 'output' ) {
|
|
1285
|
+
|
|
1286
|
+
nodedef.outputs[ child.name ] = child.type;
|
|
1287
|
+
|
|
1288
|
+
} else if ( child.element === 'input' ) {
|
|
1289
|
+
|
|
1290
|
+
const input = { type: child.type };
|
|
1291
|
+
if ( child.value !== null ) input.value = child.value;
|
|
1292
|
+
const geomprop = child.getAttribute( 'defaultgeomprop' );
|
|
1293
|
+
if ( geomprop ) input.defaultgeomprop = geomprop;
|
|
1294
|
+
nodedef.inputs[ child.name ] = input;
|
|
1295
|
+
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
this.documentNodeDefs[ nodeX.name ] = nodedef;
|
|
1301
|
+
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
return this.documentNodeDefs;
|
|
1305
|
+
|
|
1306
|
+
}
|
|
1307
|
+
|
|
841
1308
|
parseNode( nodeXML, nodePath = '' ) {
|
|
842
1309
|
|
|
843
1310
|
return parseMaterialXNodeTree(
|
|
@@ -851,12 +1318,17 @@ class MaterialXDocument {
|
|
|
851
1318
|
|
|
852
1319
|
parse( text, materialName = null, options = {} ) {
|
|
853
1320
|
|
|
1321
|
+
this.nodeResolver = options.nodeResolver || null;
|
|
1322
|
+
this.documentNodeDefs = null;
|
|
1323
|
+
|
|
854
1324
|
const rootNode = parseMaterialXText(
|
|
855
1325
|
text,
|
|
856
1326
|
( childNodeXML, childNodePath ) => new MaterialXNode( this, childNodeXML, childNodePath ),
|
|
857
1327
|
( materialXNode ) => this.addMaterialXNode( materialXNode ),
|
|
858
1328
|
);
|
|
859
1329
|
|
|
1330
|
+
this.indexImplementations( rootNode );
|
|
1331
|
+
|
|
860
1332
|
if ( options.interfaceValidator ) {
|
|
861
1333
|
|
|
862
1334
|
options.interfaceValidator( rootNode, this.log );
|