Revision control

Copy as Markdown

// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick3D
import QtQuick3D.Helpers
ApplicationWindow {
width: 1280
height: 720
visible: true
title: qsTr("User Passes")
// ![disable internal passes]
View3D {
id: view3D
anchors.fill: parent
renderOverrides: View3D.DisableInternalPasses
environment: ExtendedSceneEnvironment {
backgroundMode: SceneEnvironment.SkyMaterial
skyMaterial: ProceduralSkyMaterial {}
}
// ![disable internal passes]
//! [main texture]
SimpleQuadRenderer {
texture: Texture {
textureProvider: mainColorPassProvider
}
}
RenderPassTexture {
id: mainColorTexture
format: RenderPassTexture.RGBA16F
}
RenderOutputProvider {
id: mainColorPassProvider
textureSource: RenderOutputProvider.UserPassTexture
renderPass: mainColorPass
attachmentSelector: RenderOutputProvider.Attachment0
}
//! [main texture]
//! [depth texture]
RenderPassTexture {
id: mainDepthStencilTexture
format: RenderPassTexture.Depth24Stencil8
}
//! [depth texture]
Node {
id: originNode
y: 180
PerspectiveCamera {
id: cameraNode
z: 300
}
}
DirectionalLight {
eulerRotation.x: -45
castsShadow: true
}
// ![deferred lighting quad]
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"
}
]
}
// ![deferred lighting quad]
// ![main color pass]
RenderPass {
id: mainColorPass
clearColor: "black"
// Preserve depth across SubRenderPasses so geometry depth is available
// when rendering the skybox, transparent objects, and 2D items.
renderTargetFlags: RenderPass.RenderTargetFlags.PreserveDepthStencilContents
commands: [
ColorAttachment {
target: mainColorTexture
},
DepthTextureAttachment {
target: mainDepthStencilTexture
},
RenderablesFilter {
// Nothing renders directly in the outer pass; all rendering
// is delegated to the SubRenderPasses below.
renderableTypes: RenderablesFilter.None
},
// 1. Deferred lighting: shade opaque geometry stored in the G-buffer.
SubRenderPass {
renderPass: RenderPass {
id: deferredLightingPass
materialMode: RenderPass.OriginalMaterial
commands: [
PipelineStateOverride {
// The full-screen quad must not write or test depth;
// geometry depth was already written by the G-buffer pass.
depthWriteEnabled: false
depthTestEnabled: false
},
RenderablesFilter { layerMask: ContentLayer.Layer13 }
]
}
},
// 2. Skybox: render the environment behind all scene geometry.
SubRenderPass {
renderPass: RenderPass {
id: skyboxPass
passMode: RenderPass.SkyboxPass
commands: [
PipelineStateOverride {
// The skybox is rendered "at infinity" so it must
// depth-test (to be hidden by geometry) but must not
// write depth.
depthTestEnabled: true
depthWriteEnabled: false
}
]
}
},
// 3. 2D items: render any Qt Quick Items embedded in the 3D scene.
SubRenderPass {
renderPass: RenderPass {
id: item2DPass
passMode: RenderPass.Item2DPass
}
},
// 4. Transparent objects: render blended geometry on top of everything else.
SubRenderPass {
renderPass: RenderPass {
id: transparentItemPass
materialMode: RenderPass.OriginalMaterial
commands: [
RenderablesFilter {
renderableTypes: RenderablesFilter.Transparent
layerMask: ContentLayer.Layer0 | ContentLayer.Layer1
},
PipelineStateOverride {
// Enable alpha blending and depth testing so transparent
// objects sort correctly against opaque geometry.
blendEnabled: true
depthTestEnabled: true
targetBlend0.enable: true
targetBlend0.srcColor: RenderTargetBlend.SrcAlpha
targetBlend0.dstColor: RenderTargetBlend.OneMinusSrcAlpha
targetBlend0.srcAlpha: RenderTargetBlend.One
targetBlend0.dstAlpha: RenderTargetBlend.OneMinusSrcAlpha
}
]
}
}
]
// ![GBufferPass usage]
// The G-buffer pass is nested inside its consumer, so it renders
// first and the deferred lighting samples this frame's G-buffers.
GBufferPass {
id: gbufferPass
layerMask: ContentLayer.Layer0 | ContentLayer.Layer1
depthTexture: mainDepthStencilTexture
}
// ![GBufferPass usage]
}
// ![main color pass]
// ![gbuffer providers]
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
}
// ![gbuffer providers]
Model {
id: donut
layers: ContentLayer.Layer1
y: 100
z: 4
geometry: TorusGeometry {
radius: 100
tubeRadius: 30
segments: 64
rings: 32
}
materials: [
PrincipledMaterial {
baseColor: "#ffcc00"
metalness: 0.0
roughness: 0.5
}
]
NumberAnimation on eulerRotation.y {
from: 0
to: 360
duration: 8000
loops: Animation.Infinite
running: true
}
}
Model {
id: ground
layers: ContentLayer.Layer0
geometry: PlaneGeometry {
width: 1000
height: 1000
plane: PlaneGeometry.XZ
}
materials: [
PrincipledMaterial {
baseColor: "brown"
metalness: 0.0
roughness: 0.5
}
]
}
// ![transparent cone]
Model {
id: cone
layers: ContentLayer.Layer1
source: "#Cone"
y: 100
materials: [
PrincipledMaterial {
baseColor: Qt.rgba(0.0, 1.0, 0.0, 0.5)
alphaMode: PrincipledMaterial.Blend
metalness: 0.0
roughness: 0.5
}
]
}
// ![transparent cone]
// ![item2d node]
Node {
x: -200
y: 100
Item {
anchors.centerIn: parent
ColumnLayout {
Button {
text: "Click Me!"
}
Rectangle {
color: "blue"
implicitWidth: 50
implicitHeight: 50
NumberAnimation on rotation {
from: 0
to: 360
duration: 4000
loops: Animation.Infinite
running: true
}
}
}
}
NumberAnimation on eulerRotation.y {
from: 0
to: 360
duration: 6000
loops: Animation.Infinite
running: true
}
}
// ![item2d node]
OrbitCameraController {
origin: originNode
camera: cameraNode
}
}
}