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

Add Webgl max texture size check #56

Merged
merged 1 commit into from Jan 30, 2022
Merged

Add Webgl max texture size check #56

merged 1 commit into from Jan 30, 2022

Conversation

nickbabcock
Copy link
Collaborator

Users who have a device where the WebGL max texture size is too small
will have a difficult time diagnosing the problem as they will be
greeted with a black screen. So we add the max texture detection as a
check so users see a warning (and report it as a user metric so we can
see the spread)

Closes #53

Users who have a device where the WebGL max texture size is too small
will have a difficult time diagnosing the problem as they will be
greated with a black screen. So we add the max texture detection as a
check so users see a warning (and report it as a user metric so we can
see the spread)
@nickbabcock nickbabcock merged commit 92c3ae7 into master Jan 30, 2022
@nickbabcock nickbabcock deleted the texture-check branch January 30, 2022 01:30
nickbabcock added a commit that referenced this pull request Feb 3, 2022
After enabling user metrics for wegbl max texture size in #56, it was
revealed that the second most common reported max texture size was 4096.
This is a problem as the minimum size we support is 8192. Not meeting
this mimimum requirement would leave the map completely black. Having a
chunk of our visitors unable to see our glorious map is a shame, so this
PR reduces the max texture size requirements from 8192 to 4096.

This reduction was done by splitting the map static images that are 5632
pixels wide (provinces, terrain, rivers) into left and right components
of 2816 pixels wide. The individual components have suffixes of `1` and
`2` (numbered from left to right) in order so that this naming scheme
can survive whenever we need to break images up into more than just two
parts (eg: future game support with enhanced textures).

The framebuffer used as a pipeline between the shaders needed to be
broken up into two halves as well.

Last but not least, the provice arrays needed to be adjusted. Since
there are provinces that exceed ID 4096, the texture that province data
is uploaded to needed to wrap onto additional rows. So now when binary
searching for province info, we convert the index into a vector to
fetch. This does require us to allocate a larger array and copy the
province data into it so that resulting data completely fills declared
dimensions (ie: 4096x2), else a warning is emitted.

Another important change is that certain parameters and variables are
declared to have high floating point precision (`highp`). While
`mediump` has seemingly been sufficient on most desktop systems, lower
specced hardware rendered the map poorly as can be seen in [another
issue][0]. With [WebGL2 being based on OpenGL ES 3.0][1], the [OpenGL ES
3.0][2] spec gives flexibility about what exactly `mediump` and `highp`
mean (Section 4.5.1 Range and Precision) but define the `mediump` as at
least a 16 bit floating point number. Per this [stackoverflow
answer][3], it's common for desktop GPUs to map all precision qualifiers
to 32 bit, while mobile GPUs map `mediump` to 16 bits and `highp` to 32
bits. Since 16 bits is not enough to represent every number between 0
and 5632 (citation is needed but basically [go here][4] and enter 5000,
5001, 5002 and see they have the same binary representation), it
therefore is unable to represent every 1/5632 interval between 0 and 1
texture coordinates. The solution is to sprinkle `highp` everywhere that
we are dealing with texture coordinates, so that we can represent every
number in the interval unambiguously. The map now renders beautifully on
mobile GPUs.

The webgl context options have been updated and is reported to close #55

This commit also creates the notion of lazily loading and decoding the
terrain overlay textures. If the user opts into the terrain overlay, the
textures are then fetched and decoded. Not opted users in could see the
map render up to 1 second faster.

The map class now exposes an `onDraw` event handler so that it is easier
to configure logging of map events.

[0]: #16 (comment)
[1]: https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext
[2]: https://www.khronos.org/registry/OpenGL/specs/es/3.0/GLSL_ES_Specification_3.00.pdf
[3]: https://stackoverflow.com/a/46833587
[4]: https://evanw.github.io/float-toy/

Co-authored-by: Christopher Schnick <st141923@stud.uni-stuttgart.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Warn user if map is not supported
1 participant