Pasi Keränen

Introducing Qt Canvas3D

Published Wednesday May 27th, 2015
18 Comments on Introducing Qt Canvas3D
Posted in Qt Canvas3D | Tags: , , ,

Qt Canvas3D is a fully supported Qt module starting from Qt 5.5. Just like WebGL, Canvas3D offers a low level OpenGL-like API that enables you to execute 3D drawing commands from JavaScript. It allows easy porting of WebGL content from HTML to Qt Quick or even sharing the same WebGL code between Qt Quick and HTML applications.

WebGL is a 3D rendering API defined by Khronos Group and has been gaining momentum in the HTML world. It has also been fostering innovation and development of various libraries like three.js, Scene.js and applications like the 3D view of Google Maps. Qt Canvas3D brings a WebGL-like 3D rendering API to Qt Quick JavaScript, enabling the developers to port existing WebGL based assets to Qt Quick to applify their content or to create new 3D content using skills and libraries from the WebGL development world they may already know. It is also very easy to enhance the 3D content with the Qt Quick animations and transition enablers to create interactive 3D experiences that connect to application logic seamlessly and provide beautiful, smoothly animated 3D visualizations.

Since conformance tests for WebGL are pure HTML pages, Canvas3D is not yet WebGL conformant in that it doesn’t pass the official Khronos WebGL API conformance tests. However, we’re in the process of porting those to run on top of Canvas3D and we are selectively fixing conformance issues as we find them. Since the WebGL specification, as it stands today, is tightly coupled with the HTML object system, which doesn’t exist within Qt Quick environment, we’re not sure if we will be able to claim full conformance. However, fortunately based on our experience, this specification language difference doesn’t prevent easy porting or sharing WebGL code between Qt Quick and HTML applications.

Canvas3D Planets example, implemented with three.js and Qt Canvas3D

Screenshot of Canvas3D Planets example included in Qt 5.5

Simple Example

A very simple example of Canvas3D that just paints the screen with a random color could look something like this:

import QtCanvas3D 1.0

Canvas3D {
    id: canvas3d
    anchors.fill: parent
    focus: true
    property var gl

    onInitializeGL: {
        gl = canvas3d.getContext("experimental-webgl");

        // Setup clear color to be a random color
        gl.clearColor(Math.random(), Math.random(), Math.random(), 1.0);

        // Setup viewport
        gl.viewport(0, 0, canvas3d.width * canvas3d.devicePixelRatio, canvas3d.height * canvas3d.devicePixelRatio);
    }

    onPaintGL: {
        // Clear background to current clear color
        gl.clear(gl.COLOR_BUFFER_BIT);
    }

    onResizeGL: {
        var pixelRatio = canvas3d.devicePixelRatio;
        canvas3d.pixelSize = Qt.size(canvas3d.width * pixelRatio, canvas3d.height * pixelRatio);
        if (gl)
            gl.viewport(0, 0, canvas3d.width * canvas3d.devicePixelRatio, canvas3d.height * canvas3d.devicePixelRatio);
    }
}

For those of you who are familiar with QOpenGLWidget this should look pretty familiar, as we’ve tried to keep the names of the signals aligned with the name of the QOpenGLWidget method names.

If you have tried the technology preview versions of Canvas3D, the final version differs in that Qt 5.5 now includes built-in support for JavaScript typed arrays. This means that the Canvas3D API can now get the data needed for 3D rendering more efficiently and with reduced memory footprint. In addition Canvas3D has been better integrated with the Qt Quick JavaScript engine and this shows as better performance. Your mileage may of course vary as this all depends on the content, but we have seen applications that were running around 45-50 fps with TP 1 reaching 59-60 fps with Canvas3D in Qt 5.5.

three.js

As the Canvas3D API is very low level, you may find the three.js library useful in getting started. I maintain a port of three.js on top of Canvas3D at https://github.com/tronlec/three.js. The port includes a few of the three.js examples ported to run on top Canvas3D. These should give you an idea how to get three.js based content to run within Qt Quick on top of Canvas3D. We’ve tried to make the process as simple as possible by porting also some of the utilities included in the three.js examples to Canvas3D as many web content builders use these as well. If you visited our booth in Berlin Qt DevDays last year you may have spotted the award winning WebGL CarVisualizer application demo by Plus 360 Degrees running on top of Canvas3D prototype with just few days of effort. We even added some animations like the different fixed camera angle with transitions and animated color transitions when selecting the color of the car.

Car Visualizer application by Plus 360 Degrees, ported to run on top of Qt Canvas3D.

WebGL Car Visualizer application by Plus 360 Degrees, ported to run on top of Qt Canvas3D.

More Info

Canvas3D has been included in the Qt 5.5 Beta, you can check out the documentation at http://doc-snapshots.qt.io/qt5-5.5/qtcanvas3d-index.html

