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

WebGL 2.0: Force decompressing non power-of-2 textures with repeat/mipmap #33059

Merged
merged 1 commit into from
Oct 26, 2019

Conversation

akien-mga
Copy link
Member

@akien-mga akien-mga commented Oct 25, 2019

While OpenGL ES 3.0 and WebGL 2.0 both support non power-of-2 (NPOT)
textures in their specification, the situation seems to be less clear
about compressed NPOT textures using repeat or mipmap flags.

At least Chrome on Linux doesn't seem to support this combination,
and a variety of mobile hardware have similar limitations.

As a workaround, we force decompressing such textures when running on
WebGL 2.0, at the cost of loading time and memory usage.

Fixes #33058.

@akien-mga akien-mga added this to the 3.2 milestone Oct 25, 2019
@akien-mga akien-mga requested review from reduz and clayjohn October 25, 2019 10:31
@akien-mga akien-mga changed the title GLES3: Resize non power-of-2 mipmapped textures for WebGL 2.0 [WIP] GLES3: Resize non power-of-2 mipmapped textures for WebGL 2.0 Oct 25, 2019
@akien-mga
Copy link
Member Author

This is probably not the right fix as discussed with @reduz. OpenGL ES 3.0 and WebGL 2.0 should support NPOT textures as per specification: https://www.khronos.org/registry/webgl/specs/latest/2.0/#4.1.3

But the problem seems to be that mobile hardware (and thus likely browser WebGL implementation for consistency) don't all support compressed NPOT textures, which is a badly specified hole in the spec. So here we are.

An option would be to add some code only for WebGL that would just uncompress NPOT textures (resizing them might not be necessary).

(alternatively, we could add a Web-specific import preset for S3TC, to
allow having both PC S3TC non-resized and Web S3TC resized imported
textures).

This would still be the better option though IMO.

…pmap

While OpenGL ES 3.0 and WebGL 2.0 both support non power-of-2 (NPOT)
textures in their specification, the situation seems to be less clear
about *compressed* NPOT textures using repeat or mipmap flags.

At least Chrome on Linux doesn't seem to support this combination,
and a variety of mobile hardware have similar limitations.

As a workaround, we force decompressing such textures when running on
WebGL 2.0, at the cost of loading time and memory usage.

Fixes godotengine#33058.
@akien-mga akien-mga force-pushed the webgl2-resize-non-po2 branch from 074e24f to 6900345 Compare October 25, 2019 11:09
@akien-mga
Copy link
Member Author

An option would be to add some code only for WebGL that would just uncompress NPOT textures (resizing them might not be necessary).

I pushed an update to do that.

@akien-mga akien-mga changed the title [WIP] GLES3: Resize non power-of-2 mipmapped textures for WebGL 2.0 GLES3: Resize non power-of-2 mipmapped textures for WebGL 2.0 Oct 25, 2019
@akien-mga akien-mga changed the title GLES3: Resize non power-of-2 mipmapped textures for WebGL 2.0 WebGL 2.0: Force decompressing non power-of-2 textures with repeat/mipmaps Oct 25, 2019
@akien-mga akien-mga changed the title WebGL 2.0: Force decompressing non power-of-2 textures with repeat/mipmaps WebGL 2.0: Force decompressing non power-of-2 textures with repeat/mipmap Oct 25, 2019
@akien-mga
Copy link
Member Author

Tested successfully on Firefox Beta and Chrome on Android (current versions), and Chrom(ium) on Linux. Firefox can't be tested on Linux due to #33058.

@@ -753,13 +767,9 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p
if (config.keep_original_textures && !(texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING)) {
texture->images.write[p_layer] = p_image;
}
#ifndef GLES_OVER_GL
if (p_image->is_compressed() && p_image->has_mipmaps() && !p_image->is_size_po2()) {
ERR_PRINTS("Texuture '" + texture->path + "' is compressed, has mipmaps but is not of powerf-of-2 size. This does not work on OpenGL ES 3.0.");
Copy link
Member Author

Choose a reason for hiding this comment

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

I removed this as AFAIK, we force resizing to power of 2 sizes when compressing to ETC, ETC2 or PVRTC. So S3TC on WebGL was the only situation where this would not happen, and it should now be fixed by this forced decompression.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Mesh fails to render material with non power of 2 textures [WebGL 2.0]
2 participants