Announcement

Collapse
No announcement yet.

Transfer model matrix to Vertex shader

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Transfer model matrix to Vertex shader

    I am currently writing some advanced lighting shaders for my OpenInventor 9.x programs. I now need the model matrix in the vertex shader. The problem is that only the modelview matrix is avaialbel by the build in uniform variable gl_modelViewMatrix, but there is no build in variable for only the model matrix. My question is know how the model matrix, which is surly available in OIV, can be passed to the vertex shader. Is the SoModelMatrixElement a way to do this and if yes can somebody provide some sample code?

    Cheers and many thanks in advance

    Leonhard

  • #2
    Originally posted by hardi2111 View Post
    I am currently writing some advanced lighting shaders for my OpenInventor 9.x programs. I now need the model matrix in the vertex shader. The problem is that only the modelview matrix is avaialbel by the build in uniform variable gl_modelViewMatrix, but there is no build in variable for only the model matrix. My question is know how the model matrix, which is surly available in OIV, can be passed to the vertex shader. Is the SoModelMatrixElement a way to do this and if yes can somebody provide some sample code?
    Hi Leonhard,
    I think you're on the right track. I think you should be able to do something like this:
    • Create the SoVertexShader object
    • Create an SoShaderParameterMatrix object,
      set the name to (for example) "ModelMatrix") and add it to the vertex shader
    • Create an SoCallback node
      and give it a pointer to the SoShaderParameterMatrix object
    • In the callback function
      • Get the model matrix from SoModelMatrixElement
      • Set that matrix in the SoShaderParameterMatrix object
    • Add the SoCallback node to the scene graph before the SoShaderProgram node (that contains your vertex shader object)
    Good luck! :-)
    Mike

    Comment


    • #3
      Hi Mike,

      thanks fpr your answer. I tried to implement your proposal but I doesn't work like expected. I wrote the following code:

      void initNodes()
      {
      ...
      m_sceneSpecialRendering = new SoSeparator;
      m_sceneSep->addChild(m_sceneSpecialRendering);

      m_geometrySep = new SoSeparator;
      m_sceneSpecialRendering->addChild(m_geometrySep);
      ...
      }

      void setupShader()
      {
      ...

      sModelMatrix = new SoShaderParameterMatrix;
      sModelMatrix->ref();
      sModelMatrix->name = "sModelMatrix";
      ...

      SoVertexShader * myVertexShader = new SoVertexShader;
      SoFragmentShader * myFragmentShader = new SoFragmentShader;
      myVertexShader->sourceProgram.setValue("shader/ViAsVertex.glsl");
      myFragmentShader->sourceProgram.setValue("shader/ViAsFragment.glsl");

      // Set parameter for shader
      ...
      myVertexShader->parameter.set1Value(3, sModelMatrix);
      ...


      // Initialize and set the shader program
      SoShaderProgram * shaderProgram = new SoShaderProgram;
      shaderProgram->shaderObject.set1Value(0, myVertexShader);
      shaderProgram->shaderObject.set1Value(1, myFragmentShader);

      m_sceneSpecialRendering->insertChild(shaderProgram,0);

      m_modelCallBack = new SoCallback;
      m_modelCallBack->setCallback(modelCallback, sModelMatrix);
      m_sceneSpecialRendering->insertChild(m_modelCallBack,0);

      ...
      }

      void modelCallback(void *userdata, SoAction *action)
      {
      SoState* state = action->getState();

      SoModelMatrixElement *modelMat;
      SoShaderParameterMatrix *ptrToMatrix = (SoShaderParameterMatrix*)userdata;
      ptrToMatrix->value.setValue(modelMat->get(state));

      }


      With the initNodes()function the main senegraph is built up. Under the m_geometry Separator all geometry is placed. The setupShader() inserts all necessary nodes for the shaders and also the callbalk node you suggested. In the modelCallback() the model Matrxs is retrieved and transfered to the shader.
      The problem now is that I would expect to get different model matrices depending on the state of the traversal, as I have different subgraphs under the
      m_geometry node with different SoTransform nodes. Moreover the modelMatrix I get does'nt make sense for any of the subgraphs, as in every subgraph scaling as applied and the modelMatrix I retrive only holds a transform, but these transfrom also does not fit to any of the subgraphs. I also tried a version were I placed the SoCallback at the very beginning of the main scene graph and there I only got as result an identity matrix, which does not make sense at all to me because there all transforms of the scenegraph should be accumulated. But perhaps I have a wrong expectation to the whole thing???

      Cheers an many thanks in advance for an hopefully clarifying answer,

      Leonhard

      Comment


      • #4
        Hi Leonhard,
        I confirm that querying the model matrix from SoModelMatrixElement works as expected.
        In the attached test case I create:
        - A cone at the root of the scene graph
        - A cone translated -2,-2,0
        - A cone translated 2,2,0
        Each of the cones has an associated SoCallback node that queries and prints the model matrix from the SoModelMatrixElement.
        So the scene looks like this:

        ModelMatrixTest.png

        And the console output looks like this:
        Root
        [ 1 0 0 0 ]
        [ 0 1 0 0 ]
        [ 0 0 1 0 ]
        [ 0 0 0 1 ]

        Subgraph1
        [ 1 0 0 0 ]
        [ 0 1 0 0 ]
        [ 0 0 1 0 ]
        [ -2 -2 0 1 ]

        Subgraph2
        [ 1 0 0 0 ]
        [ 0 1 0 0 ]
        [ 0 0 1 0 ]
        [ 2 2 0 1 ]

        As expected, the model matrix is identity at the root of the scene graph because that's the default value until changed by a transform node.
        Hope that helps.
        -Mike

        Test_ModelMatrixElement.zip

        Comment


        • #5
          Hi Mike,

          thanks for the fast answer. I now placed the Callback after the transform nodes in the subraphs, as suggested by you, and now I also retrieve the right model matricse. So this part works now. But with this the next question arises. How to pass the different model matrices to the vertex shader per subgraph. I could pass the model matrices as a array of uniform SoShaderParameterMatrix, but I have no information inside the shader to figure out which vertex belongs to wich subraph. In OpenGL I possibly could do it with Vertex array objects (VAO), so one model matrix per VAO. But how to do it in OpenInventor?

          Cheers

          Leonhard

          Comment

          Working...
          X