Qt pointcloud在scene3d中表现缓慢

时间:2017-01-24 18:16:04

标签: c++ performance qt qml glsl

我在QML应用中看到了主要的性能问题,我写这篇文章是为了展示Scene3d中的点云。它的速度可以达到1000点/秒,但是在10,000点它基本上只会停止我的整台计算机。目标是达到数百万点(这是旧的应用程序,Qt / VTK混合物可以在减速之前完成。)

我担心我没有将处理卸载到另一个线程,或者没有正确渲染。 ......这是我的第一个Qt项目,对所有这些都是新手。

基本上我构建了一个圆点缓冲点(每个点都是32个字节),我将其复制到QByteArray上的自定义QGeometry上的Entity。此实体具有运行顶点和片段着色器的材质。

我能做些什么来提高性能吗?

材料

import Qt3D.Core 2.0
import Qt3D.Render 2.0

Material {
    effect: Effect {
        techniques: Technique {
            renderPasses: RenderPass {
                shaderProgram: ShaderProgram {
                    vertexShaderCode: loadSource("qrc:/shaders/pointcloud.vert")
                    fragmentShaderCode: loadSource("qrc:/shaders/pointcloud.frag")
                }
                renderStates: [
                    PointSize { sizeMode: PointSize.Programmable } //supported since OpenGL 3.2
                ]
            }
            graphicsApiFilter {
                api: GraphicsApiFilter.OpenGL
                profile: GraphicsApiFilter.CoreProfile
                majorVersion: 4
                minorVersion: 3
            }
        }
    }
        // some parameters...
}

我的着色器非常简单:

顶点

#version 430

layout(location = 1) in vec3 vertexPosition;

out VertexBlock
{
    flat vec3 col;
    vec3 pos;
    vec3 normal;
} v_out;

uniform mat4 modelView;
uniform mat3 modelViewNormal;
uniform mat4 mvp;
uniform mat4 projectionMatrix;
uniform mat4 viewportMatrix;

uniform float pointSize;
uniform float maxDistance;

void main()
{
    vec3 vertexNormal = vec3(1.0, 1.0, 1.0);
    v_out.normal = normalize(modelViewNormal * vertexNormal);
    v_out.pos    = vec3(modelView * vec4(vertexPosition, 1.0));

    float c      = (vertexPosition[0]*vertexPosition[0] + vertexPosition[1]*vertexPosition[1])*maxDistance;
    v_out.col    = vec3(c,c,0.5);

    gl_Position = mvp * vec4(vertexPosition, 1.0);
    gl_PointSize = viewportMatrix[1][1] * projectionMatrix[1][1] * pointSize / gl_Position.w;
}

片段

#version 430

in VertexBlock
{
    flat vec3 col;
    vec3 pos;
    vec3 normal;
} frag_in;

out vec4 colour;

void main()
{
    colour = vec4(frag_in.col, 1.0);
}

渲染

import Qt3D.Core 2.0
import Qt3D.Render 2.0

import "Cameras"

RenderSettings {
    id: root

    property CameraSet cameraSet: CameraSet {
        id: cameraSet
    }

    property real userViewWidth: 0.79
    property real topOrthoViewHeight: 0.79

    activeFrameGraph: Viewport {
        id: viewport
        normalizedRect: Qt.rect(0.0, 0.0, 1.0, 1.0)

        RenderSurfaceSelector {
            ClearBuffers {
                buffers : ClearBuffers.ColorDepthBuffer
                clearColor: theme.cSceneClear

                NoDraw {}
            }

            Viewport {
                id: userViewport
                normalizedRect: Qt.rect(0, 0, userViewWidth, 1.0)

                CameraSelector {
                    id: userCameraSelectorViewport
                    camera: cameraSet.user.camera
                }
            }
            // Two other viewports...
        }
    }
}

实体

Entity {
    property PointBuffer buffer: PointBuffer {
        id: pointBuffer
    }

    PointsMaterial {
        id: pointsMaterial
        dataBuffer: pointBuffer
    }

    Entity {
        id: particleRenderEntity
        property GeometryRenderer particlesRenderer: GeometryRenderer {
            instanceCount: buffer.count
            primitiveType: GeometryRenderer.Points
            geometry: PointGeometry { buffer: pointBuffer }
        }

        components: [
            particlesRenderer
            , pointsMaterial
        ]
    }
}

1 个答案:

答案 0 :(得分:2)

发现问题,而且我最初发布的信息中没有。

在实体中,我有instanceCount: buffer.count,但在我的Geometry中,我只需一步编写整个缓冲区。因此,我实际上正在调整缓冲区的大小。

解决方案是设置instanceCount: 1

我之前对这条线路感到困惑,甚至删除了它,但我怀疑它违反了这个价值。而且我并不了解QML文档究竟会做什么。

在任何情况下,实际使用的方法都是像SphereGeometry这样的几何,它为每个点构建一个缓冲区。因此,给定一个点,它构建顶点和索引以在该点周围渲染球体。 (我不确定他们为什么不在几何着色器中这样做。)