Our next blog on Canvas3D will show you how you can get started with porting three.js content so that you can run your code on top of Canvas3D.

Do you like this? Share it
Share on LinkedInGoogle+Share on FacebookTweet about this on Twitter

Posted in Qt Canvas3D | Tags: , , ,

18 comments

t3685 says:

What is the main difference between Qt Canvas3D and the upcoming Qt3D 2.0?
The HTML/javascript like API or are there more differences?

Pasi Keränen Pasi Keränen says:

Canvas3D offers a low level API for the QML JavaScript that you can then use to build 3D content. Qt3D 2.0 offers a fully data driven native code scene graph engine that offers both C++ and QML APIs. They are two very different technologies offering alternative paths to implement 3D content in Qt.

t3685 says:

Thanks for clariyfing that up!

James says:

Will “pixi.js” work on Canvas3D?

Pasi Keränen Pasi Keränen says:

I’m not familiar with “pixi.js” intimately. But if it relies on WebGL API then with a bit of porting effort it should be possible. You can check out e.g. the three.js port I’ve done and compare it to the R81 trunc to see what changes have been made. The port also includes some helpers like a wrappers and shims that allow you to load textures just like in HTML with HTML Image element reducing the needed porting effort.

James says:

Got it. thanks.

Tim says:

How is the text drawn in that example? Do you provide access to QtQuick’s fancy distance-field text rendering methods, or is it just QtQuick components overlaid on top of the OpenGL?

Pasi Keränen Pasi Keränen says:

Text in these examples is just QtQuick components overlaid on top of OpenGL. For rendering 3D text with three.js you can check out this three.js example we’ve ported.

Mihail says:

I miss the days when Qt was about C++. “The Qt way” now stands for “QMLify something”.
I love Qt, but I hate the fact I am forced into a lock-in “proprietary” language with unclear future, marketshare, stability, etc.

Matt says:

I think many share your point of view. Notice the small number of comments on QML articles. Digia is out of touch with it’s customer base.

stereomatching says:

Qt Quick is quite suit for simple mobile/tablet UI, but may(I say may because I am not a QML pro) not mature enough for complex application with sophisticaed UI yet

Qt temas focus too much on mobile market.

Pasi Keränen Pasi Keränen says:

I’m partial to QML, I love the language, the speed of development it allows and the awesome efficiency it has in utilising GPU acceleration for 2D UI’s. Having access to WebGL-like API from there makes life that much sweeter (for me).

But I know that not all people share my QML enthusiasm. Luckily Qt 3D 2.0 is still under development and it will offer a pure C++ API, in addition to a QML API, for those customers who do not wish to use QML.

And Qt 3D 2.0 is awesome piece of 3D technology in itself, fully data driven scene graph engine, gotta love that as a GPU geek.

stereomatching says:

I am not a big fans of qml but I do give it a try, impress by the animation effect and how easy you can do it with qml. I spend time to study and try to get familiar with it, it is quite easy to learn and use.

Although I am impress by the performance and the expression power of qml, I never try it with complex app(ex : somethinig like photoshop), the main reasons stop us to use qml for this kind of app are

1 : Many elements of QtQuick are too raw, it lack some good framework similar to QGraphicsView
2 : do not have a complete cook book or example to show us how to do it
3 : The performance of QtQuick is not free, it eat more memory than QWidget, every MB matters on low end mobile phone(I think the easiest way to solve this problem is do not support low end phone^_^, but customers could be unreasonable sometimes)

Mihail says:

Currently Qbs is the only QML technology I am interested in.
And yes, Qt 3D 2.0 sounds great.

Sergey says:

I tested Canvas3d examples from latest 5.5 on my iPad mini 2 and everything works perfect except CPU. For example “Textureandlight” uses 22% CPU, “Framebuffer” uses 33% CPU, “Jsonmodel” uses 66% without animation, and when select “Animate Camera” it uses 85% of CPU.
Sadly qt3d probably completely broken on iOS (at least I none example works, just black screen), so I can’t compare usefulness of this two “potentially” good solutions.

Pasi Keränen Pasi Keränen says:

Thank you for the data points, we’re going to do a blog later on analysing the performance of Canvas3D in various environments. Did you test with debug or release builds?

Sergey says:

Actually I just downloaded snapshot from http://download.qt.io/snapshots/qt/5.5/5.5.0-beta/2015-05-25_76/qt-opensource-mac-x64-android-ios-5.5.0-beta_2015-05-25_09-59-40-76.dmg so I’m not sure what compiler options were specified when libraries were built, but maintainers should know better.

joni says:

Agreed, just tried and compared about performance Qtwebkit webgl implementation took ~100mb, this is same for chromium webgl. and Canvas3D took ~125mb> in windows7 native x64, do we should move JS backend against JavascriptCore from QtWebkit instead of QJSengine ?

Commenting closed.

Get started today with Qt Download now