Auf dieser Seite

Qt Quick 3D - Beispiel für Benutzerpasses

Demonstriert das Erstellen von benutzerdefinierten Rendering-Pässen in Qt Quick 3D.

Eine 3D-Szene, die mit benutzerdefinierten Benutzerübergängen gerendert wird

}

Das User Passes Beispiel demonstriert die Erstellung von benutzerdefinierten Renderpasses in Qt Quick 3D. Es zeigt eine einfache 3D-Szene, die mit mehreren benutzerdefinierten Renderpässen gerendert wird, um eine vereinfachte Technik der verzögerten Beleuchtung zu erreichen.

Deaktivieren von internen Renderpässen

Standardmäßig verwendet Qt Quick 3D eine Reihe von internen Render-Passes zum Rendern der 3D-Szene. Manchmal möchten Sie diese internen Pässe deaktivieren und Ihre eigene Rendering-Pipeline mit benutzerdefinierten Renderpässen implementieren.

Um die internen Renderpässe zu deaktivieren, setzen Sie die Eigenschaft renderOverrides von View3D auf View3D.DisableInternalPasses.

View3D {
    id: view3D
    anchors.fill: parent
    renderOverrides: View3D.DisableInternalPasses
    environment: SceneEnvironment {
        lightProbe: Texture {
            textureData: ProceduralSkyTextureData {
            }
        }
        backgroundMode: SceneEnvironment.SkyBox
    }

Wenn Sie die internen Render-Passes deaktivieren, müssen Sie das Ergebnis des Hauptfarbpasses bereitstellen, damit View3D etwas auf dem Bildschirm anzeigen kann.

Geometrie-Puffer-Durchlauf

In diesem Beispiel ist der erste benutzerdefinierte Rendering-Durchgang ein Geometriepuffer-Durchgang (G-Buffer), der die Geometrie der Szene in mehrere Rendering-Ziele rendert und in jedem Ziel unterschiedliche Materialeigenschaften speichert. Das bereitgestellte Beispiel ist eine Teilmenge der vollständigen Materialeigenschaften, die von Qt Quick 3D-Materialien bereitgestellt werden, und konzentriert sich auf die Eigenschaften, die für eine grundlegende Implementierung von Deferred Lighting benötigt werden.

Unser RenderPass ist in GBufferPass.qml definiert:

RenderPass {
    id: gbufferPass
    clearColor: Qt.rgba(0.0, 0.0, 0.0, 0.0)

    property alias layerMask: filter.layerMask
    required property RenderPassTexture depthTexture

    RenderPassTexture {
        id: gbuffer0
        format: RenderPassTexture.RGBA16F
        // rgb: baseColor (linear), a: metalness
    }

    RenderPassTexture {
        id: gbuffer1
        format: RenderPassTexture.RGBA16F
        // rgb: normal, a: roughness
    }

    RenderPassTexture {
        id: gbuffer2
        format: RenderPassTexture.RGBA16F
        // rgb: emissive, a: ao/spare
    }

    commands: [
        ColorAttachment { target: gbuffer0; name: "GBUFFER0" },
        ColorAttachment { target: gbuffer1; name: "GBUFFER1" },
        ColorAttachment { target: gbuffer2; name: "GBUFFER2" },
        DepthTextureAttachment { target: gbufferPass.depthTexture },
        RenderablesFilter {
            id: filter
            renderableTypes: RenderablesFilter.Opaque
        }
    ]

    materialMode: RenderPass.AugmentMaterial
    augmentShader: "gbuffer_augment.glsl"
}

Es definiert 3 Farbzuordnungen und 1 Tiefenzuordnung. Für den Pass sind 3 Texturen erforderlich, die als RenderPassTexture -Objekte innerhalb von RenderPass definiert sind. Diese 3 RenderPassTextures werden als Ziele für die Farbanhänge des Passes verwendet, und der Tiefenanhang verwendet eine Tiefentextur, die von außerhalb des Passes bereitgestellt wird.

Die RenderPass selbst ist auf den Modus AugmentMaterial eingestellt, was bedeutet, dass sie die Materialien der gerenderten Objekte mit zusätzlichem Shader-Code erweitert. Der Erweiterungs-Shader wird in der Datei gbuffer_augment.glsl bereitgestellt, die die erforderlichen Materialeigenschaften an die verschiedenen Renderziele ausgibt.

void MAIN_FRAGMENT_AUGMENT()
{
    vec3 baseColor   = BASE_COLOR.rgb;
    float metalness  = METALNESS;
    float roughness  = ROUGHNESS;
    vec3 worldNormal = normalize(WORLD_NORMAL);

    // GBuffer 0: albedo + metalness
    GBUFFER0 = vec4(baseColor, metalness);

    // GBuffer 1: normal (encoded to 0..1) + roughness
    GBUFFER1 = vec4(worldNormal * 0.5 + 0.5, roughness);

    // GBuffer 2: world position
    GBUFFER2 = vec4(qt_varWorldPos, 1.0);
}

Hier sehen Sie, wie die Grundfarbe, metalness, worldNormal, roughness und world position in den 3 Farbanhängen des G-Buffers gespeichert werden.

Um den G-Buffer-Pass tatsächlich in der Rendering-Pipeline zu verwenden, müssen wir eine Instanz davon in Main.qml erstellen und die erforderliche Tiefentextur bereitstellen:

RenderPassTexture {
    id: mainDepthStencilTexture
    format: RenderPassTexture.Depth24Stencil8
}
GBufferPass {
    id: gbufferPass
    layerMask: ContentLayer.Layer0 | ContentLayer.Layer1
    depthTexture: mainDepthStencilTexture
}

RenderOutputProvider {
    id: gbuffer0Provider
    textureSource: RenderOutputProvider.UserPassTexture
    renderPass: gbufferPass
    attachmentSelector: RenderOutputProvider.Attachment0
}

RenderOutputProvider {
    id: gbuffer1Provider
    textureSource: RenderOutputProvider.UserPassTexture
    renderPass: gbufferPass
    attachmentSelector: RenderOutputProvider.Attachment1
}

RenderOutputProvider {
    id: gbuffer2Provider
    textureSource: RenderOutputProvider.UserPassTexture
    renderPass: gbufferPass
    attachmentSelector: RenderOutputProvider.Attachment2
}

Drei Instanzen von RenderPassTexture werden erstellt, um Verweise auf die gerenderten G-Buffer-Texturen bereitzustellen, die im nachfolgenden Beleuchtungsdurchgang verwendet werden.

Die Eigenschaft layerMask des G-Buffer-Passes ist so eingestellt, dass nur Objekte gerendert werden, die sich auf ContentLayer.Layer0 und ContentLayer.Layer1 befinden. So können wir steuern, welche Objekte im G-Buffer-Pass gerendert werden, indem wir ihre layers Eigenschaft entsprechend einstellen.

Deferred Lighting Pass

Der zweite benutzerdefinierte Rendering-Durchgang ist ein Durchgang mit verzögerter Beleuchtung, der die im G-Buffer gespeicherten Daten zur Berechnung der Beleuchtung für die Szene verwendet. Dieser Durchlauf rendert ein bildschirmfüllendes Quad, das die G-Buffer-Texturen abtastet und Beleuchtungsberechnungen im Fragment-Shader durchführt.

Der Durchgang für die verzögerte Beleuchtung ist in Main.qml wie folgt definiert:

Model {
    id: deferredLightingQuad
    layers: ContentLayer.Layer13
    castsShadows: false
    receivesShadows: false
    geometry: PlaneGeometry {
        // geometry doesn't matter, just need 4 verts
        plane: PlaneGeometry.XY
    }
    materials: [
        CustomMaterial {
            id: lightingPassMaterial
            property TextureInput gbuffer0: TextureInput {
                enabled: true
                texture: Texture {
                    textureProvider: gbuffer0Provider
                }
            }
            property TextureInput gbuffer1: TextureInput {
                enabled: true
                texture: Texture {
                    textureProvider: gbuffer1Provider
                }
            }
            property TextureInput gbuffer2: TextureInput {
                enabled: true
                texture: Texture {
                    textureProvider: gbuffer2Provider
                }
            }
            shadingMode: CustomMaterial.Unshaded
            fragmentShader: "lighting.frag"
            vertexShader: "lighting.vert"
        }
    ]
}

RenderPass {
    id: deferredLightingPass

    readonly property Texture gbuffer0: Texture { textureProvider: gbuffer0Provider }
    readonly property Texture gbuffer1: Texture { textureProvider: gbuffer1Provider }
    readonly property Texture gbuffer2: Texture { textureProvider: gbuffer2Provider }

    materialMode: RenderPass.OriginalMaterial

    commands: [
        ColorAttachment { target: mainColorTexture },
        DepthStencilAttachment {},
        RenderablesFilter { layerMask: ContentLayer.Layer13 }
    ]

}

Das deferredLightingQuad Modell verwendet ein CustomMaterial mit Vertex- und Fragment-Shadern, die in lighting.vert und lighting.frag Dateien definiert sind. Die CustomMaterial hat drei TextureInput Eigenschaften, die verwendet werden, um die G-Buffer-Texturen an die Shader zu übergeben.

Die deferredLightingPass RenderPass rendert das Vollbild-Quad auf die Hauptfarbtextur der View3D. Sie verwendet eine RenderablesFilter, um nur Objekte auf ContentLayer.Layer13 zu rendern, wo sich das deferredLightingQuad Model befindet.

Rendering auf dem Bildschirm

Um schließlich das Ergebnis unserer benutzerdefinierten Rendering-Durchgänge auf dem Bildschirm anzuzeigen, müssen wir sicherstellen, dass die Hauptfarbtextur von View3D mit dem Ergebnis des verzögerten Beleuchtungsdurchgangs aktualisiert wird.

SimpleQuadRenderer {
    texture: Texture {
        textureProvider: mainColorTextureProvider
    }
}

RenderPassTexture {
    id: mainColorTexture
    format: RenderPassTexture.RGBA16F
}

RenderOutputProvider {
    id: mainColorTextureProvider
    textureSource: RenderOutputProvider.UserPassTexture
    renderPass: deferredLightingPass
    attachmentSelector: RenderOutputProvider.Attachment0
}

Hier wird der SimpleQuadRenderer verwendet, um die Hauptfarbtextur von View3D mit der von deferredLightingPass bereitgestellten Textur zu rendern.

Dies ist ein stark vereinfachtes Beispiel für die Verwendung benutzerdefinierter Übergänge in Qt Quick 3D.

Beispielprojekt @ code.qt.io

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