Open mikeoverbay opened 1 week ago
And don't see any problem in your code have you tried to load the model in babylonJS as recomended?
First vpenades, thank you!! I understand the person you are! I write tools for World of Tanks. I also share it freely. I'm adding your tools to my app! I'll put it on a splash screen with the others at some point. I say I a lot LOL
Yes.. I have tried it in every online glTF viewer I can find. It simply isn't creating or adding them to the attribute. Blender shows No color attribute. I'm creating rigid node meshes, I Wonder if it thinks vertex color is a morph control? These functions need tested by someone to verify what I'm getting.
I'm not using a NodeBuilder. I don't understand how to. Examples of writing out existing model data is hard to find.
vertex colors, when they're defined, are automatically blended with the material's color, it has nothing to do with morph control.
Have you verified the glTF being written, actually has vertex colors attributes?
Vertex colors should be part of the material stack. This is true and yes, every viewer blends them with Base color. The models in world of tanks uses them as morph controls. They uses a file format that can't be opened any any thing but their game and my app. It's used by people to customize the tanks. it's limited because of what I can put in a FBX file. I have tried everything. They also use a 2nd color as a indexing of some kind. I have never tried to find out how they use them. The app I have been working on converts the formats back and forth. I uploaded a couple to my server. here
I really need some help with this. Its the ideal way to transport files for what I'm doing but I can not get vertex colors out to the file.
With the little information you've provided, it's impossible for me to help you. glTF is complex, and I am extremely busy at work. I barely have an hour per week to attend requests.
I suggest you to look into the sharpGLTF unit tests code, specifically the MeshBuilder tests, I think some tests show how to use color and textures in the vertices.
I understand the time issue. I'll dig more. Thanks!
I found it! This is important for each vertex type. I missed it somehow.
'I create them as objects before so they can be redefined.
MyMeshBuilder = New MeshBuilder(Of VertexPositionNormal, VertexColor1Texture1, VertexEmpty)(model_name)
prim = MyMeshBuilder.UsePrimitive(MyMaterialBuilder)
MyMeshBuilder = New MeshBuilder(Of VertexPositionNormal, VertexColor2Texture2, VertexEmpty)(model_name)
prim = MyMeshBuilder.UsePrimitive(MyMaterialBuilder)
MyMeshBuilder = New MeshBuilder(Of VertexPositionNormal, VertexTexture1, VertexEmpty)(model_name)
prim = MyMeshBuilder.UsePrimitive(MyMaterialBuilder)
here is the entire sub for those that need it. I would make this more visible for noobs like me :)
Public Sub write_glTF()
Dim ar() As String
If PRIMITIVES_MODE Then
ar = Path.GetFileNameWithoutExtension(frmMain.OpenFileDialog1.FileName).Split("~")
Else
ar = TANK_NAME.Split(":")
End If
frmMain.SaveFileDialog1.InitialDirectory = My.Settings.GLTF_path
frmMain.SaveFileDialog1.Filter = "glb|*.glb"
frmMain.SaveFileDialog1.Title = "Save glb.."
frmMain.SaveFileDialog1.FileName = Path.GetFileName(ar(0)) + ".glb"
frmMain.SaveFileDialog1.AddExtension = True
frmMain.SaveFileDialog1.RestoreDirectory = True
Dim result = frmMain.SaveFileDialog1.ShowDialog
Dim out_path = frmMain.SaveFileDialog1.FileName
My.Settings.fbx_path = out_path
My.Settings.Save()
'file_name = current_tank_name
If Not result = DialogResult.OK Then
Return
End If
My.Settings.GLTF_path = out_path
Dim name As String = Path.GetFileName(ar(0))
Dim save_path = Path.GetDirectoryName(out_path) + "\" + name
export_fbx_textures(False, 1) 'export all textures. converts from dds to png.
Dim MySceneBuilder As New SceneBuilder()
MySceneBuilder.Name = name
' Create a root node
For item = 1 To object_count
Dim extras As New ExtrasData()
' Create a material and assign texture maps if available
Dim MyMaterialBuilder As New MaterialBuilder("Material00" + item.ToString) With {.ShaderStyle = "PBRMetallicRoughness"}
Dim baseColorTexture = save_path + "\" + Path.GetFileNameWithoutExtension(_group(item).color_name.Replace("\tracks", "")) + ".png"
Dim aoTexture As String = save_path + "\" + Path.GetFileNameWithoutExtension(_group(item).ao_name.Replace("\tracks", "")) + ".png"
Dim metalRoughTexture = save_path + "\" + Path.GetFileNameWithoutExtension(_group(item).metalGMM_name.Replace("\tracks", "")) + ".png"
Dim normalTexture = save_path + "\" + Path.GetFileNameWithoutExtension(_group(item).normal_name.Replace("\tracks", "")) + ".png"
' Assign Base Color Texture if exists
If Not String.IsNullOrEmpty(baseColorTexture) Then
Try
MyMaterialBuilder.WithBaseColor(baseColorTexture)
Catch ex As Exception
End Try
End If
' Check its there!
If Not String.IsNullOrEmpty(aoTexture) Then
Try
MyMaterialBuilder.WithOcclusion(aoTexture)
Catch ex As Exception
End Try
End If
' Assign Metallic and Roughness Texture if exists
If Not String.IsNullOrEmpty(metalRoughTexture) Then
' GLTF PBR Metallic-Roughness uses a combined texture with metallic in the B channel and roughness in the G channel
Try
MyMaterialBuilder.WithMetallicRoughness(metalRoughTexture)
Catch ex As Exception
End Try
End If
' Assign Normal Map if exists
If Not String.IsNullOrEmpty(normalTexture) Then
Try
MyMaterialBuilder.WithNormal(normalTexture)
Catch ex As Exception
End Try
End If
Dim off = _group(item).startVertex_
Dim model_name = _group(item).name.Replace("/", "\")
model_name = model_name.Replace(":", "~")
model_name = model_name.Replace("vehicles\", "")
model_name = model_name.Replace("primitives_processed", "pri")
model_name = model_name.Replace("\lod0\", "\l\")
Dim MyMeshBuilder As Object
Dim prim As Object
If Not _group(item).has_uv2 = 1 And _group(item).has_color = 1 Then
MyMeshBuilder = New MeshBuilder(Of VertexPositionNormal, VertexColor1Texture1, VertexEmpty)(model_name)
prim = MyMeshBuilder.UsePrimitive(MyMaterialBuilder)
' Handle vertices with color and single texture coordinates
Dim vertices As New List(Of VertexBuilder(Of VertexPositionNormal, VertexColor1Texture1, VertexEmpty))()
For i As UInt32 = 0 To _group(item).nVertices_ - 1
Dim color1 = New Vector4(_group(item).vertices(i).r, _group(item).vertices(i).g, _group(item).vertices(i).b, _group(item).vertices(i).a)
Dim v As New VertexBuilder(Of VertexPositionNormal, VertexColor1Texture1, VertexEmpty)(
New VertexPositionNormal(
New Vector3(_group(item).vertices(i).x, _group(item).vertices(i).y, _group(item).vertices(i).z),
New Vector3(_group(item).vertices(i).nx, _group(item).vertices(i).ny, _group(item).vertices(i).nz)
),
New VertexColor1Texture1(color1, New Vector2(_group(item).vertices(i).u, _group(item).vertices(i).v))
)
vertices.Add(v)
Next
' Create mesh primitives using triangle indices
For i As UInt32 = 1 To _group(item).nPrimitives_
prim.AddTriangle(
vertices(_group(item).indices(i).v1 - off),
vertices(_group(item).indices(i).v2 - off),
vertices(_group(item).indices(i).v3 - off)
)
Next
ElseIf _group(item).has_uv2 = 1 Then
MyMeshBuilder = New MeshBuilder(Of VertexPositionNormal, VertexColor2Texture2, VertexEmpty)(model_name)
prim = MyMeshBuilder.UsePrimitive(MyMaterialBuilder)
' Handle vertices with two colors and two sets of texture coordinates
Dim vertices As New List(Of VertexBuilder(Of VertexPositionNormal, VertexColor2Texture2, VertexEmpty))()
For i As UInt32 = 0 To _group(item).nVertices_ - 1
Dim color1 = New Vector4(_group(item).vertices(i).r, _group(item).vertices(i).g, _group(item).vertices(i).b, _group(item).vertices(i).a)
Dim color2 = New Vector4(_group(item).vertices(i).ir, _group(item).vertices(i).ig, _group(item).vertices(i).ib, _group(item).vertices(i).ia)
Dim v As New VertexBuilder(Of VertexPositionNormal, VertexColor2Texture2, VertexEmpty)(
New VertexPositionNormal(
New Vector3(_group(item).vertices(i).x, _group(item).vertices(i).y, _group(item).vertices(i).z),
New Vector3(_group(item).vertices(i).nx, _group(item).vertices(i).ny, _group(item).vertices(i).nz)
),
New VertexColor2Texture2(color1, color2, New Vector2(_group(item).vertices(i).u, _group(item).vertices(i).v), New Vector2(_group(item).vertices(i).u2, _group(item).vertices(i).v2))
)
vertices.Add(v)
Next
' Create mesh primitives using triangle indices
For i As UInt32 = 1 To _group(item).nPrimitives_
prim.AddTriangle(
vertices(_group(item).indices(i).v1 - off),
vertices(_group(item).indices(i).v2 - off),
vertices(_group(item).indices(i).v3 - off)
)
Next
ElseIf Not _group(item).has_color = 1 Then
MyMeshBuilder = New MeshBuilder(Of VertexPositionNormal, VertexTexture1, VertexEmpty)(model_name)
prim = MyMeshBuilder.UsePrimitive(MyMaterialBuilder)
' Handle vertices with only position, normal, and texture coordinates
Dim vertices As New List(Of VertexBuilder(Of VertexPositionNormal, VertexTexture1, VertexEmpty))()
For i As UInt32 = 0 To _group(item).nVertices_ - 1
Dim v As New VertexBuilder(Of VertexPositionNormal, VertexTexture1, VertexEmpty)(
New VertexPositionNormal(
New Vector3(_group(item).vertices(i).x, _group(item).vertices(i).y, _group(item).vertices(i).z),
New Vector3(_group(item).vertices(i).nx, _group(item).vertices(i).ny, _group(item).vertices(i).nz)
),
New VertexTexture1(New Vector2(_group(item).vertices(i).u, _group(item).vertices(i).v))
)
vertices.Add(v)
Next
' Create mesh primitives using triangle indices
For i As UInt32 = 1 To _group(item).nPrimitives_
prim.AddTriangle(
vertices(_group(item).indices(i).v1 - off),
vertices(_group(item).indices(i).v2 - off),
vertices(_group(item).indices(i).v3 - off)
)
Next
End If
' Create a node and add the mesh to it
' Convert the matrix directly from _group(item).matrix to System.Numerics.Matrix4x4
Dim matrix As New Matrix4x4(
_object(item).matrix(0), _object(item).matrix(1), _object(item).matrix(2), _object(item).matrix(3),
_object(item).matrix(4), _object(item).matrix(5), _object(item).matrix(6), _object(item).matrix(7),
_object(item).matrix(8), _object(item).matrix(9), _object(item).matrix(10), _object(item).matrix(11),
_object(item).matrix(12), _object(item).matrix(13), _object(item).matrix(14), _object(item).matrix(15)
)
matrix.M11 *= -1.0
If _object(item).name.ToLower.Contains("turret") Or _object(item).name.ToLower.Contains("gun") Then
matrix.M41 *= -1.0
End If
' Create a dictionary to hold the texture paths
Dim texturePaths As New Dictionary(Of String, String)
'save the actual parts name in the game
Dim lts As String = _group(item).long_tank_name
texturePaths.Add("rootfolder", lts)
' Collect the full texture paths for PBR textures
If Not String.IsNullOrEmpty(baseColorTexture) Then
texturePaths.Add("baseColorTexture", baseColorTexture)
End If
If Not String.IsNullOrEmpty(aoTexture) Then
texturePaths.Add("aoTexture", aoTexture)
End If
If Not String.IsNullOrEmpty(metalRoughTexture) Then
texturePaths.Add("metalRoughTexture", metalRoughTexture)
End If
If Not String.IsNullOrEmpty(normalTexture) Then
texturePaths.Add("normalTexture", normalTexture)
End If
Dim jsonExtras As JsonNode = JsonNode.Parse(JsonSerializer.Serialize(texturePaths))
Dim affineTransform As AffineTransform = AffineTransform.CreateDecomposed(matrix)
' Attach the extras data to the empty node
MyMeshBuilder.Extras = jsonExtras
' Add the node to the scene
MySceneBuilder.AddRigidMesh(MyMeshBuilder, affineTransform)
Next
' Add the root node to the scene
' Save the scene to a GLTF file with settings
Dim settings As New SharpGLTF.Schema2.WriteSettings
settings.JsonIndented = True
settings.ImageWriting = ResourceWriteMode.Default
settings.MergeBuffers = False
MySceneBuilder.ToGltf2().SaveGLB(out_path, settings)
End Sub
This is how I create my vertex data. It throws no errors but the vertex colors are not being loading in blender 4.1 or any app. Any Ideas?