Search code examples
qmlqt3d

QT3D QML RenderPassFilter with several key seems bugged


I just started using QML to create a QT3D scene. I would like to filter which elements of my scene are rendered using a RenderPassFilter. Here is my really simple renderer:

import Qt3D.Core 2.0
import Qt3D.Render 2.0

Viewport {
  id: root
  property color clearColor: Qt.rgba(0, 0, 0.2, 1)
  property Camera mainCamera

  RenderSurfaceSelector {
    id: surfaceSelector

    // Clear Buffer
    ClearBuffers {
      buffers: ClearBuffers.ColorDepthBuffer
      clearColor: root.clearColor
      NoDraw {}
    }


    RenderPassFilter {
      matchAny: [FilterKey{name: "type"; value: "filter1"}] // <-- THIS LINE IS THE FILTER 

      CameraSelector {
        id: selector
        camera: mainCamera
      }
    }
  }
}

This properly displays all elements (and only those) that contains a FilterKey{name: "type"; value: "filter1"}

Replacing this with another filter works just fine:

RenderPassFilter {
  matchAny: [FilterKey{name: "type"; value: "filter2"}] // <-- THIS LINE IS THE FILTER 

  CameraSelector {
    id: selector
    camera: mainCamera
  }
}

will display the set of object with the filter value filter2 instead of filter1

Now my problem is that the matchAny field is a list, so I would excpect it to be able to take several elements. Unfortunately the following doesn't display any element at all

RenderPassFilter {
  matchAny: [FilterKey{name: "type"; value: "filter1"}, FilterKey{name: "type"; value: "filter2"}] // <-- THIS LINE IS THE FILTER 

  CameraSelector {
    id: selector
    camera: mainCamera
  }
}

I would expect this to render all elements with either value filter1 or value filter2. What is the way to achieve this?

EDIT: I just realised while posting this that matchAny could mean the opposite of what I though: any filter key in an element has to match what is int the matchAny list (but all the list must be matched)... if that makes sense. Anyway, the question remains: How can I use a RenderPassFilter to allow elements that contain either filter1 or filter2?


Solution

  • Ok, so after many trials, I what I got is:

    1) What I wrote in the question's edit is correct: using

    RenderPassFilter {
      matchAny: [FilterKey{name: "type"; value: "filter1"}]
      // ... stuff
    }
    

    means that a render pass will be exectued if it contains at least the filter FilterKey{name: "type"; value: "filter1"}

    2) The only way to test if a pass has type filter1 or filter2 is to create two different renderPassFilters:

    RenderPassFilter {
      matchAny: [FilterKey{name: "type"; value: "filter1"}]
      // ... stuff
    }
    RenderPassFilter {
      matchAny: [FilterKey{name: "type"; value: "filter2"}]
      // ... stuff
    }