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

KHR_texture_transform #1015

Closed
Closed
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
1416a9d
Started on offset/tile extension
Jun 13, 2017
c27a874
Add schema
Jun 13, 2017
92d08dc
Finish readme, add link from extension list
Jun 13, 2017
364fd9d
Fix table formatting
Jun 13, 2017
505ae1f
Rename extension, move data to texture
Jun 13, 2017
be48c5c
Addressed comments
Jun 13, 2017
fa2b379
Fix missed rename, typos, update schema descriptions
Jun 14, 2017
7a69a66
Moved offset/tile settings to textureInfo objects
Jun 14, 2017
29ab80b
AVR>EXT, tile>scale, removed value restrictions
stevenvergenz Nov 7, 2017
cdd5061
Update name again, rewrite schema
stevenvergenz Nov 7, 2017
ea111d9
Update name to take into account addition of rotation field
stevenvergenz Nov 7, 2017
421e12e
Change prefix to MSFT
stevenvergenz Nov 8, 2017
4e438f0
Move back to EXT prefix, remove rotation/matrix, add texCoord
stevenvergenz Nov 8, 2017
60dcf94
Update schema with missing items
stevenvergenz Nov 10, 2017
0b22fc5
Fix schema
stevenvergenz Nov 10, 2017
d5ecfdc
Fix default in readme
stevenvergenz Nov 10, 2017
4749966
Add rotation back in
stevenvergenz Feb 22, 2018
228a25f
EXT_texture_transform -> KHR_texture_transform as agreed during Feb21…
Feb 28, 2018
7c7f3b5
Merge branch 'master' into avr-sampler-offset-tile
emilian0 Feb 28, 2018
282f0f6
Move texture_transform to match new folder structure and fix minor ty…
MiiBond Apr 4, 2018
85cdfd4
Merge branch 'master' of github.com:KhronosGroup/glTF into avr-sample…
MiiBond Apr 11, 2018
822f6ba
Fix examples
lexaknyazev Apr 11, 2018
ed8774a
Merge remote-tracking branch 'MiiBond/update-texture-transform' into …
stevenvergenz Apr 11, 2018
017fc95
Merge branch 'avr-sampler-offset-tile' of github.com:AltspaceVR/glTF …
MiiBond Apr 11, 2018
c88158b
Fix property name in samples
lexaknyazev Apr 12, 2018
15ed1fd
Add implementation note on UV origin.
May 24, 2018
c4a1101
Update status.
Jul 3, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions extensions/Khronos/KHR_texture_transform/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# KHR_texture_transform

## Contributors

* Steven Vergenz, Microsoft ([steven.vergenz@microsoft.com](mailto:steven.vergenz@microsoft.com))

## Status

Draft

## Dependencies

Written against the glTF 2.0 spec.

## Overview

Many techniques can be used to optimize resource usage for a 3d scene. Chief among them is the ability to minimize the number of textures the GPU must load. To achieve this, many engines encourage packing many objects' low-resolution textures into a single large texture atlas. The region of the resulting atlas that corresponds with each object is then defined by vertical and horizontal offsets, and the width and height of the region.

To support this use case, this extension adds `offset`, `rotation`, and `scale` properties to textureInfo structures. These properties would typically be implemented as an affine transform on the UV coordinates. In GLSL:

```glsl
varying in vec2 Uv;

uniform vec2 Offset, Scale;
uniform float Rotation;

mat3 translation = mat3(1,0,0, 0,1,0, Offset.x, Offset.y, 1);
mat3 rotation = mat3(
cos(Rotation), sin(Rotation), 0,
-sin(Rotation), cos(Rotation), 0,
0, 0, 1
);
mat3 scale = mat3(Scale.x,0,0, 0,Scale.y,0, 0,0,1);

mat3 matrix = translation * rotation * scale;
vec2 uvTransformed = ( matrix * vec3(Uv.xy, 1) ).xy;
```

This is equivalent to Unity's `Material#SetTextureOffset` and `Material#SetTextureScale`, or Three.js's `Texture#offset` and `Texture#repeat`. UV rotation is not widely supported as of today, but is included here for forward compatibility.

## glTF Schema Updates

The `KHR_texture_transform` extension may be defined on `textureInfo` structures. It may contain the following properties:

| Name | Type | Default | Description
|------------|------------|--------------|---------------------------------
| `offset` | `array[2]` | `[0.0, 0.0]` | The offset of the UV coordinate origin as a factor of the texture dimensions.
| `rotation` | `number` | `0.0` | Rotate the UVs by this many radians counter-clockwise around the origin. This is equivalent to a similar rotation of the image clockwise.
| `scale` | `array[2]` | `[1.0, 1.0]` | The scale factor applied to the components of the UV coordinates.
| `texCoord` | `integer` | | Overrides the textureInfo texCoord value if supplied, and if this extension is supported.

Though this extension's values are unbounded, they will only produce sane results if the texture sampler's `wrap` mode is `REPEAT`, or if the result of the final UV transformation is within the range [0, 1] (i.e. negative scale settings and correspondingly positive offsets).

