fix issue #124: Texture and MipMap types #227
Draft
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.
Why
Issue #124 discusses a desire to have concrete types for the
image
andmipmaps
fields ofTHREE.Texture
.This is made difficult by the fact that Three.js appears to occasionally use the
images
field not as an actual source of image data, but as a metadata field to store width/height information about composite texture types likeTHREE.CubeTexture
.For the
mipmaps
field, all of the loaders in the examples code end up returning anImageData
structure, but in some cases likeTHREE.VideoTexture
, themipmaps
field could contain anHTMLVideoElement
. In general, Three.js does some checking on the type of theTHREE.Texture
before choosing whether to use theimage
field or one of themipmaps
array elements for a call to various texture loading functions in WebGL, some of which are capable of loading anyTexImageSource
. Indeed, it appears it's kept as such to also support manually generating mipmaps, e.g. by resizing images via rendering to a Canvas.What
For all of the Loader types in the examples folder, I've updated their returned mipmaps fields to be
ImageData[]
instead ofobject[]
.For the base
THREE.Texture
type, I started by defining a number of utility types that describe all the extant ways that theimage
field appears to be used in Three.js. I then used these to create optional type parameters toTHREE.Texture
. Subclasses ofTHREE.Texture
can then specify values for those type parameters, e.g.THREE.VideoTexture
specifies that the image type isHTMLVideoElement
.One curious thing is that there actually aren't a lot of restrictions on the types of images you put in
THREE.Texture
s. For example,THREE.VideoTexture
could contain anHTMLCanvasElement
. AllTHREE.VideoTexture
does is run an animation loop to setneedsUpdate
without the user having to do so in their own code. You could conceivably useTHREE.VideoTexture
with a canvas object that you intend to draw to continuously, saving you from having to write an animation loop to update the texture. Similarly,THREE.CanvasTexture
doesn't really care if you give it a canvas or not, all it does is setneedsUpdate
to true.But in those cases, I opted to be explicit in the typing of the textures. If someone were to want to do some shenanigans like that, they can always just cast to
any
.Finally, I also updated the type signatures for
THREE.WebGLRenderTarget
and its subclasses, so that theirtexture
fields could also be typed more explicitly.I'm submitting this as a draft PR because I'm not really sure of the ergonomics of this. The tests pass, I even managed to write a few that prove out the general concept in type checking. But I'm not really sure how useful the generic
THREE.Texture
type with the default type parameters will be when dealing with textures loaded from model loaders. Well, at the very least, it gives you more guidance on how to go about type filtering on those values, but I'm curious to see what others think.Checklist
master
, next goesdev
)