forked from KhronosGroup/glTF
-
Notifications
You must be signed in to change notification settings - Fork 9
EXT_textureInfo_constant_lod #92
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
Merged
Merged
Changes from all commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
2fbd1b9
draft wip
markschlosseratbentley 2b24930
First draft
eringram b8f7a36
Updates
eringram 6bc221c
WIP implementation notes
eringram 71be55d
Fix implementation notes formula
eringram 73c0a10
Clarify usage
eringram 7b0ac09
Fix comments
eringram 32d7a8c
Improve spec
eringram 89f1652
Sentence update
eringram e425416
Update extensions/2.0/Vendor/EXT_textureInfo_constant_lod/README.md
eringram f8157de
Update extensions/2.0/Vendor/EXT_textureInfo_constant_lod/README.md
eringram 0476ac3
Improve wording
eringram 84cdd58
Merge branch 'EXT_textureInfo_constant_lod' of https://github.com/Ces…
eringram f886f2a
Update extensions/2.0/Vendor/EXT_textureInfo_constant_lod/README.md
eringram f3ca499
Mention texCoord fallback
eringram 5de23e0
Wording
eringram 3b03d91
contributors
markschlosseratbentley 4dd2548
Update README.md
danielzhong 2713715
Allow repetititons to be <1, rm divide by 0 for clamp result
eringram c3ef591
Mention sync base color and normal texture props
eringram e1ee91e
Update schema version
eringram befe6b8
Fix latex formatting
eringram d9d5197
Make texCoord fallback UVs required
eringram e846ce8
Fix newlines in latex
eringram 2310619
Another newline formatting test
eringram 0a07ef7
Format test
eringram 37772e2
Format test
eringram f365724
Formatting, use gather instead of align
eringram 795ff6c
Improve formula readability
eringram 94be333
Update extensions/2.0/Vendor/EXT_textureInfo_constant_lod/README.md
eringram 26cec29
Fix note & mult. symbols
eringram 6843a26
Add known implementations
eringram 745a68e
Update extensions/2.0/Vendor/EXT_textureInfo_constant_lod/README.md
eringram 86c83b7
Update extensions/2.0/Vendor/EXT_textureInfo_constant_lod/README.md
eringram 45aef50
Update extensions/2.0/Vendor/EXT_textureInfo_constant_lod/README.md
eringram 7467e5a
Remove line
eringram File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
136 changes: 136 additions & 0 deletions
136
extensions/2.0/Vendor/EXT_textureInfo_constant_lod/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,136 @@ | ||
| <!-- | ||
| Copyright 2025 Bentley Systems, Incorporated | ||
| SPDX-License-Identifier: CC-BY-4.0 | ||
| --> | ||
|
|
||
| # EXT_textureInfo_constant_lod | ||
|
|
||
| ## Contributors | ||
|
|
||
| * Paul Connelly, Bentley Systems, [@pmconne](https://github.com/pmconne) | ||
| * Erin Ingram, Bentley Systems, [@eringram](https://github.com/eringram) | ||
| * Mark Schlosser, Bentley Systems, [@markschlosseratbentley](https://github.com/markschlosseratbentley) | ||
| * Daniel Zhong, Bentley Systems, [@danielzhong](https://github.com/danielzhong) | ||
|
|
||
| ## Status | ||
|
|
||
| Complete | ||
|
|
||
| ## Dependencies | ||
|
|
||
| Written against the glTF 2.0 spec. | ||
|
|
||
| ## Overview | ||
|
|
||
| Constant level-of-detail ("LOD") is a technique of texture coordinate generation which dynamically calculates texture coordinates to maintain a consistent texel-to-pixel ratio on screen, regardless of camera distance. As the camera zooms in or out, the texture coordinates are recalculated so that the texture pattern remains at approximately the same visual scale. The transition between scale levels is smoothly blended to avoid abrupt changes. | ||
|
|
||
| The `EXT_textureInfo_constant_lod` extension defines properties needed to calculate these dynamic texture coordinates: the number of times the texture is repeated per meter, an offset to shift the texture, and the minimum and maximum distance for which to clamp the texture. The minimum and maximum clamp distance control at which point the texture sizes shall be blended. These images illustrate the textures blending to create the constant LOD effect: | ||
|
|
||
|  | ||
|
|
||
|  | ||
|
|
||
| The extension specifies an alternative way of computing the texture coordinates, so if it is supported by the client then the `textureInfo`'s `texCoord` is not used. For maximum compatibility however, encoders still must provide `texCoord` UV coordinates so the texture renders even if the extension is not supported. | ||
|
|
||
| ## Specifying Constant LOD Texture Mapping | ||
|
|
||
| The `EXT_textureInfo_constant_lod` extension is defined on `textureInfo` structures. When that `textureInfo` is used by a material, this extension applies the constant LOD technique to the specified texture. | ||
|
markschlosseratbentley marked this conversation as resolved.
|
||
|
|
||
| Constant LOD uses the following properties: | ||
|
|
||
| * `repetitions` - specifies the number of times the texture is repeated per meter in both the X and Y dimensions. Increasing this will make the texture pattern appear smaller; decreasing it will make it appear larger. | ||
| * `offset` - used to shift the texture, specified as a pair of numbers in meters in the format [X, Y]. | ||
| * `minClampDistance` - specifies the minimum distance in meters from the camera to the surface at which to clamp the texture. This value must not be greater than `maxClampDistance`. | ||
| * `maxClampDistance` - specifies the maximum distance in meters from the camera to the surface at which to clamp the texture. This value must not be less than `minClampDistance`. | ||
|
|
||
| For example, the following JSON defines a material with a texture at index 0 that is modified by the `EXT_textureInfo_constant_lod` extension. The extension has a `repetitions` value of 2 causing it to be repeated twice per meter, making its pattern appear half the size. It is shifted by 1 meter in the X direction and 0 meters in the Y direction. It also has a minimum clamp distance of 0.5 meters, meaning the constant LOD effect stops being present when the camera is 0.5m away from the surface or closer. This is a closer distance than the default value of 1m; therefore, this material requires a closer zoom before the texture stops adapting its level of detail (and for it to appear magnified). The absence of the `maxClampDistance` property means it has a default value of $2^{32}$, so the constant LOD effect will occur until the camera is $2^{32}$ away from the surface. | ||
|
|
||
| ```json | ||
| "materials": [ | ||
| { | ||
| "pbrMetallicRoughness": { | ||
| "baseColorTexture": { | ||
| "index": 0, | ||
| "texCoord": 0, | ||
| "extensions": { | ||
| "EXT_textureInfo_constant_lod": { | ||
| "repetitions": 2, | ||
| "offset": [1, 0], | ||
| "minClampDistance": 0.5 | ||
| } | ||
| } | ||
| }, | ||
| "baseColorFactor": [1.0, 1.0, 1.0, 1.0], | ||
| "metallicFactor": 0.0, | ||
| "roughnessFactor": 1.0 | ||
| } | ||
| } | ||
| ], | ||
| ``` | ||
|
|
||
| ## Implementation Notes | ||
|
|
||
| The `EXT_textureInfo_constant_lod` extension may be present on any `textureInfo` object, including those that extend `textureInfo` such as `normalTextureInfo`. Encoders and clients may decide to implement the extension such that the normal texture has identical constant LOD properties to the base color texture to produce a synchronized blending of levels-of-detail, although this is not required. | ||
|
|
||
| ### Formulas | ||
|
|
||
| This section outlines the formulas that shall be used by implementations to calculate the dynamic texture coordinates for constant LOD. | ||
|
|
||
| In the vertex shader: | ||
|
|
||
| ```math | ||
| \begin{aligned} | ||
| customUvCoords.xy &= worldPosition.xy + offset\\ | ||
| customUvCoords.z &= \begin{cases} | ||
| -eyeSpace & \text{if } isPerspectiveProjection \\ | ||
| frustrumWidth & \text{if } isOrthographicProjection \\ | ||
| \end{cases} | ||
| \end{aligned} | ||
| ``` | ||
|
|
||
| Where $worldPosition$ is the vertex position in world coordinates, $eyeSpace$ is the vertex position in camera coordinates, and $frustumWidth$ is the frustum width in meters. | ||
|
|
||
| The resulting $customUvCoords.xy$ contain the vertex's X and Y position in world coordinates. $customUvCoords.z$ is the negative eye-space depth (z-coordinate) from the camera to the fragment when using perspective projection. Since all points are equidistant to the camera when using orthographic projection, this value shall be set to the frustum width as a proxy for zoom level. $customUvCoords$ should then be passed into the fragment shader as a `varying`. | ||
|
|
||
| In the fragment shader: | ||
|
|
||
| ```math | ||
| \begin{aligned} | ||
| (x, y, z) &= customUvCoords\\ | ||
| minDistance &= min(clampDistance) \\ | ||
| maxDistance &= max(clampDistance) \\ | ||
| logDepth &= \log_{2}{z}\\ | ||
| textureCoordinates_1 &= \frac{xy}{clamp(2^{\lfloor logDepth \rfloor}, minDistance, maxDistance)} \cdot repetitions\\ | ||
| textureCoordinates_2 &= \frac{xy}{clamp(2^{\lfloor logDepth \rfloor + 1}, minDistance, maxDistance)} \cdot repetitions\\ | ||
| result &= mix(textureCoordinates_1, textureCoordinates_2, fract(logDepth)) | ||
| \end{aligned} | ||
| ``` | ||
|
|
||
| *Non-normative note: the addition of $\lfloor logDepth \rfloor + 1$ when calculating $textureCoordinates_2$ allows the result of the $mix$ function to blend between two adjacent mipmap levels.* | ||
|
|
||
| Where $clamp(x, minVal, maxVal)$ constrains the value of $x$ to the range of $minVal$ to $maxVal$, defined by the [GLSL definition](https://registry.khronos.org/OpenGL-Refpages/gl4/html/clamp.xhtml) of: | ||
|
markschlosseratbentley marked this conversation as resolved.
|
||
|
|
||
| ```math | ||
| \min(\max(x, minVal), maxVal) | ||
| ``` | ||
|
|
||
| $fract(x)$ returns the fractional part of $x$, defined by the [GLSL definition](https://registry.khronos.org/OpenGL-Refpages/gl4/html/fract.xhtml) of: | ||
|
|
||
| ```math | ||
| x - \lfloor x \rfloor | ||
| ``` | ||
|
|
||
| and $mix(x, y, a)$ performs a linear interpolation between $x$ and $y$ using $a$ to weight between them, using the [GLSL definition](https://registry.khronos.org/OpenGL-Refpages/gl4/html/mix.xhtml) of: | ||
|
|
||
| ```math | ||
| x \cdot (1 − a) + y \cdot a | ||
| ``` | ||
|
|
||
|
eringram marked this conversation as resolved.
|
||
| ## JSON Schema | ||
|
|
||
| * [textureInfo.EXT_textureInfo_constant_lod.schema.json](schema/textureInfo.EXT_textureInfo_constant_lod.schema.json) | ||
|
|
||
| ## Known Implementations | ||
|
|
||
| * [iTwin.js](https://github.com/iTwin/itwinjs-core/pull/8882) | ||
| * [CesiumJS](https://github.com/CesiumGS/cesium/pull/13121) | ||
Binary file added
BIN
+981 KB
extensions/2.0/Vendor/EXT_textureInfo_constant_lod/figures/constantlod.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+47.2 KB
extensions/2.0/Vendor/EXT_textureInfo_constant_lod/figures/constantlod.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions
41
.../EXT_textureInfo_constant_lod/schema/textureInfo.EXT_textureInfo_constant_lod.schema.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| { | ||
| "$schema": "https://json-schema.org/draft/2020-12/schema", | ||
| "title": "EXT_textureInfo_constant_lod TextureInfo Extension", | ||
| "type": "object", | ||
| "description": "Enables dynamically calculated UV coordinates to keep the texture near a constant level of detail", | ||
| "allOf": [ | ||
| { "$ref": "glTFProperty.schema.json" } | ||
| ], | ||
| "properties": { | ||
| "repetitions": { | ||
| "type": "number", | ||
| "description": "The number of times the texture is repeated per meter.", | ||
| "exclusiveMinimum": 0.0, | ||
| "default": 1.0 | ||
| }, | ||
| "offset": { | ||
| "type": "array", | ||
| "description": "The offset in meters used to shift the texture.", | ||
| "items": { | ||
| "type": "number" | ||
| }, | ||
| "minItems": 2, | ||
| "maxItems": 2, | ||
| "default": [ 0.0, 0.0 ] | ||
| }, | ||
| "minClampDistance": { | ||
| "type": "number", | ||
| "description": "The minimum distance in meters from the eye to the surface at which to clamp the texture.", | ||
| "minimum": 0.0, | ||
| "default": 1.0 | ||
| }, | ||
| "maxClampDistance": { | ||
| "type": "number", | ||
| "description": "The maximum distance in meters from the eye to the surface at which to clamp the texture.", | ||
| "exclusiveMinimum": 0.0, | ||
| "default": 4294967296.0 | ||
| }, | ||
| "extensions": { }, | ||
| "extras": { } | ||
|
pmconne marked this conversation as resolved.
|
||
| } | ||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.