2017-01-24 4 views
4

Ich sehe große Leistungsprobleme in einer QML-App, die ich geschrieben habe, um eine Punktwolke in einer Scene3d anzuzeigen. Mit 1000 Punkten/Sekunde ist es in Ordnung, aber bei 10.000 hält es im Grunde nur meinen gesamten Computer an. Das Ziel ist es, in Millionen von Punkten aufzusteigen (was eine alte App ist, die eine Qt/VTK-Mischung vor der Verlangsamung machen könnte.)Qt pointcloud langsame Leistung in scene3d

Ich mache mir Sorgen, dass ich die Verarbeitung nicht in einen anderen Thread verlagern werde, oder nicht richtig rendern. ... Dies ist mein erstes Qt-Projekt und ich bin neu in all dem.

Grundsätzlich baue ich einen circular_buffer von Punkten (jeder Punkt ist 32 Bytes), die ich in eine QByteArray auf einem benutzerdefinierten QGeometry, auf einem Entity kopieren. Diese Entität verfügt über ein Material, das einen Vertex- und Fragment-Shader ausführt.

Gibt es etwas, was ich tun kann, um die Leistung zu erhöhen?

Material:

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... 
} 

sind meine Shadern ziemlich einfach:

Vertex:

#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; 
} 

Fragment:

#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); 
} 

Renderer:

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

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 
     ] 
    } 
} 

Antwort

2

das Problem gefunden, und es war nicht in der Info, die ich ursprünglich geschrieben.

In der Einheit hatte ich instanceCount: buffer.count, aber in meiner Geometrie, schreibe ich den gesamten Puffer in einem Schritt. Daher passte ich effektiv die Größe meines Puffers an.

wurde die Lösung instanceCount: 1

Ich hatte verwirrt auf dieser Linie vor zu setzen, auch wenn es zu entfernen, aber ich vermute, dass es auf diesen Wert vorbelegt .. Und ich verstehe nicht die QML docs auf, was genau würde dies machen.

In jedem Fall ist die tatsächliche Verwendung von Geometrien wie SphereGeometry, die einen Puffer für jeden Punkt erstellt. Wenn also ein Punkt angegeben wird, werden die Eckpunkte und Indizes erstellt, um eine Kugel um diesen Punkt zu rendern. (Ich bin nicht sicher, warum sie das nicht in einem Geometry Shader tun.)

Verwandte Themen