> **Implementation Note**: For maximum compatibility, it is recommended that exporters generate UV coordinate sets both with and without transforms applied, use the post-transform set in the texture `texCoord` field, then the pre-transform set with this extension. This way, if the extension is not supported by the consuming engine, the model still renders correctly. Including both will increase the size of the model, so if including the fallback UV set is too burdensome, either add this extension to `extensionsRequired` or use the same texCoord value in both places.

### JSON Schema

[KHR_texture_transform.textureInfo.schema.json](schema/KHR_texture_transform.textureInfo.schema.json)

### Example JSON

This example utilizes only the lower left quadrant of the source image, rotated clockwise 90°.

```json
{
"materials": [{
"emissionTexture": {
"source": 0,
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be "index", I believe.

"extensions": {
"KHR_texture_transform": {
"offset": [0, 1],
"rotation": 1.57079632679,
"scale": [0.5, 0.5]
}
}
}
}]
}
```

This example inverts the T axis, effectively defining a bottom-left origin.

```json
{
"materials": [{
"emissionTexture": {
"source": 0,
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto.

"extensions": {
"KHR_texture_transform": {
"offset": [0, 1],
"scale": [1, -1]
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we at all concerned that the normalTextureInfo structure already contains a scale value? I suppose there could be confusion that the scale value in the texture_transform is an override...
Maybe not but I thought I'd mention it.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it might be confusing, but I don't have a better suggestion. For reference, here is what it might look like:

      "normalTexture": {
        "index": 2,
        "scale": 1.5,
        "extensions": {
          "KHR_texture_transform": {
            "offset": [0, 1],
            "rotation": 1.57079632679,
            "scale": [0.5, 0.5]
          }
        }
      },

Copy link
Contributor

Choose a reason for hiding this comment

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

It feels OK nested under the *_texture_transform namespace to me. Conceptually it then becomes transformScale or something like that in code.

}
}
}
}]
}
```

## Known Implementations

* [UnityGLTF](https://github.com/KhronosGroup/UnityGLTF)
* [Babylon.js](https://www.babylonjs.com/)
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"$schema" : "http://json-schema.org/draft-04/schema",
"title" : "KHR_texture_transform textureInfo extension",
"type" : "object",
"description": "glTF extension that enables shifting and scaling UV coordinates on a per-texture basis",
"allOf": [ { "$ref": "glTFProperty.schema.json" } ],
"properties" : {
"offset": {
"type": "array",
"description": "The offset of the UV coordinate origin as a factor of the texture dimensions.",
"items": {
"type": "number"
},
"minItems": 2,
"maxItems": 2,
"default": [ 0.0, 0.0 ]
},
"rotation": {
"type": "number",
"description": "Rotate the UVs by this many radians counter-clockwise around the origin.",
"default": 0.0
},
"scale": {
"type": "array",
"description": "The scale factor applied to the components of the UV coordinates.",
"items": {
"type": "number"
},
"minItems": 2,
"maxItems": 2,
"default": [ 1.0, 1.0 ]
},
"texCoord": {
"type": "integer",
"description": "Overrides the textureInfo texCoord value if supplied, and if this extension is supported.",
"minimum": 0
},
"extensions": { },
"extras": { }
},
"additionalProperties" : false
}
9 changes: 5 additions & 4 deletions extensions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@

#### Draft Khronos extensions
_Draft Khronos extensions are not ratified yet._
* KHR_materials_common *(in progress)*
* KHR_technique_webgl *(in progress)*
* [KHR_materials_common](Khronos/KHR_materials_common/README.md)
* [KHR_technique_webgl](Khronos/KHR_technique_webgl/README.md)
* [KHR_texture_transform](Khronos/KHR_texture_transform/README.md)

## Extensions for glTF 1.0

Expand All @@ -24,7 +25,7 @@ _Draft Khronos extensions are not ratified yet._

# About glTF Extensions

glTF extensions extend the base glTF model format. Extensions can introduce new properties (including properties that reference external data, and the extension can define the format of those data), new parameter semantics, reserved IDs, and new container formats. Extensions are written against a specific version of glTF and may be promoted to core glTF in a later glTF version.
glTF extensions extend the base glTF model format. Extensions can introduce new properties (including properties that reference external data, and the extension can define the format of those data), new parameter semantics, reserved IDs, and new container formats. Extensions are written against a specific version of glTF and may be promoted to core glTF in a later glTF version.

## Extension Mechanics

Expand Down Expand Up @@ -68,7 +69,7 @@ This allows an engine to quickly determine if it supports the extensions needed

To create a new extension, use the [extension template](Template.md) and open a pull request into this repo. Make sure to add the extension to the glTF Extension Registry (top of this file).

If lack of extension support prevents proper geometry loading, extension specification _must_ state that (and such extension must be mentioned in `extensionsRequired` top-level glTF property).
If lack of extension support prevents proper geometry loading, extension specification _must_ state that (and such extension must be mentioned in `extensionsRequired` top-level glTF property).

Extensions start as a vendor extension, then can become a multi-vendor extensions if there are multiple implementations, and can become a ratified Khronos extension (the multi-vendor extension is an optional step).

Expand Down