KhronosGroup / glTF

glTF – Runtime 3D Asset Delivery
Other
7.12k stars 1.13k forks source link

Texture.type and Texture.format should be Image.type and Image.format #640

Closed ParticlePeter closed 5 years ago

ParticlePeter commented 8 years ago

Sorry if this was pointed out already, I could not find any issue describing it. The function glTexImage2D creates a Texture object of Texture.internalFormat AND (if last parameter data is not null) uploads image pixel data of Image.type and Image.format converting the data into Texture.internalFormat while uploading. Is there any reason for mixing the semantics which I am not able to see?

pjcozzi commented 8 years ago

Loosely, glTF image is suppose to correspond to JavaScript's Image object, and glTF's texture to a call to glTexImage2D and friends (e.g., for sampler states). The workflow has seemed to work well in practice and be easy to learn and understand.

Moving format and type to image perhaps makes image more coherent, but are you sure it is the right thing to do when looking at the workflow for loading an asset?

lexaknyazev commented 8 years ago

Imho, current layout seems to be well aligned with API calls especially considering possible future support for more traditional texture formats.

Having image reflecting HTML ImageElement makes more sense considering possible video objects reflecting HTML VideoElement. Both could be used as texture.source (which is again aligned with WebGL API calls).

ParticlePeter commented 8 years ago

glTexImage2D is a very antique function, in OpenGL 2 era it made sense to couple creation of image object and texture data upload, a texture was not used for anything else then color look up. But soon render to texture ability was introduced and having to specify two irrelevant texture parameters in that case is annoying and wired. Surprisingly glTexStorage2D made it into core as recently as OpenGL 4. You might argue that gltf texture type and format are optional in such a case but I feel that its still a semantic break. I have a good example where it would make sense to put type and format into image. Suppose you want to change the content of a texture e.g. while streaming some data with glTexSubImage2D all you need is the type and format of the new image (no internalFormat required anymore) and they don't have to be the same as of the image data at texture creation. Wouldn't it be nice to just change the image reference of the texture object and get the format and type from that image object? How could this be accomplished with the current setup?

but are you sure it is the right thing to do when looking at the workflow for loading an asset?

Why should it? A texture has a reference to an image which points to the image uri. Where do you see an issue with getting image type and format as well as the pixel bytes from the same place?

Imho, current layout seems to be well aligned with API calls especially considering possible future support for more traditional texture formats. Having image reflecting HTML ImageElement makes more sense considering possible video objects reflecting HTML VideoElement. Both could be used as texture.source (which is again aligned with WebGL API calls).

Sorry, in both cases I am not getting the relevance of your arguments, in fact quite the opposite. Whenever any data should go into a glTexture the data must inform GL about its type and format. Otherwise you constraint the data sources to exactly one type and format. Quite inflexible in particular with streaming, isn't it?

Btw, a side question, is glTF still supposed to work with desktop GL and Vulkan or are you going straight for webGL only?

lexaknyazev commented 8 years ago

Btw, a side question, is glTF still supposed to work with desktop GL and Vulkan or are you going straight for webGL only?

glTF 1.0 was initially designed around WebGL 1.0 API (with a few exceptions). It was even called WebGLTF some time ago. There is a way to declare other API targets (asset.profile) but such profiles haven't been defined yet.

A texture has a reference to an image which points to the image uri. Where do you see an issue with getting image type and format as well as the pixel bytes from the same place?

I think the main issue here is WebGL 1.0 workflow with web image formats (JPG, PNG): pixels from the ImageElement are converted to the type and format specified by texImage2D args.

All processing is done by browser and JavaScript runtime doesn't even need to know image dimensions to upload texture data.

Otherwise you constraint the data sources to exactly one type and format. Quite inflexible in particular with streaming, isn't it?

Again, WebGL 1.0 limitations: format must match internalformat and the type argument passed to texSubImage2D must match the type used to originally define the texture object.

Nevertheless, I admit that decoupling actual pixel format from texture storage is worth considering in the context of upcoming WebGL 2.0 (based on ES 3.0) with texStorage* functions and lots of new format/internalformat combinations.

ParticlePeter commented 8 years ago

glTF 1.0 was initially designed around WebGL 1.0 API (with a few exceptions). It was even called WebGLTF some time ago. There is a way to declare other API targets (asset.profile) but such profiles haven't been defined yet.

I didn't know that, however this is the description of the repository: glTF - the runtime asset format for WebGL, OpenGL ES, and OpenGL Additionally on all the glTF presentation slides I saw Runtime App OpenGL/ES WebGL as backends. For me it seems strange to argue with any API calls in general and with WebGL calls in particular for a certain property/attribute layout of a DATA format. I don't believe that you would want to change properties based on asset.profile would you?

I think the main issue here is WebGL 1.0 workflow with web image formats (JPG, PNG): pixels from the ImageElement are converted to the type and format specified by texImage2D args. ... Again, WebGL 1.0 limitations: format must match internalformat and the type argument passed to texSubImage2D must match the type used to originally define the texture object.

Same as above, I wasn't aware of that fact and now I see your reason but still disagree with the implementation. Your decision seems to be comfortable for WebGL and that only because its (current) limitations but will lead to issues with other APIs in the long run. The question is if there would be such a hassle with the way WebGL api works when format and type is stored in an image?

pjcozzi commented 6 years ago

@lexaknyazev is this worth considering for a future spec version?

lexaknyazev commented 6 years ago

This will be covered by the upcoming texture transmission extension and/or API-specific extensions (probably separately during draft stage, can't say anything specific).

lexaknyazev commented 5 years ago

Closing, since further texture transmission will be covered by CTTF/KTX2.