/// Authors USD Texture and PrimvarReader shader nodes for the given exportable material. /// /// Note that textureUris are stored as metadata and only the "Export Texture" is authored as a /// true texture in the shading network. This is due to the fact that the actual material textures /// are not currently exported with the USD file, but export textures are. /// /// Returns the texture path if a texture node was created, otherwise null. static string CreateAlphaTexture(USD.NET.Scene scene, string shaderPath, IExportableMaterial material) { // Currently, only export texture is previewed in USD. // Create an input parameter to read the texture, e.g. inputs:_MainTex. if (!material.HasExportTexture()) { return(null); } string texFile = SanitizeIdentifier(material.DurableName) + System.IO.Path.GetExtension(material.GetExportTextureFilename()); // Establish paths in the USD scene. string texturePath = GetTexturePath(material, "MainTex", shaderPath); string primvarPath = GetPrimvarPath(material, "uv", texturePath); // Create the texture Prim. var texture = new ExportTextureSample(); // Connect the texture to the file on disk. texture.file.defaultValue = new pxr.SdfAssetPath(texFile); texture.st.SetConnectedPath(primvarPath, "outputs:result"); scene.Write(texturePath, texture); if (scene.GetPrimAtPath(new pxr.SdfPath(primvarPath)) == null) { if (material.VertexLayout.texcoord0.size == 2) { var primvar = new PrimvarReader2fSample("uv"); scene.Write(primvarPath, primvar); } else if (material.VertexLayout.texcoord0.size == 3) { var primvar = new PrimvarReader3fSample("uv"); scene.Write(primvarPath, primvar); } else if (material.VertexLayout.texcoord0.size == 4) { var primvar = new PrimvarReader4fSample("uv"); scene.Write(primvarPath, primvar); } } return(texturePath); }
public UnityEngine.Matrix4x4[] ComputeInstanceMatrices(USD.NET.Scene scene, string primPath) { var prim = scene.GetPrimAtPath(primPath); var pi = new pxr.UsdGeomPointInstancer(prim); var xforms = new pxr.VtMatrix4dArray(); pi.ComputeInstanceTransformsAtTime(xforms, scene.Time == null ? pxr.UsdTimeCode.Default() : scene.Time, 0); // Slow, but works. var matrices = new UnityEngine.Matrix4x4[xforms.size()]; for (int i = 0; i < xforms.size(); i++) { matrices[i] = UnityTypeConverter.FromMatrix(xforms[i]); } return(matrices); }
/// 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); }