Example #1
0
 void Start()
 {
     InitUsd.Initialize();
     m_lastTime = m_usdTime;
     if (string.IsNullOrEmpty(m_usdFile))
     {
         m_usdFile = Path.Combine(PackageUtils.GetCallerRelativeToProjectFolderPath(), K_DEFAULT_MESH);
     }
 }
        void Start()
        {
            var asset = GetComponent <UsdAsset>();

            if (string.IsNullOrEmpty(asset.usdFullPath))
            {
                asset.usdFullPath = Path.Combine(PackageUtils.GetCallerRelativeToProjectFolderPath(), K_DEFAULT_MESH);
            }
        }
        //
        // Start generates a USD scene procedurally, containing a single cube with a material, shader
        // and texture bound. It then inspects the cube to discover the material. A Unity material is
        // constructed and the parameters are copied in a generic way. Similarly, the texture is
        // discovered and loaded as a Unity Texture2D and bound to the material.
        //
        // Also See: https://docs.unity3d.com/Manual/MaterialsAccessingViaScript.html
        //
        void Start()
        {
            // Get the current local path
            m_localPath = PackageUtils.GetCallerRelativeToProjectFolderPath();

            // Create a scene for this test, but could also be read from disk.
            Scene usdScene = CreateSceneWithShading();

            // Read the material and shader ID.
            var    usdMaterial = new MaterialSample();
            string shaderId;

            // ReadMaterial was designed for Unity and assumes there is one "surface" shader bound.
            if (!MaterialSample.ReadMaterial(usdScene, kCubePath, usdMaterial, out shaderId))
            {
                throw new System.Exception("Failed to read material");
            }

            // Map the shader ID to the corresponding Unity/USD shader pair.
            ShaderPair shader;

            if (shaderId == null || !m_shaderMap.TryGetValue(shaderId, out shader))
            {
                throw new System.Exception("Material had no surface bound");
            }

            //
            // Read and process the shader-specific parameters.
            //

            // UsdShade requires all connections target an attribute, but we actually want to deserialize
            // the entire prim, so we get just the prim path here.
            var shaderPath = new pxr.SdfPath(usdMaterial.surface.connectedPath).GetPrimPath();

            usdScene.Read(shaderPath, shader.usdShader);

            //
            // Construct material & process the inputs, textures, and keywords.
            //

            var mat = new UnityEngine.Material(shader.unityShader);

            // Apply material keywords.
            foreach (string keyword in usdMaterial.requiredKeywords ?? new string[0])
            {
                mat.EnableKeyword(keyword);
            }

            // Iterate over all input parameters and copy values and/or construct textures.
            foreach (var param in shader.usdShader.GetInputParameters())
            {
                if (!SetMaterialParameter(mat, param.unityName, param.value))
                {
                    throw new System.Exception("Incompatible shader data type: " + param.ToString());
                }
            }

            foreach (var param in shader.usdShader.GetInputTextures())
            {
                if (string.IsNullOrEmpty(param.connectedPath))
                {
                    // Not connected to a texture.
                    continue;
                }

                // Only 2D textures are supported in this example.
                var usdTexture = new Texture2DSample();

                // Again, we want the prim path, not the attribute path.
                var texturePath = new pxr.SdfPath(param.connectedPath).GetPrimPath();
                usdScene.Read(texturePath, usdTexture);

                // This example also only supports explicit sourceFiles, they cannot be connected.
                if (string.IsNullOrEmpty(usdTexture.sourceFile.defaultValue))
                {
                    continue;
                }

                // For details, see: https://docs.unity3d.com/Manual/MaterialsAccessingViaScript.html
                foreach (string keyword in param.requiredShaderKeywords)
                {
                    mat.EnableKeyword(keyword);
                }

                var data     = System.IO.File.ReadAllBytes(usdTexture.sourceFile.defaultValue);
                var unityTex = new Texture2D(2, 2);
                unityTex.LoadImage(data);
                mat.SetTexture(param.unityName, unityTex);
                Debug.Log("Set " + param.unityName + " to " + usdTexture.sourceFile.defaultValue);

                unityTex.Apply(updateMipmaps: true, makeNoLongerReadable: false);
            }

            //
            // Create and bind the geometry.
            //

            // Create a cube and set the material.
            // Note that geometry is handled minimally here and is incomplete.
            var cubeSample = new CubeSample();

            usdScene.Read(kCubePath, cubeSample);

            var go = GameObject.CreatePrimitive(PrimitiveType.Cube);

            go.transform.SetParent(transform, worldPositionStays: false);
            go.transform.localScale = Vector3.one * (float)cubeSample.size;
            m_cube = transform;

            go.GetComponent <MeshRenderer>().material = mat;
        }