Closed wangchong666 closed 1 year ago
I have unit tests that verify that shared materials are duplicated, so you may be doing something odd.
I would need to see a working example to be able to solve the problem.
@vpenades Thanks for reply. Example:
using SharpGLTF.Geometry;
using SharpGLTF.Materials;
using SharpGLTF.Schema2;
using System;
using System.Numerics;
using VERTEX = SharpGLTF.Geometry.VertexTypes.VertexPosition;
var red = new MaterialBuilder()
.WithDoubleSide(true)
.WithMetallicRoughness(0.9f, 0.1f)
.WithMetallicRoughnessShader()
.WithChannelParam(KnownChannel.BaseColor, KnownProperty.RGBA, new Vector4(1, 0, 0, 1));
var model = ModelRoot.CreateModel();
var scene = model.UseScene(0);
var rootNode = scene.CreateNode("root");
var mesh = new MeshBuilder<VERTEX>("mesh1");
var prim = mesh.UsePrimitive(red);
prim.AddTriangle(new VERTEX(-10, 0, 0), new VERTEX(10, 0, 0), new VERTEX(0, 10, 0));
prim.AddTriangle(new VERTEX(10, 0, 0), new VERTEX(-10, 0, 0), new VERTEX(0, -10, 0));
rootNode.CreateNode("1").WithMesh(model.CreateMeshes(mesh).First());
var mesh2 = new MeshBuilder<VERTEX>("mesh2");
prim = mesh2.UsePrimitive(red);
prim.AddQuadrangle(new VERTEX(-5, 0, 3), new VERTEX(0, -5, 3), new VERTEX(5, 0, 3), new VERTEX(0, 5, 3));
rootNode.CreateNode("1").WithMesh(model.CreateMeshes(mesh2).First());
// create a scene
model.SaveAsWavefront("mesh.obj");
model.SaveGLB("mesh.glb");
model.SaveGLTF("mesh.gltf");
GLTF:
{
"asset": {
"copyright": "",
"generator": "SharpGLTF 1.0.0-alpha0027",
"version": "2.0"
},
"accessors": [
{
"name": "POSITION",
"bufferView": 0,
"componentType": 5126,
"count": 4,
"max": [
10,
10,
0
],
"min": [
-10,
-10,
0
],
"type": "VEC3"
},
{
"bufferView": 1,
"componentType": 5123,
"count": 6,
"type": "SCALAR"
},
{
"name": "POSITION",
"bufferView": 2,
"componentType": 5126,
"count": 4,
"max": [
5,
5,
3
],
"min": [
-5,
-5,
3
],
"type": "VEC3"
},
{
"bufferView": 3,
"componentType": 5123,
"count": 6,
"type": "SCALAR"
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 48,
"byteStride": 12,
"target": 34962
},
{
"buffer": 0,
"byteLength": 12,
"byteOffset": 96,
"target": 34963
},
{
"buffer": 0,
"byteLength": 48,
"byteOffset": 48,
"byteStride": 12,
"target": 34962
},
{
"buffer": 0,
"byteLength": 12,
"byteOffset": 108,
"target": 34963
}
],
"buffers": [
{
"byteLength": 120,
"uri": "mesh.bin"
}
],
"materials": [
{
"doubleSided": true,
"pbrMetallicRoughness": {
"baseColorFactor": [
1,
0,
0,
1
],
"metallicFactor": 0.8999999761581421,
"roughnessFactor": 0.10000000149011612
}
},
{
"doubleSided": true,
"pbrMetallicRoughness": {
"baseColorFactor": [
1,
0,
0,
1
],
"metallicFactor": 0.8999999761581421,
"roughnessFactor": 0.10000000149011612
}
}
],
"meshes": [
{
"name": "mesh1",
"primitives": [
{
"attributes": {
"POSITION": 0
},
"indices": 1,
"material": 0
}
]
},
{
"name": "mesh2",
"primitives": [
{
"attributes": {
"POSITION": 2
},
"indices": 3,
"material": 1
}
]
}
],
"nodes": [
{
"name": "root",
"children": [
1,
2
]
},
{
"name": "1",
"mesh": 0
},
{
"name": "1",
"mesh": 1
}
],
"scenes": [
{
"nodes": [
0
]
}
]
}
emm, this work fine.
foreach(var m in model.CreateMeshes(mesh, mesh2))
{
rootNode.CreateNode("1").WithMesh(m);
}
Okey, the problem here is that you're using MeshBuilder to create a mesh and add it directly to gltf Model. When you do that, the material is converted from Toolkit.MaterialBuilder to Schema2.Material, which is a totally different thing and it's no longer possible to compare materials, producing duplications.
As you've discovered, you have one option, which is to call CreateMeshes with multiple meshes, in which case material duplication is resolved between these meshes before converting them.
The other option is that you use SceneBuilder and NodeBuilder, and at the very end, convert SceneBuilder to glTF.
If use SceneBuilder and NodeBuilder ,I must create a mesh for each node,In my case , so many nodes share one mesh.
No, you don't need to create a mesh for each node. within SceneBuilder, meshes and materials are always shared.
Sharing resources is precisely the purpose of SceneBuilder and all *Builder classes.
Describe the bug duplicate materials
To Reproduce create a material
create some mesh with this material
gltf file:
It generate one material per mesh please complete the following information: