Skip to content

Add GEO_LOD vendor extension for per-part LOD #2500

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

andybushnell
Copy link

In visual-simulation toolchains (e.g. OpenFlight/Aechelon/Geo STUDIO), it’s routine to define per-part LOD variants directly in the model hierarchy. You might have a tank’s chassis split into high/med/low meshes under one grouping node, its turret under another, its wheels under yet another—all within a single file. No “root-only” swapping, and no need to carve your model into separate glTFs for each LOD.
By contrast, glTF’s built-in LOD patterns (e.g. MSFT_lod) expect a single node that is the LOD switcher, listing mesh indices. That works, but it can’t express “here’s a chassis, with three mesh children,” or “here’s a turret behavior, with its own LOD children,” in one neat file.
Enter GEO_LOD—a small vendor extension that you attach to any grouping node (having no mesh of its own) whose children (the entire sub-tree parented by the LOD node) are considered the LOD variant for that part. Your loader/runtime software then simply activates that LOD node (and its children) based on it passing the distance or screen-coverage switchin & switchout criteria. Any dynamic transformation applied above the LOD in the hierarchy will automatically be applied to the active LOD.

@javagl
Copy link
Contributor

javagl commented Jun 24, 2025

Details:

  • There is no GEO vendor prefix
  • There are some formatting issues in the README (e.g. using special unicode characaters instead of "quotes", missing backticking)
  • Code blocks should be given as code blocks, and not as images
  • The "Lastly" section is obsolete

More important:

It is still not entirely clear to me what exactly can be described with this extension what can not be described with MSFT_lod. (I might just have to think this through or draft some examples, but maybe it can easily be illustrated)

@andybushnell
Copy link
Author

Thanks for the feedback.
(1) I'll update the readme file (remove code images etc.) today.
(2) if there's no GEO prefix - what should it be called?
(3) The MSFT_lod extension is similar but differs in the following ways....
(a) Its much more restrictive in that it necessitates a particular hard-wired node structure. whereas my lod alternative is more free-form and doesn't enforce a particular structure. Of course, I can see that the MSFT approach could be beneficial for efficiency and (from some perspectives) runtime simplicity. but that wasn't the driving factor in my suggesting this alternative lod mechanism.
(b) The MSFT_lod only defines lod via screencoverage, whereas i suggest switchinout via screencoverage as well as distance in scene units.
(4) The main driver for me was capturing the way LOD's are defined in OpenFlight, which is the defacto database exchange format for the military training & simulation market - introducing an lod mechanism which mirrored that in Openflight would, I believe, facilitate a more rapid transition to glTF in that market (brining a lot of the benefits of glTF with it).
(5) Since i'm still fairly new to glTF its possible (or likely) that I misunderstood the intension of the vendor extension mechanism - i thought there was room for 2 vendor flavors for lod switching. Please let me know, If you think they are too similar or this suggestion doesn't bring enough uniqueness to the table.

Once again thanks for your time and input (and sorry for my newbie errors!:-)

@javagl
Copy link
Contributor

javagl commented Jun 27, 2025

if there's no GEO prefix - what should it be called?

Prefixes can be registered by companies or organizations that want a "namespace" for their extension. There is no strong need to change the name now (and no need to immediately register a prefix). In doubt, another prefix can be assigned later, when the exact contents and scope are sorted out.

Related:

i thought there was room for 2 vendor flavors for lod switching.

Sure, everybody can suggest an extension. The question is rather how widely it will be adopted. Implementing a new extension can be a considerable effort for people who develop glTF viewers and libraries. So there usually must be something "subtantially new" in that extension (or something "substantially better than others").

This does not mean that there is "nothing substantially new/better" here! But I'm not deeply familiar with MSFT_lod, and have not yet wrapped my head around the details of this extension, to really understand the differences.


I roughly understand the additional option of switching based on distance (in addition to the screen coverage). I could imagine that, roughly speaking, everything that can be achieved with the distance-based switching can also be achieved with a coverage-based switching. But that may be oversimplified.

In a similar vein: You mentioned a "hard-wired node structure" and the proposed extension being "more free-form". Focussing on the geometry for now: The structural difference seems to be:

  • In MSFT_lod, the extension is attached to one node, and describes the different meshes that should be used to represent the levels of detail
  • In this extension, the extension is attached to multiple nodes, and describes the whole (part of the) scene graph that should be used to represent the levels of detail

Roughly as in

- root
  - node0
    - mesh0 (low)
    - mesh1 (medium)
    - mesh2 (high)

vs

- root
  - node0 (low)
    - mesh0 (low)
  - node1 (medium)
    - mesh1 (medium)
  - node2 (high)
    - mesh2 (high)    

I could imagine that switching whole scene graphs for different LOD levels offers some interesting options. For example, one could completely omit some meshes in the "low" level.

