以下示例使用任意三角形定义(顶点和连接矩阵)生成 3D 对象。 https://gitlab.com/dodgyville/pygltflib#create-a-mesh-convert-to-bytes-convert-back-to-mesh
如何为顶点设置自定义颜色?
就像在这个 matlab 库中一样:https://www.mathworks.com/matlabcentral/fileexchange/109264-matlab2glb
带有顶点颜色定义的 Matlab 示例代码:
example.POSITION = [0 0 0; 1 0 0; 1 1 0; 0 1 0; 0 0 1; 1 0 1; 1 1 1; 0 1 1];
example.indices = [1 4 2; 4 3 2; 3 7 2; 7 6 2; 3 4 7; 4 8 7; 8 5 7; 5 6 7; 5 2 6; 5 1 2; 1 5 4; 5 8 4];
example.COLOR_0 = [1 0 0; 0.5 0.5 0.5; 0.5 0.5 0.5; 0.5 0.5 0.5; 0.5 0.5 0.5; 0.5 0.5 0.5; 0 1 0; 0.5 0.5 0.5];
example.prop.material.pbrMetallicRoughness.baseColorFactor = [0.7 0.7 1 0.5];
example.prop.material.pbrMetallicRoughness.metallicFactor = 1;
example.prop.material.pbrMetallicRoughness.roughnessFactor = 0.1;
example.prop.material.alphaMode = 'BLEND';
example.prop.material.doubleSided = true;
write_glb('example.glb', example);
对于顶点上的颜色,您需要将其定义为每个顶点的 RGB 向量,类似于
pygltflib
中每个顶点的 x,y,z
对于您的数据,我创建了一个示例代码来使用
gltf
创建 pygltflib
文件,如下所示。
我从
here获取了
wavefront
obj到gltf
的转换代码
并根据您的用例和数据进行调整
import sys
import os
import traceback
import numpy as np
from pygltflib import *
if __name__ == "__main__":
output_path = "/content/sample_data/square.glb"
# instantiate GLTF2
gltf = GLTF2()
gltf.asset = Asset()
gltf.scenes = [Scene()]
gltf.nodes = [Node()] # Mesh node
gltf.meshes = [Mesh()]
gltf.accessors = [Accessor() for _ in range(3)] # faces, vertices, v_colors
gltf.materials = [Material()]
gltf.bufferViews = [BufferView() for _ in range(3)]
gltf.buffers = [Buffer()]
# asset
gltf.asset = Asset()
# scene
gltf.scene = 0
# vertices
vertices_lst = [[0.0 ,0.0 ,0.0],[1.0 ,0.0, 0.0],[1.0, 1.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 0.0, 1.0],[1.0, 1.0, 1.0],[0.0, 1.0, 1.0]]
# faces indices
faceindices_lst = [[1,4,2], [4,3,2], [3,7,2], [7,6,2], [3,4,7], [4,8,7], [8,5,7], [5,6,7], [5,2,6], [5,1,2], [1,5,4], [5,8,4]]
# colors
vertices_colors_lst = [[1,0,0],[0.5,0.5,0.5],[0.5,0.5,0.5],[0.5,0.5,0.5],[0.5,0.5,0.5],[0.5,0.5,0.5],[0,1,0],[0.5,0.5,0.5]]
# convert colorlist to np.array
vertices_colors_nparray = np.array([np.array(xi) for xi in vertices_colors_lst])
# store faces
indices_chunk = b""
for f in faceindices_lst:
indices_chunk += struct.pack("<III", *f)
gltf.bufferViews[0].buffer = 0
gltf.bufferViews[0].byteOffset = 0
gltf.bufferViews[0].byteLength = len(indices_chunk)
gltf.bufferViews[0].target = ELEMENT_ARRAY_BUFFER
gltf.accessors[0].bufferView = 0
gltf.accessors[0].byteOffset = 0
gltf.accessors[0].componentType = UNSIGNED_INT
gltf.accessors[0].normalized = False
gltf.accessors[0].count = len(faceindices_lst) * 3
gltf.accessors[0].type = "SCALAR"
# store vertices
vertices_chunk = b""
for v in vertices_lst:
vertices_chunk += struct.pack("<fff", *v)
gltf.bufferViews[1].buffer = 0
gltf.bufferViews[1].byteOffset = gltf.bufferViews[0].byteLength
gltf.bufferViews[1].byteLength = len(vertices_chunk)
gltf.bufferViews[1].target = ARRAY_BUFFER
gltf.accessors[1].bufferView = 1
gltf.accessors[1].byteOffset = 0
gltf.accessors[1].componentType = FLOAT
gltf.accessors[1].normalized = False
gltf.accessors[1].count = len(vertices_lst)
gltf.accessors[1].type = "VEC3"
gltf.accessors[1].max = list(np.max(np.array(vertices_lst).T, axis=1)) # get the max value for each xyz
gltf.accessors[1].min = list(np.min(np.array(vertices_lst).T, axis=1))
# store vertex colors
vcolor_chunk = b""
for vc in vertices_colors_nparray:
vc_rgb = vc[:3]
vcolor_chunk += struct.pack("<fff", *vc_rgb)
gltf.bufferViews[2].buffer = 0
gltf.bufferViews[2].byteOffset = gltf.bufferViews[1].byteOffset + gltf.bufferViews[1].byteLength
gltf.bufferViews[2].byteLength = len(vcolor_chunk)
gltf.bufferViews[2].target = ARRAY_BUFFER
gltf.accessors[2].bufferView = 2
gltf.accessors[2].byteOffset = 0
gltf.accessors[2].componentType = FLOAT
gltf.accessors[2].normalized = False
gltf.accessors[2].count = len(vertices_colors_nparray)
gltf.accessors[2].type = "VEC3"
# store buffer data
gltf.identify_uri = BufferFormat.BINARYBLOB
gltf._glb_data = indices_chunk + vertices_chunk + vcolor_chunk
gltf.buffers[0].byteLength = gltf.bufferViews[2].byteOffset + gltf.bufferViews[2].byteLength
# mesh
gltf.meshes[0].primitives = [
Primitive(
attributes=Attributes(
POSITION=1,
#NORMAL=3,
COLOR_0=2,
),
indices=0,
material=0
)
]
gltf.meshes[0].name = "Mesh"
# assemble nodes
gltf.nodes[0].mesh = 0
gltf.nodes[0].name = "Mesh"
gltf.scenes[0].nodes = [0]
# export
gltf.save_binary(output_path)
感谢您提供的示例。我通过在颜色列表中添加 alpha 值进行了一些修改,但是 alpha 值无法识别并且透明度不起作用。有人可以帮助告诉我如何使用 pygltflib 实现透明度吗?预先感谢。
import sys
import os
import traceback
import numpy as np
from pygltflib import *
if __name__ == "__main__":
output_path = "square.glb"
# instantiate GLTF2
gltf = GLTF2()
gltf.asset = Asset()
gltf.scenes = [Scene()]
gltf.nodes = [Node()] # Mesh node
gltf.meshes = [Mesh()]
gltf.accessors = [Accessor() for _ in range(3)] # faces, vertices, v_colors
#gltf.materials = [Material()]
gltf.bufferViews = [BufferView() for _ in range(3)]
gltf.buffers = [Buffer()]
# asset
gltf.asset = Asset()
# scene
gltf.scene = 0
# vertices
vertices_lst = [[0.0 ,0.0 ,0.0],[1.0 ,0.0, 0.0],[1.0, 1.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 0.0, 1.0],[1.0, 1.0, 1.0],[0.0, 1.0, 1.0]]
faceindices_lst = [[1,4,2], [4,3,2], [3,7,2], [7,6,2], [3,4,7], [4,6,7], [6,5,7], [5,6,7], [5,2,6], [5,1,2], [1,5,4], [5,6,4]]
# colors
#vertices_colors_lst = [[1,0,0],[0.5,0.5,0.5],[0.5,0.5,0.5],[0.5,0.5,0.5],[0.5,0.5,0.5],[0.5,0.5,0.5],[0,1,0],[0.5,0.5,0.5]]
#vertices_colors_lst = [[1,0,0, 0.1],[0.5,0.5,0.5,0.1],[0.5,0.5,0.5, 0.1],[0.5,0.5,0.5, 0.1],[0.5,0.5,0.5,0.1],[0.5,0.5,0.5,0.1],[0,1,0, 0.1],[0.5,0.5,0.5,0.1]]
vertices_colors_lst = [[1,0,0, 0.9],[0.5,0.5,0.5,0.9],[0.5,0.5,0.5, 0.9],[0.5,0.5,0.5, 0.9],[0.5,0.5,0.5,0.9],[0.5,0.5,0.5,0.9],[0,1,0, 0.9],[0.5,0.5,0.5,0.9]]
# convert colorlist to np.array
vertices_colors_nparray = np.array([np.array(xi) for xi in vertices_colors_lst])
# store faces
indices_chunk = b""
for f in faceindices_lst:
indices_chunk += struct.pack("<III", *f)
gltf.bufferViews[0].buffer = 0
gltf.bufferViews[0].byteOffset = 0
gltf.bufferViews[0].byteLength = len(indices_chunk)
gltf.bufferViews[0].target = ELEMENT_ARRAY_BUFFER
gltf.accessors[0].bufferView = 0
gltf.accessors[0].byteOffset = 0
gltf.accessors[0].componentType = UNSIGNED_INT
gltf.accessors[0].normalized = False
gltf.accessors[0].count = len(faceindices_lst) * 3
gltf.accessors[0].type = "SCALAR"
# store vertices
vertices_chunk = b""
for v in vertices_lst:
vertices_chunk += struct.pack("<fff", *v)
gltf.bufferViews[1].buffer = 0
gltf.bufferViews[1].byteOffset = gltf.bufferViews[0].byteLength
gltf.bufferViews[1].byteLength = len(vertices_chunk)
gltf.bufferViews[1].target = ARRAY_BUFFER
gltf.accessors[1].bufferView = 1
gltf.accessors[1].byteOffset = 0
gltf.accessors[1].componentType = FLOAT
gltf.accessors[1].normalized = False
gltf.accessors[1].count = len(vertices_lst)
gltf.accessors[1].type = "VEC3"
gltf.accessors[1].max = list(np.max(np.array(vertices_lst).T, axis=1)) # get the max value for each xyz
gltf.accessors[1].min = list(np.min(np.array(vertices_lst).T, axis=1))
# store vertex colors
vcolor_chunk = b""
for vc in vertices_colors_nparray:
#print("vc", vc)
vc_rgb = vc[:4]
vcolor_chunk += struct.pack("<ffff", *vc_rgb)
gltf.bufferViews[2].buffer = 0
gltf.bufferViews[2].byteOffset = gltf.bufferViews[1].byteOffset + gltf.bufferViews[1].byteLength
gltf.bufferViews[2].byteLength = len(vcolor_chunk)
gltf.bufferViews[2].target = ARRAY_BUFFER
gltf.accessors[2].bufferView = 2
gltf.accessors[2].byteOffset = 0
gltf.accessors[2].componentType = FLOAT
gltf.accessors[2].normalized = False
gltf.accessors[2].count = len(vertices_colors_nparray)
gltf.accessors[2].type = "VEC4"
#materials
material = Material()
pbr = PbrMetallicRoughness() # Use PbrMetallicRoughness
#pbr.baseColorFactor = [1.0, 0.0, 0.0, 1.0] # solid red
material.pbrMetallicRoughness = pbr
material.doubleSided = True # make material double sided
material.alphaMode = MASK # to get around 'MATERIAL_ALPHA_CUTOFF_INVALID_MODE' warning
material.alphaCutoff=None
# store buffer data
gltf.identify_uri = BufferFormat.BINARYBLOB
gltf._glb_data = indices_chunk + vertices_chunk + vcolor_chunk
gltf.buffers[0].byteLength = gltf.bufferViews[2].byteOffset + gltf.bufferViews[2].byteLength
# mesh
gltf.meshes[0].primitives = [
Primitive(
attributes=Attributes(
POSITION=1,
#NORMAL=3,
COLOR_0=2,
),
indices=0,
material=0
)
]
gltf.meshes[0].name = "Mesh"
gltf.materials.append(material)
# assemble nodes
gltf.nodes[0].mesh = 0
gltf.nodes[0].name = "Mesh"
gltf.scenes[0].nodes = [0]
# export
gltf.save_binary(output_path)