Exemplo n.º 1
0
        /// Authors USD Shader inputs onto the given shader and material and connects private shader
        /// inputs to the public material inputs (the intent being, inputs are authored on the material
        /// and flow into the shader, which is a detail of the network).
        static void CreateShaderInputs <T>(pxr.UsdShadeShader shader,
                                           pxr.UsdShadeMaterial material,
                                           Dictionary <string, T> paramDict)
        {
            USD.NET.UsdTypeBinding binding;
            if (!USD.NET.UsdIo.Bindings.GetBinding(typeof(T), out binding))
            {
                // TODO: add "with exception" to GetBinding().
                throw new Exception("Type not found: " + typeof(T).Name);
            }

            foreach (var kvp in paramDict)
            {
                var inputName   = new pxr.TfToken(kvp.Key);
                var matInput    = material.CreateInput(inputName, binding.sdfTypeName);
                var shaderInput = shader.CreateInput(inputName, binding.sdfTypeName);
                matInput.Set(binding.toVtValue(kvp.Value));
                shaderInput.Set(binding.toVtValue(kvp.Value));
                shaderInput.ConnectToSource(matInput);
            }
        }
Exemplo n.º 2
0
        /// Authors a USD Material, Shader, parameters and connections between the two.
        /// The USD shader structure consists of a Material, which is connected to a shader output. The
        /// Shader consists of input parameters which are either connected to other shaders or in the case
        /// of public parameters, back to the material which is the public interface for the shading
        /// network.
        ///
        /// This function creates a material, shader, inputs, outputs, zero or more textures, and for each
        /// texture, a single primvar reader node to read the UV data from the geometric primitive.
        static string CreateMaterialNetwork(USD.NET.Scene scene,
                                            IExportableMaterial material,
                                            string rootPath = null)
        {
            var matSample = new ExportMaterialSample();

            // Used scene object paths.
            string materialPath = GetMaterialPath(material, rootPath);
            string shaderPath   = GetShaderPath(material, materialPath);
            string displayColorPrimvarReaderPath   = GetPrimvarPath(material, "displayColor", shaderPath);
            string displayOpacityPrimvarReaderPath = GetPrimvarPath(material, "displayOpacity", shaderPath);

            // The material was already created.
            if (scene.GetPrimAtPath(materialPath) != null)
            {
                return(materialPath);
            }

            // Ensure the root material path is defined in the scene.
            scene.Stage.DefinePrim(new pxr.SdfPath(rootPath));

            // Connect the materail surface to the output of the shader.
            matSample.surface.SetConnectedPath(shaderPath, "outputs:result");
            scene.Write(materialPath, matSample);

            // Create the shader and conditionally connect the diffuse color to the MainTex output.
            var shaderSample = GetShaderSample(material);
            var texturePath  = CreateAlphaTexture(scene, shaderPath, material);

            if (texturePath != null)
            {
                // A texture was created, so connect the opacity input to the texture output.
                shaderSample.opacity.SetConnectedPath(texturePath, "outputs:a");
            }
            else
            {
                // TODO: currently primvars:displayOpacity is not multiplied when an alpha texture is
                //                present. However, this only affects the USD preview. The correct solution
                //                requires a multiply node in the shader graph, but this does not yet exist.
                scene.Write(displayOpacityPrimvarReaderPath, new PrimvarReader1fSample("displayOpacity"));
                shaderSample.opacity.SetConnectedPath(displayOpacityPrimvarReaderPath, "outputs:result");
            }

            // Create a primvar reader to read primvars:displayColor.
            scene.Write(displayColorPrimvarReaderPath, new PrimvarReader3fSample("displayColor"));

            // Connect the diffuse color to the primvar reader.
            shaderSample.diffuseColor.SetConnectedPath(displayColorPrimvarReaderPath, "outputs:result");

            scene.Write(shaderPath, shaderSample);

            //
            // Everything below is ad-hoc data, which is written using the low level USD API.
            // It consists of the Unity shader parameters and the non-exported texture URIs.
            // Also note that scene.GetPrimAtPath will return null when the prim is InValid,
            // so there is no need to call IsValid() on the resulting prim.
            //
            var shadeMaterial = new pxr.UsdShadeMaterial(scene.GetPrimAtPath(materialPath));
            var shadeShader   = new pxr.UsdShadeShader(scene.GetPrimAtPath(shaderPath));

            if (material.SupportsDetailedMaterialInfo)
            {
                CreateShaderInputs(shadeShader, shadeMaterial, material.FloatParams);
                CreateShaderInputs(shadeShader, shadeMaterial, material.ColorParams);
                CreateShaderInputs(shadeShader, shadeMaterial, material.VectorParams);
            }

            CreateTextureUris(shadeShader.GetPrim(), material);

            return(materialPath);
        }