But beyond that (an attempt to understand the differences), I can probably not provide toooo much substantial feedback. Maybe others will chime in here as well. (This could be people who already have implemented MSFT_lod, or who wanted LODs and couldn't achieve the desired goals with `MSFT_lod).

@andybushnell
Copy link
Author

The main difference is that this Lod extension can be on any (non-mesh) grouping node and all the children of the node (the subtree routed at the LOD node) are considered part of that Lod and will be active/visible when the parent Lod passes its switchinout values.

for example:

if you consider this more complex hierarchy...

node "root" //root node with (4 children)
node "high_lod // GEO_LOD extension - visible when switchinout [15,0] (2 children)
node "g1"
node "ultra_detail" // GEO_LOD extension - visible when switchinout [10,0]
node "ultra_detail_mesh" mesh: index1
node "high_LOD_mesh" mesh: index2
node "plinth" mesh: index3
node "med_lod" // GEO_LOD extension - visible when switchinout [25,15] (1 child)
node "med_lod_mesh" mesh: index4
node "low_lod" // GEO_LOD extension - visible when switchinout [100,25] (1 child)
node "low_lod_mesh" mesh: index5

if distance to lod center is 14 units then during traversal "high_lod" is active as is
child "plinth" which is not under any lod control but since the high_lod has itself an
embedded LOD node - it wont draw "ultra_detail" unless the distance is <= 10 database
units. If it is then the sub tree routed at LOD "ultra_detail" is also shown.

I'm not suggesting that this nesting is the best way to do this (the "ultra_detail" node
doesnt have to be nested) - but I mention it to showcase that the "high_lod" can be a
complex hierarchy of nodes/articulated parts etc - but they all adhere to the higher-level
lod control.

does that help? :-)

@javagl
Copy link
Contributor

javagl commented Jun 27, 2025

I think that I see the point - with the main aspect being that it's possble to switch in/out a whole node hierarchy. With MSFT_lod, there may be different levels for a single mesh. But it's not possible to, say, render multiple (complex) meshes for one LOD, and a single (simple) mesh for another LOD.

In terms of CAD, hierarchy, and assemblies, I could imagine the example of the engine of a car (maybe consisting of hundreds of meshes, maybe even animated), and at some point, replacing that with a simple box.

@andybushnell
Copy link
Author

Thats it!! :-)

@andybushnell
Copy link
Author

more_complex_hierarchy
here's an in-editor snapshot to show the hierarchy better

@bghgary
Copy link
Contributor

bghgary commented Jun 30, 2025

With MSFT_lod, there may be different levels for a single mesh. But it's not possible to, say, render multiple (complex) meshes for one LOD, and a single (simple) mesh for another LOD.

FWIW, the intention of MSFT_lod is to support different node hierarchies for different LODs. It is at the node level where the switching happens. Each LOD can have a completely different node structure.

@andybushnell
Copy link
Author

Thanks mate,
This is my first Khronos pull request (eh, in fact it's also my first git pull request ever! - i've been living in Subversion land for too many years! :-) . What expectation should I have (if any) in terms of progress/next steps? If there's not many comments - does that mean its not a worthwhile suggestion and, if so, do I need to do anything else ? Thanks for your patience.

@javagl
Copy link
Contributor

javagl commented Jun 30, 2025

FWIW, the intention of MSFT_lod is to support different node hierarchies for different LODs. It is at the node level where the switching happens. Each LOD can have a completely different node structure.

When glancing over it, I actually misread the example from the README (but it is in fact described clearly - should have taken more time to read it thoroughly before chiming in here).

Given that it is possible to switch out whole hierarchies for different LODs, I'm not sure what the remaining differences are to this proposal, except for the 'distance'-based switching criterion.

@bghgary
Copy link
Contributor

bghgary commented Jun 30, 2025

Given that it is possible to switch out whole hierarchies for different LODs, I'm not sure what the remaining differences are to this proposal, except for the 'distance'-based switching criterion.

MSFT_lod doesn't strictly specify what criterion is used to switch. We put the screen coverage values in extras because it's application/scenario specific how switching happens. But I can see people wanting this to be better defined.

@andybushnell
Copy link
Author

Thats why i have the switchinout attribute which can be interpreted as scene units of distance or screen coverage percentage depending on the LOD type. I also couldn't see how this hierarchy (where a higher lod for super fine detail) is actually a child node of the first lod in MSFT_LOD - although maybe it could be supported. I think having the first/high lod reference the subsequent med/low etc lods is restrictive and not an issue with my pproposal.
more_complex_hierarchy

Since my proposal explicitly calls out which lod switch logic/algorithm to use - and has other flexibility (as I see it anyway) is that enough to accept my vendor proposal?

@bghgary
Copy link
Contributor

bghgary commented Jul 1, 2025

I also couldn't see how this hierarchy (where a higher lod for super fine detail) is actually a child node of the first lod in MSFT_LOD - although maybe it could be supported

I'm not sure I follow. The picture you showed can be represented in MSFT_lod as far as I can tell, but I'm probably not understanding what you mean.

Another consideration is that if this extension is intended to be in extensionsUsed and not in extensionsRequired, then it should work correctly when the loading engine does not support this extension. MSFT_lod does this by putting the references to the LODs as extension values so that they will be ignored if the loading engine doesn't support MSFT_lod.

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

Successfully merging this pull request may close these issues.

3 participants