Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Qt 3D + QML and Points Cloud. Stuck with data exchange between QML and vertex shader. [QT 5.14.2]



  • Hi guyz,

    let me explain my goal.
    I would like to draw a points cloud with points number > 300 000.
    I first investigated the Qt Data Visualization for Scatter, but performances are not up to my expectations.
    I then investigated the regular Qt Quick 2D and tried to work with shaders, but it was stupid, as results is always 2D :p
    I then investigated the Qt Quick 3D, and thought I could easily modify an example, but I got lost after half a day.
    I then decided to go with Qt 3D, which I think is a good way to go. I work with openGL 3.3.

    Here the simplest plan I came up with.
    1- render a PlaneMesh from QML with a resolution of 640x480 vertices => very easy to achieve thanks to provided examples. OK
    2- generate random z coordinates for 640*480 points and stupidly store them in a QVariantList data type so they can easily be shared with QML in a dedicated pointsCloud class. OK
    3- write a specific vertex shader to modify the z coordinate of each vertices applying values stored in the QVariantList. NOK.
    4- write a specific fragment shader to modify the color of each rendered point depending on the z coordinate value and map them on an HSL color model. OK

    So right now I'm stuck with point 3.
    I try to exchange my QVariantList of 307200 values with my vertex shader.
    One of my tests was to just declare a Parameter as such:
    QML (in the Material definition)
    Parameter {
    id: idMyParam
    name: "zArray[0]"
    value: pointsCloud .zArray
    }
    // I checked the data in pointsCloud.zArray and they are all available in QML.

    Vertex Shader:
    uniform float zArray[307200];

    Doing just the declaration is fine.
    But then I have no idea how to assign the z value for each vertex?
    I tried something like:
    worldPosition.z = zArray [ gl_VertexID ];
    But I get the following compiler issue:
    QOpenGLShader::compile(Vertex): ERROR: 3:21: 'gl_VertexID' : undeclared identifier
    ERROR: 3:21: '[]' : integer expression required

    Then I added the following declaration:
    uniform int gl_VertexID;

    But now the issue I have is the following:
    QOpenGLShader::link: Number of Default Vertex Uniforms exceeds HW limits.
    Number of Vertex Uniforms exceeds HW limits.

    Actually, even if I try something like:
    worldPosition.z = zArray [ 1 ];
    I have the same issue:
    QOpenGLShader::link: Number of Default Vertex Uniforms exceeds HW limits.
    Number of Vertex Uniforms exceeds HW limits.

    So using such a big variant data might not be a good idea, besides I have no idea if the variant in the QML side is existing while the GPU already tries to access the array?

    So I would like to explore other possibilities and I found some QML types like Buffer and Texture1D, but both I have no idea if this is a good idea, nor how to use these QML types, it seems I can not find any information anywhere about them?

    Does someone has a good knowledge in Qt3D and vertex shaders and could give me a hint to help me solve my issues so far?

    I can share the source code if someone is interested, although it is very ugly right now since wip is still fresh...

    Thank you,
    Regards,
    Bill



  • Hi guyz,

    well I just seem to have solved the HW limit issue, by declaring:
    uniform int gl_VertexID;
    uniform float zArray[];

    and
    if (gl_VertexID < 10000)
    {
    worldPosition.z = zArray [ gl_VertexID ];
    }

    And then I realized that my first mistake was probably to think that delaring a PlaneMesh like this:
    PlaneMesh {
    id: mesh
    width: 5.0
    height: 10.0
    meshResolution: Qt.size(640, 480)
    }

    would lead to 307200 vertices, which is probably totally wrong. I have no idea how many vertices are generated by this instruction, does anybody have any idea?

    Thank you,
    Bill



  • @BillouParis2

    I changed my mind, and now decided to go with a Buffer and a QByteArray directly written in C++.
    I will create a new ticket to follow my new issues :p


Log in to reply