// Adds a glTF attribute, as described by name, type, and semantic, to the given technique tech. private static void AddAttribute(string name, GlTF_Technique.Type type, GlTF_Technique.Semantic semantic, GlTF_Technique tech) { GlTF_Technique.Parameter tParam = new GlTF_Technique.Parameter(); tParam.name = name; tParam.type = type; tParam.semantic = semantic; tech.parameters.Add(tParam); GlTF_Technique.Attribute tAttr = new GlTF_Technique.Attribute(); tAttr.name = "a_" + name; tAttr.param = tParam.name; tech.attributes.Add(tAttr); }
// Adds a glTF uniform, as described by name, type, and semantic, to the given technique tech. If // node is non-null, that is also included (e.g. for lights). private void AddUniform( IExportableMaterial exportableMaterial, string name, GlTF_Technique.Type type, GlTF_Technique.Semantic semantic, GlTF_Node node = null) { //var techName = GlTF_Technique.GetNameFromObject(matObjName); var tech = GlTF_Writer.GetTechnique(G, exportableMaterial); GlTF_Technique.Parameter tParam = new GlTF_Technique.Parameter(); tParam.name = name; tParam.type = type; tParam.semantic = semantic; if (node != null) { tParam.node = node; } tech.parameters.Add(tParam); GlTF_Technique.Uniform tUniform = new GlTF_Technique.Uniform(); tUniform.name = "u_" + name; tUniform.param = tParam.name; tech.uniforms.Add(tUniform); }
// Updates glTF technique tech by adding all relevant attributes. // Pass: // mesh - (optional) the attributes of some mesh that uses this material, for sanity-checking. private void AddAllAttributes( GlTF_Technique tech, IExportableMaterial exportableMaterial, GlTF_Attributes mesh) { GlTF_VertexLayout layout = new GlTF_VertexLayout(G, exportableMaterial.VertexLayout); if (mesh != null) { GlTF_VertexLayout meshLayout = mesh.m_layout; if (layout != meshLayout) { if (meshLayout.GetTexcoordSize(2) > 0) { // We funnel timestamps in through GeometryPool.texcoord2 and write them out as // _TB_TIMESTAMP. Thus, the Pool's layout has a texcoord2 but the material's layout does // not. This is a mismatch between the mesh data and the material props, but: // 1. Timestamp isn't intended to be funneled to the material, so it's correct that the // material layoutdoesn't have texcoord2 // 2. It's fine if material attrs are a subset of the mesh attrs // 3. This only affects gltf1; only materials with techniques need to enum their attrs. // Maybe this check should be layout.IsSubset(meshLayout). /* ignore this mismatch */ } else { Debug.LogWarning($"Layout for {exportableMaterial.DurableName} doesn't match mesh's"); } } } // Materials are things that are shared across multiple meshes. // Material creation shouldn't depend on data specific to a particular mesh. // But it does. It's a hack. // Rather than do something reasonable like this: // // Create material's technique's attributes based on layout // Create mesh and its accessors based on layout // // We do this: // // Create mesh and its accessors based on layout // Lazily create the material used by the mesh // Create material's technique's attributes based on the accessors // of the last mesh we created AddAttribute("position", layout.PositionInfo.techniqueType, GlTF_Technique.Semantic.POSITION, tech); if (layout.NormalInfo != null) { AddAttribute("normal", layout.NormalInfo.Value.techniqueType, GlTF_Technique.Semantic.NORMAL, tech); } if (layout.ColorInfo != null) { AddAttribute("color", layout.ColorInfo.Value.techniqueType, GlTF_Technique.Semantic.COLOR, tech); } if (layout.TangentInfo != null) { AddAttribute("tangent", layout.TangentInfo.Value.techniqueType, GlTF_Technique.Semantic.TANGENT, tech); } // TODO: remove; this accessor isn't used. Instead, shaders use texcoord1.w if (layout.PackVertexIdIntoTexcoord1W) { AddAttribute("vertexId", GlTF_Technique.Type.FLOAT /* hardcoded, but this is gong away */, GlTF_Technique.Semantic.UNKNOWN, tech); } for (int i = 0; i < 4; ++i) { var texcoordInfo = layout.GetTexcoordInfo(i); if (texcoordInfo != null) { GlTF_Technique.Semantic semantic = GlTF_Technique.Semantic.TEXCOORD_0 + i; AddAttribute($"texcoord{i}", texcoordInfo.Value.techniqueType, semantic, tech); } } }