// Adds material and sets up its dependent technique, program, shaders. This should be called
    // after adding meshes, but before populating lights, textures, etc.
    // Pass:
    //   hack - attributes of some mesh that uses this material
    public void AddMaterialWithDependencies(
        IExportableMaterial exportableMaterial,
        string meshNamespace,
        GlTF_Attributes hack)
    {
        GlTF_Material gltfMtl = G.CreateMaterial(meshNamespace, exportableMaterial);

        // Set up technique.
        GlTF_Technique tech = GlTF_Writer.CreateTechnique(G, exportableMaterial);

        gltfMtl.instanceTechniqueName = tech.name;
        GlTF_Technique.States states = null;
        if (m_techniqueStates.ContainsKey(exportableMaterial))
        {
            states = m_techniqueStates[exportableMaterial];
        }

        if (states == null)
        {
            // Unless otherwise specified the preset, enable z-buffering.
            states        = new GlTF_Technique.States();
            states.enable = new[] { GlTF_Technique.Enable.DEPTH_TEST }.ToList();
        }
        tech.states = states;
        AddAllAttributes(tech, exportableMaterial, hack);
        tech.AddDefaultUniforms(G.RTCCenter != null);

        // Add program.
        GlTF_Program program = new GlTF_Program(G);

        program.name = GlTF_Program.GetNameFromObject(exportableMaterial);
        tech.program = program.name;
        foreach (var attr in tech.attributes)
        {
            program.attributes.Add(attr.name);
        }
        G.programs.Add(program);

        // Add vertex and fragment shaders.
        GlTF_Shader vertShader = new GlTF_Shader(G);

        vertShader.name      = GlTF_Shader.GetNameFromObject(exportableMaterial, GlTF_Shader.Type.Vertex);
        program.vertexShader = vertShader.name;
        vertShader.type      = GlTF_Shader.Type.Vertex;
        vertShader.uri       = ExportFileReference.CreateHttp(exportableMaterial.VertShaderUri);
        G.shaders.Add(vertShader);

        GlTF_Shader fragShader = new GlTF_Shader(G);

        fragShader.name        = GlTF_Shader.GetNameFromObject(exportableMaterial, GlTF_Shader.Type.Fragment);
        program.fragmentShader = fragShader.name;
        fragShader.type        = GlTF_Shader.Type.Fragment;
        fragShader.uri         = ExportFileReference.CreateHttp(exportableMaterial.FragShaderUri);
        G.shaders.Add(fragShader);
    }
 /// Returns an ExportFileReference given an absolute http:// uri.
 /// Depending on settings, this may become a relative reference in the gltf.
 private ExportFileReference CreateExportFileReferenceFromHttp(string httpUri)
 {
     if (!AllowHttpUri)
     {
         string localPath = HostedUriToLocalFilename(httpUri);
         if (localPath != null)
         {
             return(ExportFileReference.GetOrCreateSafeLocal(
                        G.m_disambiguationContext,
                        Path.GetFileName(localPath), Path.GetDirectoryName(localPath),
                        "Brush_" + Path.GetFileName(localPath)));
         }
         Debug.LogWarning($"Cannot convert {httpUri} to local");
     }
     return(ExportFileReference.CreateHttp(httpUri));
 }