Making your WebGL code more flexible
The August update for Internet Explorer 11 includes new capabilities to help web developers detect when their WebGL application might encounter performance problems due to underlying hardware, including support for the failIfMajorPerformanceCaveat flag and WEBGL_debug_renderer_info extension. These can be added to other best practices to make your WebGL code more adaptable to the hardware that it is running on.
WebGL strategies for addressing hardware diversity
Web developers know that the world where we live is a complex one. The diversity of operating systems, hardware and browsers that our code can run on is huge. For example, to have your code work across diverse hardware means creating adaptable layouts or using graceful degradation. For a WebGL developer this means designing your code to run on high-end hardware that can render millions of triangles, or on a low-end device where 1000 triangles is the limit.
To allow your 3D scene to run on a small device, you can use some of these strategies to address this diversity:
- Remove visual enhancements like shadows or particles
- Reduce texture resolution
- Reduce object complexity by using level of details
- Change the resolution of your canvas and use hardware scaling
- Reduce shader complexity (fewer lights, etc…)
Here's how I handled these differences in the WorldMonger demo on the www.babylonjs.com site:
Here's the full version, complete with shadows, reflection, refraction, and post-process effects. The following steps outline how I reduced the complexity to accommodate less powerful devices.
Step 1 – The post-process is disabled, particles are disabled, shadows are disabled, and the texture resolution is reduced for reflection and refraction
Step 2 – The hardware scaling is now 2x, meaning the canvas resolution is the screen resolution / 2
Step 3 – The hardware scaling is now 4x and texture resolution is reduced again for reflection and refraction
To be able to apply these strategies to reduce scene complexity, you must figure out if the current device is powerful enough or not. To do so, let’s see together different options you have.
Benchmarking
The obvious option is benchmarking. One way is to render some scenes and measure the frames per second on a specific hardware to judge the overall performance. You can get more detail in an article I wrote about how to measure performance:
The main idea in measuring performance is to compute the delta in time between two frames. If the delta time is lower than a given threshold, then you can consider taking actions to reduce your overall rendering complexity.
failIfMajorPerformanceCaveat
Because of the direct access to the GPU allowed by WebGL, browsers must ensure that running your code will not cause a major security issue. For some specific drivers that are not perfectly secure, the browser can prevent hardware acceleration in order to prevent security issues.
To enforce this, IE has a block-list of drivers that are not safe for use with hardware acceleration. On these devices, WebGL will software rendering instead, resulting in a slower but safer experience.
In the August update of Internet Explorer, we support a new flag that you can specify when getting your WebGL context: failIfMajorPerformanceCaveat.
The Khronos specification defines how this attribute works:
Context creation will fail if the implementation determines that the performance of the created WebGL context would be dramatically lower than that of a native application making equivalent OpenGL calls.
When a context is requested on a computer with a block-listed driver, the failIfMajorPerformanceCaveat flag prevents IE from returning a software context, and instead returns no context.
To use it you just have to add it as an option to the getContext function:
var canvas = document.getElementById('renderCanvas');
var context = canvas.getContext('webgl',
{
failIfMajorPerformanceCaveat: true
});
Using this attribute, you can know that the current device isn't powerful or secure enough to run hardware accelerated 3D rendering. Then you can decide to use the software renderer, or if you prefer, let the user know their computer or graphics card aren't supported.
Identifying the renderer
Finally, in conjunction with the failIfMajorPerformanceCaveat attribute, IE also now supports the WEBGL_debug_renderer_info extension (Khronos specification).
The WEBGL_debug_renderer_info extension is a tool to get the renderer and vendor strings for the underlying graphics driver:
var gl = document.createElement('renderCanvas').getContext('experimental-webgl');
var extension = gl.getExtension('WEBGL_debug_renderer_info');
if (extension != undefined) {
var renderer = gl.getParameter(extension.UNMASKED_RENDERER_WEBGL);
console.log('UNMASKED_RENDERER_WEBGL = ' + renderer);
var vendor = gl.getParameter(extension.UNMASKED_VENDOR_WEBGL);
console.log('UNMASKED_VENDOR_WEBGL = ' + vendor);
}
For instance, here is the result I get on one of my computers:
UNMASKED_RENDERER_WEBGL = NVIDIA GeForce GTX 750 Series
UNMASKED_VENDOR_WEBGL = Microsoft
You can use this information to gather useful information for debugging; for example, if you detect using benchmarking that your code is running slowly, then you will be able to gather data for reproducing the issue.
But beware: Like user agent sniffing, using this feature to create a GPU “approved list” could result in a lot of other devices not being able to experience the best your app has to offer. Instead, I recommend targeting the broader audience by using it to only block specific devices that you've identified to perform poorly with your app.
Conclusion
Being able to create WebGL experiences that works seamlessly in all kinds of configurations is extremely hard. However, you can use these tools to have more control over the device and give more feedback to your users.
We will be sharing more details about WebGL support in the latest version of IE11 soon. In the meantime, we look forward to your feedback @IEDevChat or on Connect.
— David Catuhe, Principal Program Manager, Internet Explorer
Comments
Anonymous
September 12, 2014
In last month's AMA on reddit, it was explained that poor WebGL performance on some software/hardware configurations was due to IE falling back to software mode for security reasons: "On some older NVidia & some (Windows 7) AMD GPUs we render WebGL in software rendering mode for security reasons; you might be on a system where IE is rendering WebGL content in software rendering mode. (Take a look at the F12 console; it'll say in there.)" I'm using an AMD Radeon 7970 on Windows 7 and WebGL doesn't work (more specifically, it does not appear to be GPU accelerated) for me in IE11 (presumably for this reason). Is any progress being made towards this issue?Anonymous
September 12, 2014
The comment has been removedAnonymous
September 12, 2014
@Mark: Radeon 7970 is not particularly old though.Anonymous
September 13, 2014
What about the increasing fingerprinting factor that this extension provides?Anonymous
September 13, 2014
When will IE start with support for h.265 video codec in html5 tag.Anonymous
September 14, 2014
The comment has been removedAnonymous
September 14, 2014
Maybe Microsoft does not understand that consuming media is the #1 thing that people do on the internet. Who cares about WebGLAnonymous
September 14, 2014
.They talk about it a lot, yeah, I'mAnonymous
September 14, 2014
Could you please provide details whether XNA 5 will support compiling to Asm.js and use Web GL? Thank you! Any details on your collaboration with MonoGame developers would also be appreciated. XNA 5 is a top request by users: visualstudio.uservoice.com/.../3725445-xna-5Anonymous
September 15, 2014
The comment has been removedAnonymous
September 17, 2014
@Nacimota also some of the GPU manufactures have issues where they force the browsers to use the GPU on the CPU rather than the gfx card so you will get decreased performance see here: alteredqualia.com/.../optimus which is also why the unmasked renderer is important to knowAnonymous
September 18, 2014
@Ben Adams, your link says that IE doesn't support unmasked. This blog post contradicts it. So when people say web developers are bunch of fkin liars spreading FUD, they aren't wrong eh?