-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
KHR_texture_transform #1015
Changes from 25 commits
1416a9d
c27a874
92d08dc
364fd9d
505ae1f
be48c5c
fa2b379
7a69a66
29ab80b
cdd5061
ea111d9
421e12e
4e438f0
60dcf94
0b22fc5
d5ecfdc
4749966
228a25f
7c7f3b5
282f0f6
85cdfd4
822f6ba
ed8774a
017fc95
c88158b
15ed1fd
c4a1101
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
# KHR_texture_transform | ||
|
||
## Contributors | ||
|
||
* Steven Vergenz, Microsoft ([[email protected]](mailto:[email protected])) | ||
|
||
## 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. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's add another note:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
### 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": [{ | ||
"emissiveTexture": { | ||
"index": 0, | ||
"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": [{ | ||
"emissiveTexture": { | ||
"index": 0, | ||
"extensions": { | ||
"KHR_texture_transform": { | ||
"offset": [0, 1], | ||
"scale": [1, -1] | ||
} | ||
} | ||
} | ||
}] | ||
} | ||
``` | ||
|
||
## 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 | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does
cover inherited structures as well (i.e.,
occlusionTextureInfo
andnormalTextureInfo
)?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say yes since both
occlusionTextureInfo
andnormalTextureInfo
inherit fromtextureInfo
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. It would be nice to have sample models showing those cases (I've run into this internally).