File: RefractionPane.qml

package info (click to toggle)
qt6-quick3d 6.8.2-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 140,860 kB
  • sloc: cpp: 380,464; ansic: 36,078; xml: 252; sh: 241; makefile: 29
file content (309 lines) | stat: -rw-r--r-- 13,190 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick3D

// qmllint disable missing-property
// Disabling missing-property because the targetMaterial property
// will either be a PrincipaledMaterial or SpecularGlossyMaterial
// but the shared properties are not part of the common base class
ScrollView {
    id: rootView
    required property Material targetMaterial
    ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
    width: availableWidth
    property bool specularGlossyMode: false

    ColumnLayout {
        width: rootView.availableWidth

        MarkdownLabel {
            text: `# Refraction
The properties in this section would probably be best described as advanced
transparency. In the previous section on transparency we discussed alpha
blending, which is about blending colors together using the alpha channel of
the material's color. What makes the transparency effects in this section
different is that the goal is to handle transparency in a way that more
physically represents how light works. To achieve this blending requires that
all content that is blended with needs to be rendered to a texture in separate
pass. Using any properties on this page is as expensive as rendering all opaque
content in the scene at least twice. Once to get the background items, and again
including the items using the refractive transparency effects. The advantage of
this approach though is that we are not limited in how we can blend, but comes
with the caveat that only opaque items are visible through refracted objects.`
        }

        MarkdownLabel {
            text: `## Transmission
Transmission refers to lights ability to transmit, or pass through a surface.  Not all
light will penetrate a surface and some will still be reflected as a specular
reflection. This ability to transmit light only concerns the surface of a material, and
not its depth. Without the use of further properties in this section, a material that
has transmission alone can be assumed to be infinitely thin.
### Transmission Factor
The Transmission Factor property controls the percentage of light that is transmitted by
a materials surface.  This value is a single value between 0.0 meaning no light is
transmitted and 1.0 meaning that 100% of the light that penetrates the surface of the
material is transmitted through.

Note: If you adjust the Transmission Factor to 1.0 and you still can't see
through the models, it could be that your material is metallic. Metallic materials
cannot transmit light.`
        }
        Button {
            text: "Reset Metalness to 0.0"
            onClicked: rootView.targetMaterial.metalness = 0.0
        }

        RowLayout {
            Label {
                text: "Transmission Factor (" + rootView.targetMaterial.transmissionFactor.toFixed(2) + ")"
                Layout.fillWidth: true
            }
            Slider {
                from: 0
                to: 1
                value: rootView.targetMaterial.transmissionFactor
                onValueChanged: rootView.targetMaterial.transmissionFactor = value
            }
        }
        MarkdownLabel {
            text: `### Transmission Map
Like most other single floating point value properties, the Transmission property
also allows for the use of a single channel of a texture to map transmission values
to a mesh. And like many other textures, the final value of transmission will be
the multiplication of Transmission Factor and the value sampled from Transmission Map.
So when using a Transmission Map, it typically makes sense to set the Transmission
Factor to 1.0.
`
        }
        Button {
            text: "Reset Transmission"
            onClicked: rootView.targetMaterial.transmissionFactor = 1.0
        }

        ComboBox {
            id: transmissionChannelComboBox
            textRole: "text"
            valueRole: "value"
            implicitContentWidthPolicy: ComboBox.WidestText
            onActivated: rootView.targetMaterial.transmissionChannel = currentValue
            Component.onCompleted: currentIndex = indexOfValue(rootView.targetMaterial.transmissionChannel)
            model: [
                { value: PrincipledMaterial.R, text: "Red Channel"},
                { value: PrincipledMaterial.G, text: "Green Channel"},
                { value: PrincipledMaterial.B, text: "Blue Channel"},
                { value: PrincipledMaterial.A, text: "Alpha Channel"}
            ]
        }
        TextureSourceControl {
            defaultTexture: "maps/noise.png"
            defaultClearColor: "black"
            onTargetTextureChanged: {
                rootView.targetMaterial.transmissionMap = targetTexture
            }
        }

        VerticalSectionSeparator {}

        ColumnLayout {
            visible: !rootView.specularGlossyMode
            MarkdownLabel {
                text: `## Index of Refraction (IOR)
The Index of Refraction or refraction index refers to the physical property of
how fast light passes through a material. This number then is used to determine
how light is bent or refracted when it enters a material. Since this value is
a physical value, it's possible to plug in the same values as real life
materials as well. The default value that the PrincipledMaterial uses for all
lighting calculations is 1.5, which is very close to window glass. Below are
several other materials' IOR values that will produce different results when
used with a refractive material (especially ones with thickness).`
            }

            ComboBox {
                id: iorChannelComboBox
                textRole: "text"
                valueRole: "value"
                implicitContentWidthPolicy: ComboBox.WidestText
                onActivated: rootView.targetMaterial.indexOfRefraction = currentValue
                Component.onCompleted: currentIndex = 0
                model: [
                    { value: 1.5, text: "Custom"},
                    { value: 1.4, text: "Acrylic glass"},
                    { value: 1.0, text: "Air"},
                    { value: 1.33, text: "Water"},
                    { value: 1.76, text: "Sapphire"},
                    { value: 2.42, text: "Diamond"}
                ]
            }
            RowLayout {
                Label {
                    text: "IOR (" + iorSlider.value.toFixed(2) + ")"
                    Layout.fillWidth: true
                }
                Slider {
                    id: iorSlider
                    from: 1.0
                    to: 3.0
                    value: rootView.targetMaterial.indexOfRefraction ?? 1.5
                    onValueChanged: {
                        if (iorChannelComboBox.currentValue != value)
                            iorChannelComboBox.currentIndex = 0;
                        rootView.targetMaterial.indexOfRefraction = value
                    }
                }
            }

            VerticalSectionSeparator {}
        }

        MarkdownLabel {
            text: `## Thickness
The Thickness properties are for giving refractive materials volume.  A
transmissive material alone is considered to be infinitely thin so any
Index of Refraction values will only affect the specular and fresnel
effects of a material.  However when a transmissive material is given
volume via the thickness properties, then light passing through the
material is bent as it passes through.
### Thickness Factor
The Thickness Factor property defines the thickness of the volume beneath
the surface of the mesh.  Unlike other factors, the Thickness Factor
Property is not clipped at 1.0, but rather refers to the distance in the
coordinate space of the mesh itself.  When used in conjunction with the
Thickness Map, the Thickness Factor would be the point of maximum thickness.
`
        }

        RowLayout {
            Label {
                text: "Thickness Factor (" + rootView.targetMaterial.thicknessFactor.toFixed(2) + ")"
                Layout.fillWidth: true
            }
            Slider {
                from: 0
                to: 100.0
                value: rootView.targetMaterial.thicknessFactor
                onValueChanged: rootView.targetMaterial.thicknessFactor = value
            }
        }

        MarkdownLabel {
            text: `### Thickness Map
The Thickness Map is a single channel (greyscale) texture that defines
the thickness (or volume) of a mesh.  The values sampled from the
Thickness Map are multiplied against the value of Thickness Factor to
get the thickness of the mesh under the surface in the meshe's coordinate
space.  Thickness Maps are baked in 3D content creation tools using ray
tracers. The process of baking thickness is similar to the process for
baking ambient occlusion, but the rays are cast in the opposite direction
of the surface normal (into the mesh).  Darker values represent thin
sections, and lighter values will be thicker.  Provided is a baked thickness
map of the Monkey model. (The other models would have uniform thicknesses).`
        }

        ComboBox {
            id: thicknessChannelComboBox
            textRole: "text"
            valueRole: "value"
            implicitContentWidthPolicy: ComboBox.WidestText
            onActivated: rootView.targetMaterial.thicknessChannel = currentValue
            Component.onCompleted: currentIndex = indexOfValue(rootView.targetMaterial.thicknessChannel)
            model: [
                { value: PrincipledMaterial.R, text: "Red Channel"},
                { value: PrincipledMaterial.G, text: "Green Channel"},
                { value: PrincipledMaterial.B, text: "Blue Channel"},
                { value: PrincipledMaterial.A, text: "Alpha Channel"}
            ]
        }
        TextureSourceControl {
            defaultTexture: "maps/monkey_thickness.jpg"
            defaultClearColor: "black"
            onTargetTextureChanged: {
                rootView.targetMaterial.thicknessMap = targetTexture
            }
        }

        VerticalSectionSeparator {}

        MarkdownLabel {
            text: `## Attenuation
As light passes through a volume it will be subject to absorption and scattering.
To simulate this interaction, two properties are provided for determining this
attenuation.
### Attenuation Color
The Attenuation Color property refers to the color that white light turns into
due to the absorption when reaching the attenuation distance.
`
        }
        RowLayout {
            Label {
                text: "Red (" + rootView.targetMaterial.attenuationColor.r.toFixed(2) + ")"
                Layout.fillWidth: true
            }
            Slider {
                from: 0
                to: 1
                value: rootView.targetMaterial.attenuationColor.r
                onValueChanged: rootView.targetMaterial.attenuationColor.r = value
            }
        }
        RowLayout {
            Label {
                text: "Green  (" + rootView.targetMaterial.attenuationColor.g.toFixed(2) + ")"
                Layout.fillWidth: true
            }

            Slider {
                from: 0
                to: 1
                value: rootView.targetMaterial.attenuationColor.g
                onValueChanged: rootView.targetMaterial.attenuationColor.g = value
            }
        }
        RowLayout {
            Label {
                text: "Blue (" + rootView.targetMaterial.attenuationColor.b.toFixed(2) + ")"
                Layout.fillWidth: true
            }

            Slider {
                from: 0
                to: 1
                value: rootView.targetMaterial.attenuationColor.b
                onValueChanged: rootView.targetMaterial.attenuationColor.b = value
            }
        }
        MarkdownLabel {
            text: `### Attenuation Distance
Attenuation Distance defines material density, but does so by describing the
average distance light must travel through the medium before interacting with a
particle (absorption). In this case the distance is specified in world
coordinate space (scene space). This distance can be any positive floating point
value. This means the attenuation color will start to appear when the thickness
is greater than the attenuation distance, with the caveat that the Attenuation
Color assumes white light is passing through the model, so any other light will
create a blended result. For this demonstration the slider value is limited to
100, which should be the maximum thickness for all 3 models.`
        }

        RowLayout {
            Label {
                text: "Attenuation Distance (" + rootView.targetMaterial.attenuationDistance.toFixed(2) + ")"
                Layout.fillWidth: true
            }
            Slider {
                from: 0
                to: 100
                value: rootView.targetMaterial.attenuationDistance
                onValueChanged:  {
                    if (value != rootView.targetMaterial.attenuationDistance)
                        rootView.targetMaterial.attenuationDistance = value
                }
            }
        }
    }
}
// qmllint enable missing-property