本页

Qt Quick 3D - 用户通行证示例

演示在Qt Quick 3D 中创建自定义渲染通道。

使用自定义用户通行证渲染 3D 场景

}

用户通道示例演示了如何在Qt Quick 3D 中创建自定义渲染通道。它展示了一个简单的 3D 场景,该场景使用多个用户定义的渲染传递进行渲染,以实现简化的延迟照明技术。

禁用内部渲染传递

默认情况下,Qt Quick 3D 使用一组内部渲染传递来渲染 3D 场景。有时,您可能希望禁用这些内部传递,并使用用户定义的渲染传递实现自己的渲染管道。

要禁用内部呈现通道,请将View3D 的 renderOverrides 属性设置为View3D.DisableInternalPasses

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

如果禁用内部渲染传递,则需要提供主颜色传递的结果,这样View3D 才能在屏幕上显示任何内容。

几何图形缓冲区传递

在本示例中,第一个自定义渲染传递是几何图形缓冲区(G-buffer)传递,它将场景几何图形渲染到多个渲染目标中,并在每个目标中存储不同的材质属性。所提供的示例是Qt Quick 3D 材质所提供的全部材质属性的子集,侧重于基本延迟照明实施所需的属性。

我们的RenderPass 定义于GBufferPass.qml

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"
}

它定义了 3 个颜色附件和 1 个深度附件。该通道需要 3 种纹理,它们被定义为RenderPass 内的RenderPassTexture 对象。这 3 种 RenderPassTextures 被用作该通道色彩附件的目标,而深度附件则使用通道外部提供的深度纹理。

RenderPass 本身设置为AugmentMaterial 模式,这意味着它将使用额外的着色器代码来增强渲染对象的材质。增强着色器在gbuffer_augment.glsl 文件中提供,它会将所需的材质属性输出到多个渲染目标。

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);
}

在这里,你可以看到基色、金属度、世界法线、粗糙度和世界位置是如何存储到 G 缓冲区的 3 个颜色附件中的。

要在渲染管道中实际使用 G 缓冲通道,我们需要在Main.qml 中创建一个实例,并提供所需的深度纹理:

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
}

我们创建了RenderPassTexture 的三个实例,以提供对渲染的 G 缓冲区纹理的引用,这些纹理将在随后的光照传递中使用。

G 缓冲传递的layerMask 属性设置为只渲染ContentLayer.Layer0 和ContentLayer.Layer1 上的对象。这样,我们就可以通过相应设置layers 属性来控制在 G 缓冲通道中渲染的对象。

延迟照明传递

第二个自定义渲染传递是延迟光照传递,它使用 G 缓冲区中存储的数据来计算场景的光照。该通道渲染全屏四边形,对 G 缓冲区纹理进行采样,并在片段着色器中应用光照计算。

延迟光照传递在Main.qml 中定义如下:

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 }
    ]

}

deferredLightingQuad 模型使用CustomMaterial ,顶点和片段着色器定义在lighting.vertlighting.frag 文件中。CustomMaterial 有三个TextureInput 属性,用于将 G 缓冲纹理传递给着色器。

deferredLightingPass RenderPass 将全屏四边形渲染为View3D 的主色调纹理。它使用RenderablesFilter 只渲染ContentLayer.Layer13 上的对象,也就是deferredLightingQuad 模型所在的层。

渲染到屏幕

最后,为了在屏幕上显示自定义渲染传递的结果,我们需要确保View3D 的主色纹理根据延迟光照传递的结果进行更新。

SimpleQuadRenderer {
    texture: Texture {
        textureProvider: mainColorTextureProvider
    }
}

RenderPassTexture {
    id: mainColorTexture
    format: RenderPassTexture.RGBA16F
}

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

在这里,SimpleQuadRenderer 使用deferredLightingPass 提供的纹理来渲染View3D 的主颜色纹理。

这是一个在Qt Quick 3D 中使用自定义用户传递的高度简化示例。

示例项目 @ 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.