Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. How to pass QML array to OpenGL shader

How to pass QML array to OpenGL shader

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
3 Posts 2 Posters 1.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • O Offline
    O Offline
    oska
    wrote on 5 Apr 2017, 19:03 last edited by
    #1

    Hello everyone,
    I am implementing an application using QML 3D, there is 3D scene in this application and you can move around in the scene.
    I am trying to pass an array of vectors from QML into fragment shader, but it doesn't work for me.

    I am using Scene3D QML type as the viewport into OpenGL scene.
    My project is implemented in really similar way as this example https://doc.qt.io/qt-5/qt3d-shadow-map-qml-example.html.
    I have scene with shadows and I need to have more than just one light in the scene.

    The important part is :
    My implementation of Effect in QML

    Effect {
    
        parameters: [
            Parameter { name: "lightViewProjection"; value: root.light.lightViewProjection },
            Parameter { name: "lightPosition"; value: 
    [Qt.vector3d(30.0, 100.0, 0.0), Qt.vector3d(-30.0, 100.0, 0.0)] },
            Parameter { name: "lightIntensity"; value: 
    [Qt.vector3d(0.5, 0.5, 0.5), Qt.vector3d(0.5, 0.5, 0.5)] },
            Parameter { name: "shadowMapTexture"; value: root.shadowTexture },
        ]
    
        techniques: [
            Technique {
                graphicsApiFilter {
                    api: GraphicsApiFilter.OpenGL
                    profile: GraphicsApiFilter.CoreProfile
                    majorVersion: 3
                    minorVersion: 2
                }
    
                renderPasses: [
    
                    RenderPass {
                        filterKeys: [ FilterKey { name: "pass"; value: "shadowmap" } ]
                        shaderProgram: ShaderProgram {
                            id: shader1
                            vertexShaderCode:   loadSource("qrc:/shaders/shaders/shadowmap.vert")
                            fragmentShaderCode: loadSource("qrc:/shaders/shaders/shadowmap.frag")
                        }
                        renderStates: [
                            PolygonOffset { scaleFactor: 4; depthSteps: 4 },
                            DepthTest { depthFunction: DepthTest.Less }
                        ]
                    },
    
                    RenderPass {
                        filterKeys: [ FilterKey { name: "pass"; value: "forward" } ]
                        shaderProgram: ShaderProgram {
                            vertexShaderCode:   loadSource("qrc:/shaders/shaders/myshader.vert")
                            fragmentShaderCode: loadSource("qrc:/shaders/shaders/myshader.frag")
                        }
                    }
                ]
            }
        ]
    }
    

    just important part of my fragment shader:

    uniform vec3 lightPosition [2];     // set from QML Effect
    uniform vec3 lightIntensity [2];    // set from QML Effect
    uniform sampler2DShadow shadowMapTexture;   // set from QML Effect
    

    The problem is the data are not loaded from QML to the shader when there is array.
    If I declare static values in the shader like this LightPosition[0] = vec3(10, 0, 20) and so on everything works.
    If I pass only one vector3d from QML and don't use array neither in shader, it works as well.

    Can someone help me how to pass array of vector3d from qml to shader?

    1 Reply Last reply
    0
    • ? Offline
      ? Offline
      A Former User
      wrote on 5 Apr 2017, 21:04 last edited by
      #2

      Hi! Looking at quick3dparameter.cpp...

      void Quick3DParameterPrivate::setValue(const QVariant &value)
      {
          if (value.userType() == qjsValueTypeId) {
              QJSValue v = value.value<QJSValue>();
              if (v.isArray())
                  QParameterPrivate::setValue(value.value<QVariantList>());
          } else {
              QParameterPrivate::setValue(value);
          }
      }
      

      ...to me, at least it looks as if the JS-to-Parameter-Item-part should work. So, before we start further investigations, one stupid question: what's your Qt version?

      1 Reply Last reply
      0
      • O Offline
        O Offline
        oska
        wrote on 6 Apr 2017, 08:08 last edited by
        #3

        I am using Qt 5.7.1
        To store the value is called this function:

        void Quick3DParameterPrivate::setValue(const QVariant &value)
        

        or this one:

        void QParameterPrivate::setValue(const QVariant &v)
        {
            Qt3DCore::QNode *nodeValue = v.value<Qt3DCore::QNode *>();
            if (nodeValue != nullptr)
                m_backendValue = QVariant::fromValue(nodeValue->id());
            else
                m_backendValue = v;
            m_value = v;
        }
        

        As in the documentation is said that Parameter QML Type Instantiates QParameter.

        1 Reply Last reply
        0

        1/3

        5 Apr 2017, 19:03

        • Login

        • Login or register to search.
        1 out of 3
        • First post
          1/3
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved