Renderizado por instancias
Introducción
Qt Quick 3D permite crear instancias de objetos en Model. El instanciado se refiere a una técnica en la que un objeto se renderiza varias veces con una única llamada de dibujo. (Por ejemplo, la función OpenGL glDrawElementsInstanced.)
El instanciado permite duplicar un modelo con variaciones. A diferencia de lo que ocurre en Repeater3D, el modelo y sus recursos gráficos sólo se asignan una vez. El renderizado de las instancias duplicadas se realiza a bajo nivel por la GPU. Dependiendo de la complejidad del modelo, esto puede suponer una mejora del rendimiento de varios órdenes de magnitud.
En la práctica, el instanciado se realiza definiendo una tabla que especifica cómo se modifica cada instancia en relación con el modelo base.
API de instanciación
El principio fundamental de la API de instanciación es que es explícita: No trata de detectar automáticamente las posibilidades de creación de instancias dentro de la API existente. En su lugar, cada modelo se marca individualmente estableciendo su propiedad instancing para hacer referencia a un objeto Instancing. El mismo objeto Instancing puede utilizarse en varios modelos al mismo tiempo.
El objeto Instancing especifica una tabla que define cómo se renderiza cada copia. Las modificaciones disponibles son
- transformación: posición, rotación y escala
- color: un color que se mezcla con el material del modelo
- datos personalizados: datos que pueden ser utilizados por materiales personalizados
Qt proporciona tres tipos QML que heredan de Instancing:
- InstanceList enumera todas las instancias y permite enlazar con las propiedades de cada instancia.
- RandomInstancing proporciona una forma rápida de probar y crear prototipos generando instancias aleatorias dentro de unos límites definidos.
- FileInstancing lee una tabla de instancias de un archivo externo.
El ejemplo de instanciación muestra cómo crear una escena utilizando la API QML.
Se pueden definir otros tipos de tablas de instancias en C++ subclasificando QQuick3DInstancing. Por ejemplo, particle system utiliza internamente su propia tabla de instanciación. Está disponible como ModelParticle3D.instanceTable.
Escribiendo código de sombreado personalizado, es posible utilizar el instanciado para controlar propiedades adicionales, como variables para el renderizado basado en la física, pesos de animación del esqueleto, distorsión o cualquier otra cosa que pueda expresarse con materiales personalizados. Los datos personalizados de la tabla de instanciación constan de cuatro números de coma flotante.
El ejemplo de instanciación personalizada muestra cómo combinar materiales personalizados y una tabla de instanciación implementada en C++.
Mezcla alfa e instanciación
Una mezcla alfa correcta requiere que los objetos semitransparentes se representen de atrás hacia delante. Por este motivo, QtQuick3D ordena los objetos opacos y semitransparentes por separado y los renderiza en el orden correcto. Sin embargo, con el instanciado, la GPU renderizará las instancias en el orden especificado por la tabla de instanciado, si depth-sorting no está activado. Por razones de rendimiento, QtQuick3D no ordena la tabla por defecto, ya que puede tardar mucho tiempo con un gran número de instancias. Esto significa que si las instancias semitransparentes se solapan entre sí, o con otros objetos semitransparentes, los resultados pueden parecer erróneos. En general, el error es menos visible cuando la opacidad es baja.
Los objetos totalmente opacos junto con objetos semitransparentes no superpuestos siempre se renderizarán correctamente, ya que Qt utiliza la comprobación del búfer de profundidad para evitar dibujar detrás de objetos opacos. Sin embargo, la falta de ordenación tiene implicaciones potenciales de rendimiento para los objetos opacos: Pueden no ser renderizados en el orden óptimo, lo que significa que el mismo píxel puede ser escrito varias veces, haciendo más trabajo para el fragment shader.
El renderizador no inspecciona el contenido de la tabla de instancias, por lo que debe especificarse explícitamente cuando una tabla de instancias contiene valores alfa semitransparentes: Establezca la propiedad hasTransparency a true para asegurarse de que el renderizador habilita la mezcla alfa. Esto se aplica a todas las instancias: Incluso las instancias completamente opacas se renderizarán sin comprobación de profundidad, causando potencialmente errores visibles.
El orden de renderizado relativo al resto de la escena puede ajustarse configurando depth bias del modelo.
Transformaciones e instanciación
Cada instancia tiene su propia transformación en la tabla de instancias. Esto se combina con las transformaciones del modelo instanciado. Esto es un poco complejo, ya que hay varios casos de uso:
- Hacer una transformación en el modelo que se aplica a cada instancia individual. Esto permite animaciones baratas, por ejemplo rotando todas las instancias a la vez sin tener que cambiar la tabla de instancias.
- Transformar todo el grupo de instancias a la vez.
- Crear instancias de una jerarquía de modelos.
Para soportar todos estos casos, la transformación del modelo se divide en dos partes: la transformación de instancia local y la transformación de instancia global. Conceptualmente, la instanciación se realiza así:
- Primero se transforma el modelo según la transformación de instancia local.
- A continuación, se calcula cada instancia aplicando la transformación de la tabla de instancias.
- Por último, todo el grupo de objetos instanciados se transforma según la transformación de instancia global.
Por defecto, la transformación de instancia local de un modelo consiste en la escala y rotación del modelo, mientras que el resto va a la transformación de instancia global.
Esto puede controlarse estableciendo la propiedad instanceRoot del modelo. Esto define el origen del sistema de coordenadas de la instancia. El uso más común es cuando se instancian una jerarquía de modelos. Por ejemplo, una esfera orbitando alrededor de un cubo:
Model { id: cube instancing: someInstanceTable source: "#Cube" materials: DefaultMaterial { diffuseColor: "lightgray" } Node { Model { source: "#Sphere" instanceRoot: cube instancing: cube.instancing x: 150 materials: DefaultMaterial { diffuseColor: "gray" } } NumberAnimation on eulerRotation.y { from: 0 to: 360 duration: 4000 loops: Animation.Infinite } } }
El instanceRoot es necesario para especificar que la instancia de la esfera debe posicionarse como si fuera un elemento del cubo. Cada modelo en una jerarquía aún necesita especificar la propiedad instancing: en casos normales todos deben ser fijados al mismo objeto Instancing.
instanceRoot también puede utilizarse para crear instancias de un único modelo. Por ejemplo, un cilindro que gira alrededor de un punto descentrado:
Node { id: parentNode Model { source: "#Cylinder" instanceRoot: parentNode instancing: anotherInstanceTable x: 25 materials: DefaultMaterial { diffuseColor: "white" } } NumberAnimation on eulerRotation.y { from: 0 to: 360 duration: 1000 loops: Animation.Infinite } }
Selección e instanciación
Picking es un mecanismo que permite seleccionar un modelo a partir de una interacción con la interfaz de usuario. Con el renderizado instanciado, existen varias representaciones del mismo modelo, por lo que el resultado del picking incluirá un instance index. El picking instanciado se habilita configurando la propiedad pickable en el modelo base.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.