godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.16k stars 97 forks source link

Improved LOD importing #7339

Open reduz opened 1 year ago

reduz commented 1 year ago

Describe the project you are working on

Godot

Describe the problem or limitation you are having in your project

While Godot supports importing LOD automatically with meshes, and the current algorithm should kind of more or less work in most cases, it does not in all of them. Sometimes, when the mesh has a certain complexity (like a character, a tree, etc) the current automatic LOD falls short in either quality or performance (as it can't improve past certain level of decimation).

In other words, automatic LOD works for most cases, but not always and it can't be finetuned.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

The idea here is that finetuning options are used for LODs that artists can tweak more easily to ensure a low amount of vertices when the object is far away at the most optimal quality.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Important: This proposal is dependent on #7238 and should be implemented as a continuation, as the ability to preview materials in the viewport is needed for this.

Ideally, the Mesh importer screen should look like this:

image

The LOD option is moved to its own section. Most of the properties in the LOD section should be hidden when parent option is disabled, but they are shown here for context. They are explained as follows:

Viewport Preview

Any changes to LOD settings will trigger regeneration and preview of LOD in the viewport (some progress bar needs to be put somewhere, as this will happen in a thread). There are certain preview options:

Additionally, an option to toggle viewport to wireframe needs to be added.

If this enhancement will not be used often, can it be worked around with a few lines of script?

N/A

Is there a reason why this should be core and not an add-on in the asset library?

N/A

clayjohn commented 1 year ago

Should the HLOD mode also support a "manual" HLOD where the user can specify an artist-created LOD mesh? For certain assets, it may still be worthwhile to support an artist-controlled workflow.

reduz commented 1 year ago

@clayjohn I think that can be done at the scene level already, since its just a VisualInstance property, but my idea here was to add another editor to the mesh importer that is more complex (not just mesh based) where you can select a single mesh as a replacement of multiple ones (as in, all scene going to an impostor or an artist supplied LOD). So its likely a feature that happens more at scene level in the importer in a separate tab.

My idea was calling it "Group Lod" where you can associate multiple meshes to a single other one, even if it also works for one to one.

lyuma commented 1 year ago

Regarding import flow for manually constructed LODs, I would like to propose that we solve that by implementing MSFT_lod, which permits a glTF document to define LOD levels for meshes and materials. https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/MSFT_lod/README.md

It's a good fit for the HLOD workflow, since it is done at import time in the same way: instead of autogenerating these LOD levels, it's just getting them from the glTF document. It may be somewhat lacking in tooling, but that problem tends to resolve itself if it's useful functionality.

As an alternative to (or in addition to) the glTF extension, we could also offer support for naming child mesh nodes whose names are -lod1, -lod2 etc

reduz commented 1 year ago

@lyuma that should be easy to add if someone wants to do it in the GLTF importer.

fire commented 1 year ago

Notes for my future reference:

Octahedral-Impostors has an implementation here https://github.com/wojtekpil/Godot-Octahedral-Impostors

I believe @aaronfranke has contact with @wojtekpil

Merged: It merges all surfaces, renders all materials to texture, generates a new UV unwrap

I proof of concept this scheme several years ago with xatlas unwrap. Is this still a valid texture unwrap method? Maybe there's another. I recall a simple method where each texture sheet is statically tiled.

https://github.com/V-Sekai/godot/tree/vsk-merge-scene

This is in a state where mesh merging almost is restored from Godot Engine 3.0, but is currently broken.

  1. It depends on a unwrapping based on xtlas https://github.com/V-Sekai/godot/commit/bae2cfa96e6cc53af8fae4ed19354e3e5e570436
  2. The code for https://github.com/V-Sekai/godot/blob/vsk-merge-scene/modules/scene_merge/merge.cpp#L260-L324 for baking materials is fairly complicated. I recall you had an rendering based baking method. Can you remind me?
Calinou commented 1 year ago

@cosmoddd Please don't bump issues without contributing significant new information. Use the :+1: reaction button on the first post instead.

mrjustaguy commented 1 year ago

doesn't HLOD also make sense to kick in based on the same heuristics as ALOD (namely relative size on screen) instead of just a fixed distance from camera which is what I'm guessing the Distance is, or am I getting something wrong here?

atirut-w commented 1 year ago

Not sure how they meant it to work in Godot, but Unity uses on-screen size IIRC. Sounds like a better approach in my opinion.

Calinou commented 1 year ago

doesn't HLOD also make sense to kick in based on the same heuristics as ALOD (namely relative size on screen) instead of just a fixed distance from camera which is what I'm guessing the Distance is, or am I getting something wrong here?

HLOD generally requires manual control to look best, as it also works best with artist-authored LODs. Also, how do you compute the on-screen size for HLOD nodes? Remember that these can be adjuted in real-time with no baking.

If you need automatic distance threshold adjusment based on resolution or FOV, this can be done with a script once https://github.com/godotengine/godot-proposals/issues/3787 is implemented. (This could also be implemented in core with similar logic, but I'm not sure if it can be done without breaking split screen support if each camera uses a different FOV.)

atirut-w commented 1 year ago

Also, how do you compute the on-screen size for HLOD nodes?

In pixels? That way, the quality also scales with resolution.

Calinou commented 1 year ago

In pixels? That way, the quality also scales with resolution.

I don't mean the unit, but how do you compute it considering the content of HLODs is not necessarily a single mesh? It can be any node inheriting from GeometryInstance3D, which includes particles (CPUParticles and GPUParticles), etc. It can also be multiple mesh nodes, a MultiMeshInstance3D, …

I haven't checked the mesh LOD detection for LOD selection – does it only use a AABB size or something more elaborate?

atirut-w commented 1 year ago

I don't mean the unit, but how do you compute it considering the content of HLODs is not necessarily a single mesh?

I see. I'd personally go for the quick and dirty method of using AABB, but there are clearly better methods out there. Maybe combine the screen area taken by just the meshes? Maybe do it on a per-mesh basis?

fire commented 1 year ago

updated port of imposters to Godot 4: https://github.com/wojtekpil/Godot-Octahedral-Impostors/issues/20

Rytelier commented 7 months ago

I've been researching around LODs lately so I'll add few things to the proposal:

Calinou commented 7 months ago
  • Crossfade animation where one mesh is fades then other mesh unfades. Use alpha dithering or hashing. Make it a tween instead of position based, so it doesn't get stuck in the middle of fading at certain camera positions.

This is about LOD rendering, not importing (this proposal is purely focused on importing). It's also tracked in another proposal: https://github.com/godotengine/godot-proposals/issues/5240

  • Global setting for HLOD distance (that can be easily changed in game too), where in the mesh settings user sets the multiplier for it.

This is also about rendering, and it's being tracked in https://github.com/godotengine/godot-proposals/issues/3787.

fire commented 7 months ago

I've been improving the lod generation https://github.com/godotengine/godot/pull/90180