Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework Mesh handling on scene importing. #44319

Merged
merged 1 commit into from
Dec 14, 2020

Conversation

reduz
Copy link
Member

@reduz reduz commented Dec 12, 2020

-Reworked how meshes are treated by importer by using EditorSceneImporterMesh and EditorSceneImporterMeshNode. Instead of Mesh and MeshInstance, this allows more efficient processing of meshes before they are actually registered in the RenderingServer.
-Integrated MeshOptimizer
-Reworked internals of SurfaceTool to use arrays, making it more performant and easy to run optimizatons on.

@reduz reduz force-pushed the integrate-meshoptimizer branch 4 times, most recently from aa8ae4b to 1a09a20 Compare December 12, 2020 13:16
@@ -1440,7 +1444,8 @@ Error EditorSceneImporterGLTF::_parse_materials(GLTFState &state) {
if (d.has("name")) {
material->set_name(d["name"]);
}
material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
//don't do this here only if vertex color exists
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since the albedo code was touched i have to reverify that the test cases don't regress #21087 (comment)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This flag is less optimal if turned on, so I only make it on when needed

if (surfaces[i].lods.size()) {
Dictionary lods;
for (int j = 0; j < surfaces[i].lods.size(); j++) {
lods[surfaces[i].lods[j].distance] = surfaces[i].lods[j].indices;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Distance or screen coverage?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Distance

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All this will be generated internally in Godot, the extensions in GLTF will be ignored

} else {
idx = *idxptr;
}

index_array.push_back(idx);
}

vertex_array.clear();
vertex_array = new_vertices;

format |= Mesh::ARRAY_FORMAT_INDEX;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will you be adding a quantized mesh format? You'd have to read up what gltf quantized requires. KhronosGroup/glTF#1670

Copy link
Member

@fire fire Dec 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, we do our own optimizations on import

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EXT GPU Instancing can be supported with a multimesh, but to be honest all this stuff seem like unsupported by authoring software anyway

Copy link
Member

@fire fire Dec 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be clear, I'm asking about the benefit of smaller in memory sizes for meshes. I don't think it's possible to use a smaller type for vertices. [Since you decided to only have have one (compressed) mesh format.]

As an example, a static PBR-ready mesh typically requires POSITION (12 bytes), TEXCOORD (8 bytes), NORMAL (12 bytes) and TANGENT (16 bytes) for each vertex, for a total of 48 bytes. With this extension, it is possible to use SHORT to store position and texture coordinate data (8 and 4 bytes, respectively) and BYTE to store normal and tangent data (4 bytes each), for a total of 20 bytes per vertex with often negligible quality impact.

Copy link
Member Author

@reduz reduz Dec 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Godot 4.0 uses:

  • 12 bytes for position. At some point we added quantizing for this as optional, but it just generally looks bad and users had a lot of problems. Meshes had visible seams, small details get deformed easily, etc. Its just not worh it.
  • 4 bytes for normal (Godot 4.0 uses ARGB2101010)
  • 4 bytes for tangent (also ARGB2101010)
  • 8 bytes for UV. Again, we s upported having less, but to be honest users nowadays mostly use larger textures than 1024, so using half float for UV looks pretty terrible.

This way, Godot uses 12+4+4+8=28 bytes per vertex instead of 20. Its honestly not much of a problem and things just work.

ClassDB::bind_method(D_METHOD("optimize_indices_for_cache"), &SurfaceTool::optimize_indices_for_cache);

ClassDB::bind_method(D_METHOD("get_max_axis_length"), &SurfaceTool::get_max_axis_length);
ClassDB::bind_method(D_METHOD("generate_lod", "nd_threshold", "target_index_count"), &SurfaceTool::generate_lod, DEFVAL(3));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nd_threshold is confusing to people who don't read documentation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't understand this without reading doc anyway

@reduz reduz force-pushed the integrate-meshoptimizer branch 2 times, most recently from ac84242 to 93017fe Compare December 13, 2020 03:04
Copy link
Member

@akien-mga akien-mga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, but please document the provenance, release or commit, and update steps for meshoptimizer in thirdparty/README.md.

-Reworked how meshes are treated by importer by using EditorSceneImporterMesh and EditorSceneImporterMeshNode. Instead of Mesh and MeshInstance, this allows more efficient processing of meshes before they are actually registered in the RenderingServer.
-Integrated MeshOptimizer
-Reworked internals of SurfaceTool to use arrays, making it more performant and easy to run optimizatons on.
@akien-mga akien-mga merged commit fe49eaa into godotengine:master Dec 14, 2020
@akien-mga
Copy link
Member

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants