CustomMaterial QML Type
Basiskomponente zur Erstellung von benutzerdefinierten Materialien, die zur Schattierung von Modellen verwendet werden. Mehr...
| Import Statement: | import QtQuick3D |
| Inherits: |
Eigenschaften
- alwaysDirty : bool
- destinationAlphaBlend : enumeration
(since 6.7) - destinationBlend : enumeration
- fragmentShader : url
- lineWidth : real
- shadingMode : enumeration
- sourceAlphaBlend : enumeration
(since 6.7) - sourceBlend : enumeration
- vertexShader : url
Detaillierte Beschreibung
Das benutzerdefinierte Material ermöglicht die Verwendung von benutzerdefiniertem Shader-Code für ein Material, was die Programmierbarkeit auf Grafik-Shader-Ebene ermöglicht. Es können ein Vertex-, ein Fragment- oder beide Shader bereitgestellt werden. Die Eigenschaften vertexShader und fragmentShader sind URLs, die auf Dateien verweisen, die Shader-Snippets enthalten, und funktionieren ganz ähnlich wie ShaderEffect oder Image.source. Bei benutzerdefinierten Materialien werden nur die Schemata file und qrc unterstützt. Es ist auch möglich, das Schema file wegzulassen, um auf bequeme Weise einen relativen Pfad anzugeben. Ein solcher Pfad wird relativ zum Speicherort der Komponente (der Datei .qml ) aufgelöst.
Eine Anleitung für den Einstieg in benutzerdefinierte Materialien finden Sie auf der Seite Programmierbare Materialien, Effekte, Geometrie und Texturdaten.
Einführung
Betrachten Sie die folgenden Versionen der gleichen Szene. Auf der linken Seite verwendet der Zylinder ein eingebautes, nicht programmierbares Material. Solche Materialien sind durch eine Vielzahl von Eigenschaften konfigurierbar, aber es gibt keine weitere Kontrolle über die Shader, die unter der Haube erzeugt werden. Auf der rechten Seite ist derselbe Zylinder nun mit einem CustomMaterial verknüpft, das auf die von der Anwendung bereitgestellten Vertex- und Fragment-Shader-Snippets verweist. Dies ermöglicht das Einfügen benutzerdefinierter, anwendungsspezifischer Logik in den Vertex-Shader, um die Geometrie zu transformieren und bestimmte Farbeigenschaften auf benutzerdefinierte Weise im Fragment-Shader zu bestimmen. Da es sich um ein shaded benutzerdefiniertes Material handelt, nimmt der Zylinder weiterhin normal an der Beleuchtung der Szene teil.
View3D { anchors.fill: parent PerspectiveCamera { id: camera position: Qt.vector3d(0, 0, 600) } camera: camera DirectionalLight { position: Qt.vector3d(-500, 500, -100) color: Qt.rgba(0.2, 0.2, 0.2, 1.0) ambientColor: Qt.rgba(0.1, 0.1, 0.1, 1.0) } Model { source: "#Cylinder" eulerRotation: Qt.vector3d(30, 30, 0) scale: Qt.vector3d(1.5, 1.5, 1.5) materials: [ DefaultMaterial { diffuseColor: Qt.rgba(0, 1, 0, 1) } ] } } | View3D { anchors.fill: parent PerspectiveCamera { id: camera position: Qt.vector3d(0, 0, 600) } camera: camera DirectionalLight { position: Qt.vector3d(-500, 500, -100) color: Qt.rgba(0.2, 0.2, 0.2, 1.0) ambientColor: Qt.rgba(0.1, 0.1, 0.1, 1.0) } Model { source: "#Cylinder" eulerRotation: Qt.vector3d(30, 30, 0) scale: Qt.vector3d(1.5, 1.5, 1.5) materials: [ CustomMaterial { vertexShader: "material.vert" fragmentShader: "material.frag" property real uTime property real uAmplitude: 50 NumberAnimation on uTime { from: 0; to: 100; duration: 10000; loops: -1 } } ] } } |
Nehmen wir an, dass die Shader-Snippets in material.vert und material.frag die folgenden sind:
void MAIN()
{
VERTEX.x += sin(uTime + VERTEX.y) * uAmplitude;
} | void MAIN()
{
BASE_COLOR = vec4(0.0, 1.0, 0.0, 1.0);
} |
Beachten Sie, dass uTime und uAmplitude Eigenschaften des Elements CustomMaterial sind. Sie können Werte ändern und normal animiert werden. Die Werte werden den Shadern automatisch und ohne weiteres Zutun des Entwicklers zur Verfügung gestellt.
Das Ergebnis ist ein Zylinder, der seine Scheitelpunkte animiert:

Zwei Arten von benutzerdefinierten Materialien
Es gibt zwei Haupttypen von benutzerdefinierten Materialien. Dies wird durch die Eigenschaft shadingMode festgelegt. Bei unshaded benutzerdefinierten Materialien gibt der Fragment-Shader eine einzelne vec4 Farbe aus und ignoriert Lichter, Lichtsonden und Schatten in der Szene. Bei shaded materials wird vom Shader erwartet, dass er bestimmte Funktionen implementiert und mit eingebauten Variablen arbeitet, um Licht- und Schattenbeiträge zu berücksichtigen.
Die Standardwahl ist normalerweise ein schattiertes Material, was sich im Standardwert der Eigenschaft shadingMode widerspiegelt. Dies passt zu Materialien, die Scheitelpunkte oder andere eingehende Daten aus der Geometrie transformieren oder Werte wie BASE_COLOR oder EMISSIVE_COLOR auf eine benutzerdefinierte Weise bestimmen müssen, vielleicht durch Abtasten von SCREEN_TEXTURE oder DEPTH_TEXTURE, während sie weiterhin Licht- und Schattenbeiträge aus der Szene erhalten. Darüber hinaus können solche Materialien auch die Gleichungen außer Kraft setzen und neu implementieren, die zur Berechnung der Beiträge von gerichteten, punktförmigen und anderen Lichtern verwendet werden. Die von der Anwendung bereitgestellten Shader-Snippets werden von der Qt Quick 3D-Engine unter der Haube stark verändert, um die Funktionen, wie z. B. die Beleuchtung, der Standardmaterialien bereitzustellen.
Nicht schattierte Materialien sind nützlich, wenn das Aussehen des Objekts vollständig durch den benutzerdefinierten Shader-Code bestimmt wird. Die Shader für solche Materialien erhalten nur minimale Ergänzungen durch die Engine, so dass es vollständig dem Shader überlassen bleibt, die endgültige Fragmentfarbe zu bestimmen. Dies bietet mehr Freiheit, schränkt aber auch die Möglichkeiten zur Integration mit anderen Elementen der Szene, wie z. B. Lichtern, ein.
Hinweis: Shader-Code wird immer mit GLSL im Vulkan-Stil bereitgestellt, unabhängig von der Grafik-API, die von Qt zur Laufzeit verwendet wird.
Hinweis: Der Vertex- und Fragment-Shader-Code, der vom Material bereitgestellt wird, ist kein vollständiger GLSL-Shader für sich. Vielmehr stellen sie eine Reihe von Funktionen bereit, die dann von der Engine mit weiterem Shader-Code ergänzt werden.
Freigabe von Daten an die Shader
Die dynamischen Eigenschaften des CustomMaterials können mit Hilfe von QML- und Qt Quick -Funktionen geändert und animiert werden, und die Werte werden automatisch an die Shader weitergegeben. In der Praxis ist dies ShaderEffect sehr ähnlich. Die folgende Liste zeigt, wie Eigenschaften abgebildet werden:
- bool, int, real -> bool, int, float
- QColor, color -> vec4, und die Farbe wird in den linearen, angenommenen sRGB-Raum für den in QML angegebenen Farbwert konvertiert. Die eingebauten Qt-Farben, wie
"green", sind ebenfalls im sRGB-Farbraum, und die gleiche Konvertierung wird für alle Farbeigenschaften von DefaultMaterial und PrincipledMaterial durchgeführt, so dass dieses Verhalten von CustomMaterial mit diesen übereinstimmt. Im Gegensatz zu Qt Quick ist für Qt Quick die 3D-Linearisierung unerlässlich, da in der Regel ein Tonemapping für die 3D-Szene durchgeführt wird. - QRect, QRectF, rect -> vec4
- QPoint, QPointF, point, QSize, QSizeF, size -> vec2
- QVector2D, vector2d -> vec2
- QVector3D, vector3d -> vec3
- QVector4D, vector4d -> vec4
- QMatrix4x4, matrix4x4 -> mat4
- QQuaternion, quaternion -> vec4, skalarer Wert ist
w - TextureInput -> sampler2D oder samplerCube, je nachdem, ob Texture oder CubeMapTexture in der Textur-Eigenschaft von TextureInput verwendet wird. Wenn die Eigenschaft enabled auf false gesetzt wird, wird dem Shader eine Dummy-Textur präsentiert, was bedeutet, dass der Shader zwar noch funktioniert, aber eine Textur mit undurchsichtigem schwarzem Bildinhalt abtastet. Achten Sie darauf, dass Eigenschaften für Sampler immer auf ein TextureInput Objekt verweisen müssen, nicht direkt auf ein Texture. Was die Texture Eigenschaften betrifft, so sind die Quelle, die Kacheln und die Filterung die einzigen, die bei benutzerdefinierten Materialien implizit berücksichtigt werden, während der Rest (z. B. UV-Transformationen) von den benutzerdefinierten Shadern nach eigenem Ermessen implementiert werden kann.
Hinweis: Wenn eine Uniform, auf die im Shader-Code verwiesen wird, keine entsprechende Eigenschaft hat, führt dies zu einem Shader-Kompilierungsfehler bei der Verarbeitung des Materials zur Laufzeit. Es gibt einige Ausnahmen, wie z. B. Sampler-Uniformen, die eine Dummy-Textur gebunden bekommen, wenn keine entsprechende QML-Eigenschaft vorhanden ist, aber als allgemeine Regel gilt, dass alle Uniformen und Sampler eine entsprechende Eigenschaft im CustomMaterial-Objekt deklariert haben müssen.
Unschattierte benutzerdefinierte Materialien
Im Folgenden finden Sie ein Beispiel für ein benutzerdefiniertes Material von unshaded.
CustomMaterial { // These properties are automatically exposed to the shaders property real time: 0.0 property real amplitude: 5.0 property real alpha: 1.0 property TextureInput tex: TextureInput { enabled: true texture: Texture { source: "image.png" } } shadingMode: CustomMaterial.Unshaded sourceBlend: alpha < 1.0 ? CustomMaterial.SrcAlpha : CustomMaterial.NoBlend destinationBlend: alpha < 1.0 ? CustomMaterial.OneMinusSrcAlpha : CustomMaterial.NoBlend cullMode: CustomMaterial.BackFaceCulling vertexShader: "customshader.vert" fragmentShader: "customshader.frag" }
Mit dem obigen Beispiel könnten die unshaded Vertex- und Fragment-Shader-Schnipsel wie folgt aussehen. Beachten Sie, dass die Shader keine Uniformen oder Vertex-Eingänge deklarieren müssen, da dies von Qt beim Zusammensetzen des endgültigen Shader-Codes erledigt wird.
VARYING vec3 pos;
VARYING vec2 texcoord;
void MAIN()
{
pos = VERTEX;
pos.x += sin(time * 4.0 + pos.y) * amplitude;
texcoord = UV0;
POSITION = MODELVIEWPROJECTION_MATRIX * vec4(pos, 1.0);
}VARYING vec3 pos;
VARYING vec2 texcoord;
void MAIN()
{
vec4 c = texture(tex, texcoord);
FRAGCOLOR = vec4(pos.x * 0.02, pos.y * 0.02, pos.z * 0.02, alpha) * c;
}Die folgenden speziellen, in Großbuchstaben geschriebenen Schlüsselwörter sind verfügbar:
- MAIN -> der Name des Einstiegspunktes im Vertex- oder Fragment-Shader-Snippet muss immer
MAINlauten. Die Bereitstellung dieser Funktion ist in Shader-Snippets für nicht schattierte benutzerdefinierte Materialien obligatorisch. - VARYING -> deklariert eine Ausgabe des Vertex-Shaders oder eine Eingabe für den Fragment-Shader
- POSITION -> vec4, die Ausgabe des Vertex-Shaders
- FRAGCOLOR -> vec4, die Ausgabe des Fragment-Shaders. Nur für nicht schattierte benutzerdefinierte Materialien verfügbar.
- VERTEX -> vec3, die Vertex-Position im Vertex-Shader.
- NORMAL -> vec3, die Vertexnormale im Vertexshader. Wenn das Mesh für das zugehörige Modell keine Normalen bereitstellt, ist der Wert vec3(0.0).
- UV0 -> vec2, der erste Satz von Texturkoordinaten im Vertex-Shader. Wenn das Netz des zugehörigen Modells keine Texturkoordinaten bereitstellt, ist der Wert vec2(0.0).
- UV1 -> vec2, der zweite Satz von Texturkoordinaten im Vertex-Shader. Wenn das Netz des zugehörigen Modells keinen zweiten Satz von Texturkoordinaten bereitstellt, ist der Wert vec2(0.0).
- COLOR -> vec4, die Scheitelfarbe im Vertex-Shader. Wenn das Netz für das verknüpfte Modell keine Farben pro Scheitelpunkt bereitstellt, ist der Wert vec4(1.0).
- TANGENT -> vec3, die Tangente im Vertex-Shader. Wenn das Mesh für das verknüpfte Modell keine Tangentialdaten bereitstellt, ist der Wert vec3(0.0).
- BINORMAL -> vec3, binormal im Vertex-Shader. Wenn das Netz für das zugehörige Modell keine binormalen Daten bereitstellt, ist der Wert vec3(0.0).
- JOINTS -> ivec4, Gelenkindizes im Vertex-Shader. Wenn das Netz für das verknüpfte Modell keine Joint-Indexdaten bereitstellt, ist der Wert ivec4(0).
- WEIGHTS -> vec4, Gelenkgewichte im Vertex-Shader. Wenn das Mesh für das zugehörige Modell keine Joint-Weights-Daten bereitstellt, ist der Wert vec4(0.0).
- MORPH_POSITION(n) -> vec3, die n+1teMorph-Zielposition im Vertex-Shader. Das zugehörige Modell sollte die richtigen Daten liefern.
- MORPH_NORMAL(n) -> vec3, die n+1-teMorph-Zielnormale im Vertex-Shader. Das zugehörige Modell sollte die richtigen Daten liefern.
- MORPH_TANGENT(n) -> vec3, die n+1-teMorph-Ziel-Tangente im Vertex-Shader. Das zugehörige Modell sollte die richtigen Daten liefern.
- MORPH_BINORMAL(n) -> vec3, das n+1-teMorph-Ziel binormal im Vertex-Shader. Das zugehörige Modell sollte die richtigen Daten liefern.
- MODELVIEWPROJECTION_MATRIX -> mat4, die Model-View-Projektionsmatrix. Projektionsmatrizen folgen immer den OpenGL-Konventionen, mit einer eingebrannten Transformation für die Y-Achsenrichtung und die Cliptiefe, abhängig von der zur Laufzeit verwendeten Grafik-API.
- VIEWPROJECTION_MATRIX -> mat4, die Ansichtsprojektionsmatrix
- PROJECTION_MATRIX -> mat4, die Projektionsmatrix
- INVERSE_PROJECTION_MATRIX -> mat4, die inverse Projektionsmatrix
- VIEW_MATRIX -> mat4, die Ansichtsmatrix (Kamera)
- MODEL_MATRIX -> mat4, die Modell-(Welt-)Matrix
- NORMAL_MATRIX -> mat3, die normale Matrix (die Transponierung der Inverse des oberen linken 3x3 Teil des Modells Matrix)
- BONE_TRANSFORMS -> mat4[], das Array der Knochenmatrixen des Modells
- BONE_NORMAL_TRANSFORMS -> mat3[], das Array des Modells Knochen normale Matrizen (die Transponierung der Inverse des oberen linken 3x3 Teil der einzelnen Knochenmatrizen)
- MORPH_WEIGHTS -> float[], das Array der Morph-Gewichte. Das zugehörige Modell sollte die richtigen Daten liefern. Zur Sicherheit wird QT_MORPH_MAX_COUNT auf die Größe dieses Arrays festgelegt.
- CAMERA_POSITION -> vec3, die Kameraposition im Weltraum
- CAMERA_DIRECTION -> vec3, der Richtungsvektor der Kamera
- CAMERA_PROPERTIES -> vec2, die Nah- und Fern-Clipwerte für die Kamera
- POINT_SIZE -> Float, nur im Vertex-Shader beschreibbar. Beim Rendern von Geometrie mit einer Topologie aus Punkten muss der benutzerdefinierte Vertex-Shader diesen Wert entweder auf 1,0 oder einen anderen Wert setzen, sowohl in schattierten als auch in nicht schattierten benutzerdefinierten Materialien. Siehe PrincipledMaterial::pointSize für weitere Hinweise zur Unterstützung von anderen Größen als 1.
Schattierte benutzerdefinierte Materialien
Ein shaded Material augments den Shader-Code, der von einem PrincipledMaterial generiert werden würde. Im Gegensatz zu nicht schattierten Materialien, die fast die gesamte Logik für die Vertex- und Fragment-Shader-Hauptfunktionen selbst bereitstellen, verhindern sie das Hinzufügen von generiertem Code für Beleuchtung, Schattenwurf, globale Beleuchtung usw., lassen schattierte Materialien die Shader-Generierung ganz normal ablaufen, so als wäre das CustomMaterial ein PrincipledMaterial. Von den Vertex- und Fragment-Shader-Snippets wird erwartet, dass sie optionale Funktionen bereitstellen, die dann an bestimmten Punkten aufgerufen werden und ihnen die Möglichkeit geben, die Farben und andere Werte anzupassen, die dann für die Berechnung der Beleuchtung und der endgültigen Fragmentfarbe verwendet werden.
Anstatt nur eine MAIN Funktion zu implementieren, kann der Fragment-Shader für ein schattiertes benutzerdefiniertes Material mehrere Funktionen implementieren. Alle Funktionen, einschließlich MAIN, sind optional in schattierten benutzerdefinierten Materialien zu implementieren. Ein leeres Shader-Snippet oder sogar das Fehlen der Eigenschaften vertexShader oder fragmentShader kann ebenfalls vollkommen gültig sein.
Vertex-Shader-Snippets in einem schattierten benutzerdefinierten Material
Die folgenden Funktionen können in einem Vertex-Shader-Snippet implementiert werden:
void MAIN()Wenn vorhanden, wird diese Funktion aufgerufen, um den Wert vonPOSITION, der vec4-Ausgabe des Vertex-Shaders, zu setzen und optional die Werte vonVERTEX,COLOR,NORMAL,UV0,UV1,TANGENT,BINORMAL,JOINTSundWEIGHTSzu ändern. Anders als bei nicht schattierten Materialien ist das Schreiben in diese sinnvoll, da die geänderten Werte dann im restlichen generierten Shader-Code berücksichtigt werden (während bei nicht schattierten Materialien kein zusätzlicher Shader-Code generiert wird). Wenn der benutzerdefinierte Scheitelpunkt-Shader beispielsweise die Scheitelpunkte oder die Normalen verschiebt, wird er die geänderten Werte aufVERTEXoderNORMALspeichern wollen, um anschließend korrekte Beleuchtungsberechnungen durchzuführen. Außerdem kann die Funktion in Variablen schreiben, die mitVARYINGdefiniert wurden, um interpolierte Daten an den Fragment-Shader zu übergeben. Wenn diese Funktion oder eine Neudefinition vonPOSITIONnicht vorhanden ist, wirdPOSITIONauf der Grundlage vonVERTEXundMODELVIEWPROJECTION_MATRIXberechnet, genau wie es ein PrincipledMaterial tun würde.Beispiel, bei dem sowohl auf QML-Eigenschaften, die als Uniformen dargestellt werden, als auch auf die Übergabe von Daten an den Fragment-Shader zurückgegriffen wird:
VARYING vec3 vNormal; VARYING vec3 vViewVec; void MAIN() { VERTEX.x += sin(uTime * 4.0 + VERTEX.y) * uAmplitude; vNormal = normalize(NORMAL_MATRIX * NORMAL); vViewVec = CAMERA_POSITION - (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz; POSITION = MODELVIEWPROJECTION_MATRIX * vec4(VERTEX, 1.0); }Hinweis: Im obigen Beispiel ist die Zuweisung eines Wertes an
POSITIONoptional, da die Verwendung in diesem Fall mit dem Standardverhalten identisch ist.
Hinweis: Um Daten ohne Interpolation vom Scheitelpunkt an die Fragmentstufe zu übergeben, fügen Sie das Schlüsselwort flat vor dem Typ in den VARYING -Deklarationen hinzu.
Fragment-Shader-Snippets in einem schattierten benutzerdefinierten Material
Die folgenden Funktionen können in einem Fragment-Shader-Snippet implementiert werden:
void MAIN()Wenn vorhanden, wird diese Funktion aufgerufen, um die Werte der speziellen beschreibbaren VariablenBASE_COLOR,METALNESS,ROUGHNESS,SPECULAR_AMOUNT, NORMAL, CLEARCOAT_FRESNEL_POWER, CLEARCOAT_FRESNEL_SCALE, CLEARCOAT_FRESNEL_BIAS zu setzen, CLEARCOAT_AMOUNT, CLEARCOAT_ROUGHNESS, CLEARCOAT_NORMAL, FRESNEL_BIAS, FRESNEL_SCALE, FRESNEL_POWER, IOR,TRANSMISSION_FACTOR, THICKNESS_FACTOR, ATTENUATION_COLOR, ATTENUATION_DISTANCE undOCCLUSION_AMOUNT.Ein häufiger Anwendungsfall ist die Festlegung des Wertes von
BASE_COLORauf der Grundlage der Abtastung einer Textur, sei es eine Basisfarbkarte,SCREEN_TEXTUREoder eine andere Art von Quelle. Dies kann insbesondere dann relevant und praktisch sein, wenn keine eigenen Lichtprozessorfunktionen implementiert sind. Wenn manBASE_COLOR.aauf etwas anderes als den Standardwert 1.0 setzt, kann man den endgültigen Alpha-Wert des Fragments beeinflussen. (Beachten Sie, dass dies oft auch die Aktivierung von Alpha-Blending in sourceBlend und destinationBlend erfordert)Ein weiteres Szenario ist, wenn keine benutzerdefinierte
SPECULAR_LIGHTFunktion zur Verfügung steht oder wenn eine Lichtsonde in SceneEnvironment eingestellt ist. Die Metallizität, Rauheit und andere Werte, die die Berechnung des Spiegelungsbeitrags beeinflussen, können inMAINauf die gewünschten benutzerdefinierten Werte eingestellt werden.Die Funktion kann in die folgenden speziellen Variablen schreiben. Die Werte, die in diese Variablen geschrieben werden, sind normalerweise entweder fest kodiert oder werden auf der Grundlage von QML-Eigenschaften berechnet, die auf Uniformen abgebildet werden. Die Semantik ist identisch mit PrincipledMaterial.
- vec4
BASE_COLOR- Der Basisfarb- und Materialalphawert. Entspricht built-in materials' color property. Wenn keine Lichtprozessorfunktionen implementiert sind, kann es praktisch sein, eine benutzerdefinierte Grundfarbe inMAINzu setzen, da diese dann bei den Standardbeleuchtungsberechnungen berücksichtigt wird. Der Standardwert istvec4(1.0), d. h. Weiß mit einem Alpha-Wert von 1,0. Der Alphawert wirkt sich auf den endgültigen Alphawert des Fragments aus. Der endgültige Alphawert ist die Deckkraft des Objekts (Modells) multipliziert mit der Grundfarbe Alpha. Wenn Sie den Wert direkt im Shader-Code angeben und sich nicht auf einheitliche Werte verlassen, die aus den Farbeigenschaften in QML hervorgehen, sollten Sie sich darüber im Klaren sein, dass es dem Shader obliegt, die Konvertierung von sRGB in linear vorzunehmen, falls erforderlich. Unter der Annahme vonvec3 colorundfloat alphakann dies zum Beispiel wie folgt erreicht werden:float C1 = 0.305306011; vec3 C2 = vec3(0.682171111, 0.682171111, 0.682171111); vec3 C3 = vec3(0.012522878, 0.012522878, 0.012522878); BASE_COLOR = vec4(rgb * (rgb * (rgb * C1 + C2) + C3), alpha);
- vec3
EMISSIVE_COLOR- Die Farbe der Selbstbeleuchtung. Entspricht der Emissionsfarbe der eingebauten Materialien, die durch built-in materials's emissiveFactor property und built-in materials's emissiveMap property kombiniert wird. Der Standardwert istvec3(0.0). Wenn Sie den Wert direkt im Shader-Code angeben und sich nicht auf einheitliche Werte verlassen, die aus den Farbeigenschaften in QML hervorgehen, sollten Sie sich darüber im Klaren sein, dass es dem Shader obliegt, die Konvertierung von sRGB in linear vorzunehmen, falls erforderlich. - float
IORGibt den Brechungsindex des Materials an. Ein typischer Wert und auch der Standardwert ist1.5, da dies der Wert ist, den ein PrincipledMaterial verwenden würde. - float
TRANSMISSION_FACTORLegt den Betrag der Lichtdurchlässigkeit fest. Ein typischer Wert wäre1.0und die Vorgabe ist0.0, da dies der Wert ist, den PrincipledMaterial verwenden würde. - float
THICKNESS_FACTORLegt die Stärke des durchscheinenden Materials fest. Ein typischer Wert wäre10.0und der Standardwert ist0.0, da dies der Wert ist, den PrincipledMaterial verwenden würde. - vec3
ATTENUATION_COLORLegt die Farbverschiebung des durchscheinenden Materials um die Entfernung fest. Ein typischer Wert wärevec3(1.0, 0.0, 0.0)und auch der Standardwert istvec3(1.0), da dies der Wert ist, den PrincipledMaterial verwenden würde. - float
ATTENUATION_DISTANCELegt die Abschwächung der Farbverschiebung des lichtdurchlässigen Materials in der Entfernung fest. Ein typischer Wert wäre100.0und die Vorgabe ist0.0, da dies der Wert ist, den PrincipledMaterial verwenden würde. - float
METALNESSMetalness-Wert im Bereich 0.0 - 1.0. Der Standardwert ist 0. Muss auf einen Wert ungleich Null gesetzt werden, um Wirkung zu zeigen. - float
ROUGHNESSRauhigkeitswert im Bereich 0.0 - 1.0. Der Standardwert ist 0. - float
CLEARCOAT_FRESNEL_POWERGibt die Fresnelkraft der Klarlackschicht an. Ein typischer Wert und auch der Standardwert ist5.0, da dies der Wert ist, den PrincipledMaterial verwenden würde. - float
CLEARCOAT_FRESNEL_SCALELegt die Fresnel-Skala der Klarlackschicht fest. Ein typischer Wert und auch der Standardwert ist1.0, da dies der Wert ist, den ein PrincipledMaterial verwenden würde. - float
CLEARCOAT_FRESNEL_BIASLegt die Fresnel-Bias der Klarlackschicht fest. Ein typischer Wert und auch der Standardwert ist0.0, da dies der Wert ist, den PrincipledMaterial verwenden würde. - float
CLEARCOAT_AMOUNTLegt die Menge der Klarlackschicht auf dem Material fest. Ein typischer Wert ist1.0und der Standardwert ist0.0, da dies der Wert ist, der für PrincipledMaterial verwendet wird. - float
CLEARCOAT_ROUGHNESSLegt die Rauheit der Klarlackschicht fest. Ein typischer Wert wäre1.0für eine vollständig unscharfe Klarlackschicht und auch die Voreinstellung ist0.0, da dies der Wert ist, der für PrincipledMaterial verwendet würde. - vec3
CLEARCOAT_NORMAL- Die Normalen der Klarlackschicht, die aus dem Vertex-Shader im Weltraum stammen. Während diese Eigenschaft den gleichen Anfangswert wieVAR_WORLD_NORMALhat, hat nur die Änderung des Wertes vonCLEARCOAT_NORMALeine Auswirkung auf die Normalen der Klarlackschicht. - Float
FRESNEL_POWERGibt die Fresnelleistung an. Ein typischer Wert und auch der Standardwert ist5.0, da dies der Wert ist, den PrincipledMaterial verwenden würde. - float
FRESNEL_SCALELegt die Fresnel-Skala fest. Ein typischer Wert und auch der Standardwert ist1.0, da dies der Wert ist, den PrincipledMaterial verwenden würde. - float
FRESNEL_BIASLegt den Fresnel-Bias fest. Ein typischer Wert und auch der Standardwert ist0.0, da dies der Wert ist, den PrincipledMaterial verwenden würde. - float
SPECULAR_AMOUNTSpiegelungsanteil im Bereich 0,0 - 1,0. Der Standardwert ist0.5und entspricht PrincipledMaterial::specularAmount. Muss auf einen Wert ungleich Null gesetzt werden, um Wirkung zu zeigen. - float
OCCLUSION_AMOUNTLegt den AO-Faktor fest. Ein typischer Wert und auch der Standardwert ist1.0, da dies der Wert ist, den PrincipledMaterial verwenden würde. - vec3
NORMAL- Die Normale, die vom Vertex-Shader im Weltraum kommt. Während diese Eigenschaft den gleichen Anfangswert wieVAR_WORLD_NORMALhat, hat nur die Änderung des Wertes vonNORMALeine Auswirkung auf die Beleuchtung. - vec3
TANGENT- Die Tangente, die vom Vertex-Shader im Weltraum kommt. Dieser Wert wird möglicherweise für Doppelseitigkeit angepasst. - vec3
BINORMAL- Die Binormale, die vom Vertex-Shader im Weltraum kommt. Dieser Wert wird potenziell für Doppelseitigkeit angepasst. - vec2
UV0- Der erste Satz von Texturkoordinaten aus dem Vertex-Shader. Diese Eigenschaft ist im Fragment-Shader schreibgeschützt. - vec2
UV1- Der zweite Satz von Texturkoordinaten aus dem Vertex-Shader. Diese Eigenschaft ist im Fragment-Shader schreibgeschützt.
Hinweis: Anders als bei nicht schattierten Materialien hat das Fragment
MAINfür ein schattiertes Material keine direkte Kontrolle überFRAGCOLOR. Vielmehr sind es die in den Lichtprozessorfunktionen geschriebenen WerteDIFFUSEundSPECULAR, die über die endgültige Fragmentfarbe entscheiden. Wenn keine Lichtprozessorfunktion implementiert ist, werden die entsprechenden Standard-Schattierungsberechnungen wie bei PrincipledMaterial durchgeführt, wobeiBASE_COLORund andere Werte aus der obigen Liste berücksichtigt werden.Ein Beispiel für einen einfachen, metallischen benutzerdefinierten Material-Shader könnte folgendermaßen aussehen:
void MAIN() { METALNESS = 1.0; ROUGHNESS = 0.5; FRESNEL_POWER = 5.0; }Ein weiteres Beispiel, bei dem die Grundfarbe und Alpha durch Sampling einer Textur festgelegt werden:
VARYING vec2 texcoord; void MAIN() { BASE_COLOR = texture(uColorMap, texcoord); }- vec4
void AMBIENT_LIGHT()Wenn vorhanden, wird diese Funktion einmal für jedes Fragment aufgerufen. Die Aufgabe der Funktion ist es, den gesamten Umgebungsbeitrag zu einer beschreibbaren SpezialvariablenDIFFUSEzu addieren. Sie kann natürlich auch einen anderen Wert berechnen oderDIFFUSEüberhaupt nicht berühren (um die Umgebungsbeleuchtung vollständig zu ignorieren). Wenn diese Funktion nicht vorhanden ist, wird der Umgebungslichtanteil normal berechnet, wie es eine PrincipledMaterial tun würde.Die Funktion kann in die folgenden speziellen Variablen schreiben:
- vec3
DIFFUSEAddiert die diffusen Lichtanteile pro Fragment. Die Lichtprozessorfunktionen addieren typischerweise (+=) dazu, da durch das Überschreiben des Wertes der Beitrag anderer Lichter verloren gehen würde.
Die Funktion kann die folgenden speziellen Variablen lesen, zusätzlich zu den Matrix- (z.B.
MODEL_MATRIX) und Vektor- (z.B.CAMERA_POSITION) Uniformen aus der obigen Tabelle:- vec3
TOTAL_AMBIENT_COLORDer gesamte Umgebungsbeitrag in der Szene.
Beispiel:
void AMBIENT_LIGHT() { DIFFUSE += TOTAL_AMBIENT_COLOR; }- vec3
void DIRECTIONAL_LIGHT()Wenn vorhanden, wird diese Funktion für jedes aktive Richtungslicht in der Szene für jedes Fragment aufgerufen. Die Aufgabe der Funktion ist es, den diffusen Beitrag zu einer beschreibbaren SpezialvariablenDIFFUSEhinzuzufügen. Die Funktion kann sich auch dafür entscheiden, nichts zu tun, in diesem Fall werden die diffusen Beiträge der gerichteten Lichter ignoriert. Wenn die Funktion überhaupt nicht vorhanden ist, werden die diffusen Beiträge von gerichteten Lichtern normal akkumuliert, wie es eine PrincipledMaterial tun würde.Die Funktion kann in die folgenden speziellen Variablen schreiben:
- vec3
DIFFUSEAkkumuliert die diffusen Lichtbeiträge pro Fragment.
- Die Lichtprozessorfunktionen addieren typischerweise (
+=
- dazu, da durch das Überschreiben des Wertes die Beiträge anderer Lichter verloren gehen würden.
Die Funktion kann die folgenden speziellen Variablen lesen, zusätzlich zu den Matrix- (z.B.
)MODEL_MATRIXund Vektor- (z.B.
CAMERA_POSITION) Uniformen aus der obigen Tabelle:- vec3
LIGHT_COLORDiffuse Lichtfarbe. - float
SHADOW_CONTRIBSchattenbeitrag, oder 1.0, wenn überhaupt kein Schatten vorhanden ist oder kein Schatten empfangen wird. - vec3
TO_LIGHT_DIRVektor, der auf die Lichtquelle zeigt. - vec3
NORMALDer Normalenvektor im Weltraum. - vec4
BASE_COLORDie Grundfarbe und der Materialalphawert. - float
METALNESSDer Metallanteil. - float
ROUGHNESSDer Rauhigkeitsanteil.
Beispiel:
void DIRECTIONAL_LIGHT() { DIFFUSE += LIGHT_COLOR * SHADOW_CONTRIB * vec3(max(0.0, dot(normalize(VAR_WORLD_NORMAL), TO_LIGHT_DIR))); }- vec3
void POINT_LIGHT()Wenn vorhanden, wird diese Funktion für jedes aktive Punktlicht in der Szene für jedes Fragment aufgerufen. Die Aufgabe der Funktion ist es, den diffusen Beitrag zu einer beschreibbaren speziellen VariablenDIFFUSEhinzuzufügen. Die Funktion kann auch nichts tun, in diesem Fall werden die diffusen Beiträge der Punktlichter ignoriert. Wenn die Funktion überhaupt nicht vorhanden ist, werden die diffusen Beiträge von Punktlichtern normal akkumuliert, wie es eine PrincipledMaterial tun würde.Die Funktion kann in die folgenden speziellen Variablen schreiben:
- vec3
DIFFUSEAkkumuliert die diffusen Lichtbeiträge, pro Fragment.
Die Funktion kann die folgenden speziellen Variablen lesen, zusätzlich zu den Matrix- (z.B.
)MODEL_MATRIXund Vektor- (z.B.
CAMERA_POSITION) Uniformen aus der Tabelle oben:- vec3
LIGHT_COLORDiffuse Lichtfarbe. - float
LIGHT_ATTENUATIONLichtabschwächung. - float
SHADOW_CONTRIBSchattenbeitrag oder 1.0, wenn überhaupt kein Schatten vorhanden ist oder kein Schatten empfangen wird. - vec3
TO_LIGHT_DIRVektor, der in Richtung der Lichtquelle zeigt. - vec3
NORMALDer Normalenvektor im Weltraum. - vec4
BASE_COLORDie Grundfarbe und der Materialalphawert. - float
METALNESSDer Metallanteil. - float
ROUGHNESSDer Rauhigkeitsanteil.
Beispiel:
void POINT_LIGHT() { DIFFUSE += LIGHT_COLOR * LIGHT_ATTENUATION * SHADOW_CONTRIB * vec3(max(0.0, dot(normalize(VAR_WORLD_NORMAL), TO_LIGHT_DIR))); }- vec3
void SPOT_LIGHT()Wenn vorhanden, wird diese Funktion für jedes aktive Spotlicht in der Szene für jedes Fragment aufgerufen. Die Aufgabe der Funktion ist es, den diffusen Beitrag zu einer beschreibbaren SpezialvariablenDIFFUSEhinzuzufügen. Die Funktion kann auch nichts tun, in diesem Fall werden die diffusen Beiträge der Scheinwerfer ignoriert. Wenn die Funktion nicht vorhanden ist, werden die diffusen Beiträge von Scheinwerfern normal akkumuliert, wie es eine PrincipledMaterial tun würde.Die Funktion kann in die folgenden speziellen Variablen schreiben:
- vec3
DIFFUSEAkkumuliert die diffusen Lichtbeiträge pro Fragment.
Die Funktion kann die folgenden speziellen Variablen lesen, zusätzlich zu den Matrix- (wie
)MODEL_MATRIXund Vektor-Uniformen (wie
CAMERA_POSITION) aus der obigen Tabelle:- vec3
LIGHT_COLORDiffuse Lichtfarbe. - float
LIGHT_ATTENUATIONLichtabschwächung. - float
SHADOW_CONTRIBSchattenbeitrag oder 1.0, wenn überhaupt kein Schatten vorhanden ist oder kein Schatten empfangen wird. - vec3
TO_LIGHT_DIRVektor, der auf die Lichtquelle zeigt. - float
SPOT_FACTORPunktlichtfaktor. - vec3
NORMALDer Normalenvektor im Weltraum. - vec4
BASE_COLORDie Grundfarbe und der Alphawert des Materials. - float
METALNESSDer Metallanteil. - float
ROUGHNESSDer Rauhigkeitsanteil.
Beispiel:
void SPOT_LIGHT() { DIFFUSE += LIGHT_COLOR * LIGHT_ATTENUATION * SPOT_FACTOR * SHADOW_CONTRIB * vec3(max(0.0, dot(normalize(VAR_WORLD_NORMAL), TO_LIGHT_DIR))); }- vec3
void SPECULAR_LIGHT()Wenn vorhanden, wird diese Funktion für jedes aktive Licht in der Szene für jedes Fragment aufgerufen. Die Aufgabe der Funktion ist es, den Spiegelungsbeitrag zu einer beschreibbaren speziellen VariablenSPECULARhinzuzufügen. Die Funktion kann auch nichts tun, in diesem Fall werden die spiegelnden Beiträge der Lichter ignoriert. Wenn die Funktion nicht vorhanden ist, werden die spiegelnden Beiträge von Lichtern normal akkumuliert, wie es eine PrincipledMaterial tun würde.Die Funktion kann in die folgenden speziellen Variablen schreiben:
- vec3
SPECULARAkkumuliert die spiegelnden Lichtbeiträge, pro Fragment.
- Die Lichtprozessorfunktionen addieren typischerweise (
+=
- dazu, da durch das Überschreiben des Wertes die Beiträge anderer Lichter verloren gehen würden.
Die Funktion kann zusätzlich zu den Matrix- (z.B.
)MODEL_MATRIXund Vektor- (z.B.
CAMERA_POSITION) Uniformen aus der obigen Tabelle die folgenden speziellen Variablen lesen:- vec3
LIGHT_COLORSpecular light color. - float
LIGHT_ATTENUATIONLight attenuation. Für gerichtete Lichter ist der Wert 1,0. - Für Punktlichter ist der Wert derselbe wie
LIGHT_ATTENUATION * SPOT_FACTORvonvoid SPOT_LIGHT(). - float
SHADOW_CONTRIBSchattenbeitrag oder 1.0, wenn überhaupt kein Schatten vorhanden ist oder kein Schatten empfangen wird. - vec3
FRESNEL_CONTRIBFresnel-Beitrag aus der eingebauten Fresnel-Berechnung. - vec3
TO_LIGHT_DIRVektor, der auf die Lichtquelle zeigt. - vec3
NORMALDer Normalenvektor im Weltraum. - vec4
BASE_COLORDie Grundfarbe und der Material-Alpha-Wert. - float
METALNESSDer Metallanteil. - float
ROUGHNESSDer Rauheitsanteil. - float
SPECULAR_AMOUNTDer Spiegelanteil. Dieser Wert liegt zwischen 0,0 und 1,0 und ist derselbe Wert, der in der benutzerdefinierten FunktionMAINfestgelegt wurde. Dieser Wert ist nützlich für die Berechnung von Fresnel-Beiträgen, wenn nicht der integrierte Fresnel-Beitrag vonFRESNEL_CONTRIBverwendet wird
.- vec3
void SPECULAR_LIGHT() { vec3 H = normalize(VIEW_VECTOR + TO_LIGHT_DIR); float cosAlpha = max(0.0, dot(H, normalize(NORMAL))); float shine = pow(cosAlpha, exp2(15.0 * (1.0 - ROUGHNESS) + 1.0) * 0.25); SPECULAR += shine * LIGHT_COLOR * FRESNEL_CONTRIB * SHADOW_CONTRIB * LIGHT_ATTENUATION; }void POST_PROCESS()Wenn vorhanden, wird diese Funktion am Ende der Fragment-Pipeline aufgerufen. Die Aufgabe der Funktion ist es,COLOR_SUMmit den endgültigen diffusen, spiegelnden und emittierenden Termen abzuschließen. Im Gegensatz zuFRAGCOLORfür ein nicht schattiertes Material wirdCOLOR_SUMautomatisch tongemappt, bevor es in den Framebuffer geschrieben wird. Zu Debugging-Zwecken ist es manchmal nützlich, einen Wert auszugeben, der nicht als Farbe behandelt werden soll. Um zu vermeiden, dass das Tonemapping diesen Wert verzerrt, kann es deaktiviert werden, indem die Eigenschaft tonemapMode aufTonemapModeNonegesetzt wird. Die Funktion kann in die folgenden speziellen Variablen schreiben:
- vec4
COLOR_SUMdie Ausgabe des Fragment-Shaders.
- Der Standardwert ist vec4(DIFFUSE.rgb + SPECULAR + EMISSIVE, DIFFUSE.a)
Die Funktion kann die folgenden speziellen Variablen lesen.
- vec4
DIFFUSEDer endgültige diffuse Term der Fragment-Pipeline. - vec3
SPECULARDer endgültige specular Term der Fragment-Pipeline. - vec3
EMISSIVEDer letzte emissive Term der Fragment-Pipeline. - vec2
UV0- Der erste Satz von Texturkoordinaten aus dem Vertex-Shader. - vec2
UV1- Der zweite Satz von Texturkoordinaten aus dem Vertex-Shader.
void POST_PROCESS() { float center_x = textureSize(SCREEN_TEXTURE, 0).x * 0.5; if (gl_FragCoord.x > center_x) COLOR_SUM = DIFFUSE; else COLOR_SUM = vec4(EMISSIVE, DIFFUSE.a); }- vec4
void IBL_PROBE()Wenn vorhanden, wird diese Funktion für IBL (Image-Based Lighting) aufgerufen. Die Aufgabe der Funktion ist es, sowohl die diffusen als auch die spiegelnden Beiträge von IBL zu den beschreibbaren SpezialvariablenDIFFUSEundSPECULARzu addieren. Die Funktion kann in die folgenden Spezialvariablen schreiben:
- vec3
DIFFUSEAkkumuliert die diffusen Lichtbeiträge, pro Fragment. - vec3
SPECULARAkkumuliert die spiegelnden Lichtbeiträge, pro Fragment.
Die Funktion kann die folgenden Spezialvariablen lesen.
- vec4
BASE_COLORDie Grundfarbe und der Material-Alpha-Wert. - float
AO_FACTORDer Bildschirmraum-Verdeckungsfaktor. - float
SPECULAR_AMOUNTDer spiegelnde Anteil. - float
ROUGHNESSDer endgültige Emissionsterm der Fragment-Pipeline. - vec3
NORMALDer Normalenvektor im Weltraum. - vec3
VIEW_VECTORZeigt in Richtung der Kamera. - mat3
IBL_ORIENTATIONDie Ausrichtung der Lichtsonde. Sie ergibt sich aus SceneEnvironment::probeOrientation
.- vec3
void IBL_PROBE() { vec3 smpDir = IBL_ORIENTATION * NORMAL; DIFFUSE += AO_FACTOR * BASE_COLOR.rgb * textureLod(IBL_TEXTURE, smpDir, IBL_MAXMIPMAP).rgb; }
Benutzerdefinierte Variablen zwischen Funktionen
Zusätzliche Variablen können von der MAIN-Funktion an die anderen Funktionen übergeben werden. Das Schlüsselwort SHARED_VARS kann zur Definition neuer benutzerdefinierter Variablen verwendet werden. Auf diese benutzerdefinierten Variablen kann mit SHARED.<Variablenname> zugegriffen werden.
Ein schattiertes benutzerdefiniertes Material kann zum Beispiel einen gemeinsamen Wert in der Funktion MAIN abrufen und in anderen Funktionen verwenden.
SHARED_VARS {
vec3 colorThreshold;
};
void MAIN()
{
BASE_COLOR = texture(baseColorMap, UV0);
SHARED.colorThreshold = texture(thresholdMap, UV0).rgb;
}
void DIRECTIONAL_LIGHT()
{
if (DIFFUSE >= SHARED.colorThreshold) {
DIFFUSE = SHARED.colorThreshold;
return;
}
DIFFUSE += LIGHT_COLOR * SHADOW_CONTRIB;
}Hinweis: SHARED kann in alle Funktionen ohne POST_PROCESS geschrieben werden, aber es ist sicher, es in MAIN zu schreiben und in den anderen Funktionen zu lesen.
Hinweis: Ein empfohlener Anwendungsfall, um SHARED in LIGHT-Funktionen zu schreiben, ist, es zuerst in MAIN zurückzusetzen und es dann in jeder LIGHT-Funktion zu akkumulieren.
SHARED_VARS {
float sheenIntensity;
float sheenRoughness;
vec3 sheenColor;
vec3 outSheenColor;
};
void MAIN()
{
...
vec4 tex = texture(uSheenMap, UV0);
SHARED.sheenColor = tex.rgb;
SHARED.sheenIntensity = tex.a;
SHARED.sheenRoughness = uSheenRoughness;
SHARED.outSheenColor = vec3(0.0);
}
void SPECULAR_LIGHT()
{
SHARED.outSheenColor += ...;
}
void POST_PROCESS()
{
COLOR_SUM = DIFFUSE + SPECULAR + EMISSIVE + SHARED.outSheenColor;
}Hinweis: MAIN wird vor den anderen Funktionen und POST_PROCESS nach allen anderen Funktionen aufgerufen, aber es gibt keine Garantie für eine andere Reihenfolge bei Light-Prozessoren.
Zusätzliche spezielle Schlüsselwörter
Der benutzerdefinierte Fragment-Shader-Code kann frei auf Uniformen (wie CAMERA_DIRECTION oder CAMERA_POSITION) und Variationen zugreifen, die vom benutzerdefinierten Vertex-Shader weitergegeben werden. Zusätzlich gibt es eine Reihe von eingebauten Variationen, die als spezielle Schlüsselwörter verfügbar sind. Einige davon sind optional in dem Sinne, dass ein Vertex-Shader MAIN diese selbst berechnen und weitergeben könnte, aber um doppelte Daten zu reduzieren, können sich Fragment-Shader stattdessen auch auf diese Built-ins verlassen. Diese Built-Ins sind in den Lichtprozessorfunktionen und im Fragment MAIN verfügbar.
- vec3
VAR_WORLD_NORMAL- Interpolierte Normale, transformiert durchNORMAL_MATRIX. - vec3
VAR_WORLD_TANGENT- Interpolierter Tangens transformiert durchMODEL_MATRIX. - vec3
VAR_WORLD_BINORMAL- Interpolierte Binormale transformiert nachMODEL_MATRIX - vec3
NORMAL- Im Gegensatz zuVAR_WORLD_NORMAL, der die interpolierte Normale im Ist-Zustand darstellt, wird dieser Wert potenziell für Doppelseitigkeit angepasst: Beim Rendern mit deaktiviertem Culling wird die Normale bei Bedarf invertiert. Daher wird empfohlen, für Beleuchtungs- und andere BerechnungenNORMALanstelle vonVAR_WORLD_NORMALzu verwenden, um sich mit allen Culling-Modi korrekt zu verhalten. - vec3
TANGENT- WieNORMALwird dieser Wert für Doppelseitigkeit angepasst: beim Rendern mit deaktiviertem Culling wird die Tangente bei Bedarf invertiert. - vec3
BINORMAL- WieNORMAL, wird dieser Wert potenziell für Doppelseitigkeit angepasst: Beim Rendern mit deaktiviertem Culling wird die Binormale bei Bedarf invertiert. - vec3
VAR_WORLD_POSITION- Interpolierte Weltraum-Eckpunktposition ((MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz) - vec4
VAR_COLOR- Die interpolierte Scheitelfarbe, wenn im Netz Farben angegeben sind.vec4(1.0)ansonsten. - vec3
VIEW_VECTOR- Zeigt in Richtung der Kamera. Dies ist effektiv derCAMERA_POSITION - VAR_WORLD_POSITIONVektor, normalisiert. - vec4
FRAGCOORD- Enthält die Fenster-relativen Koordinaten des aktuellen Fragments. - float
FRAMEBUFFER_Y_UP- Der Wert ist1, wenn die Y-Achse im Koordinatensystem für Framebuffer (Texturen) nach oben zeigt, was bedeutet, dass(0, 0)die untere linke Ecke ist. Der Wert ist-1, wenn die Y-Achse nach unten zeigt;(0, 0)ist dann die linke obere Ecke. Solche Unterschiede in den zugrunde liegenden Grafik-APIs betreffen die meisten benutzerdefinierten Materialien nicht. Eine bemerkenswerte Ausnahme ist das Sampling vonSCREEN_TEXTUREmit Texturkoordinaten , die nicht aufFRAGCOORDbasieren. Da die Ausrichtung vonSCREEN_TEXTUREvon Natur aus an die zugrundeliegende Grafik-API gebunden ist, kann es bei der Verwendung von Texturkoordinaten aus einem Mesh erforderlich sein, die Y-Koordinate entsprechend anzupassen.Der folgende Fragment-Shader, der für Rechteck- oder Würfel-Meshes geeignet ist, zeigt beispielsweise die opaken Objekte der Szene auf dem Modell an:
VARYING vec2 texcoord; void MAIN() { vec2 screencoord = texcoord; if (FRAMEBUFFER_Y_UP < 0.0) // effectively: if not OpenGL screencoord.y = 1.0 - screencoord.y; BASE_COLOR = texture(SCREEN_TEXTURE, screencoord); }Wenn andere Texturen als
SCREEN_TEXTUREundDEPTH_TEXTUREgesampelt werden, oder wennFRAGCOORDzur Berechnung der Texturkoordinate verwendet wird (was der typische Anwendungsfall für den Zugriff auf die Bildschirm- und Tiefentexturen wäre), ist eine solche Anpassung nicht erforderlich. - float
NDC_Y_UP- Der Wert ist1, wenn die Y-Achse im normalisierten Gerätekoordinatenraum nach oben zeigt, und-1, wenn die Y-Achse nach unten zeigt. Wenn Y nach unten zeigt, ist dies der Fall, wenn das Rendering mit Vulkan erfolgt. Die meisten Materialien müssen sich nicht darum kümmern, aber die Möglichkeit, basierend auf diesem Wert zu verzweigen, kann in bestimmten fortgeschrittenen Anwendungsfällen nützlich werden. - float
NEAR_CLIP_VALUE- Der Wert ist-1für den Fall, dass der Bereich der Clipping-Ebene bei-1beginnt und bis1reicht. Dies ist der Fall, wenn OpenGL zum Rendern verwendet wird. Bei anderen Rendering-Backends ist der Wert dieser Eigenschaft0, was bedeutet, dass der Bereich der Clipping-Ebene von0bis1reicht. Dieser Wert ist bei bestimmten Techniken nützlich, bei denen dieDEPTH_TEXTUREDer folgende Fragment-Shader demonstriert beispielsweise eine Technik zur Rekonstruktion der Position eines Wertes aus dem Tiefenpuffer, um die Entfernung von der aktuellen gerenderten Position zu bestimmen. Bei Verwendung in Kombination mit
INVERSE_PROJECTION_MATRIXmuss der Tiefenwert in normalisierten Gerätekoordinaten angegeben werden, daher ist es wichtig, dass der Tiefenwertbereich dies widerspiegelt. WennNEAR_CLIP_VALUE-1ist, wird der Tiefenwert so skaliert, dass er zwischen-1und1liegt.void MAIN() { vec2 screen_uv = FRAGCOORD.xy / vec2(textureSize(SCREEN_TEXTURE, 0)); float depth = texture(DEPTH_TEXTURE, screen_uv).r; if (NEAR_CLIP_VALUE < 0.0) // effectively: if opengl depth = depth * 2.0 - 1.0; vec4 unproject = INVERSE_PROJECTION_MATRIX * vec4(screen_uv, depth, 1.0); depth = (unproject.xyz / unproject.w).z; float viewVectorZ = (VIEW_MATRIX * vec4(VAR_WORLD_POSITION, 1.0)).z; depth = viewVectorZ - depth; BASE_COLOR = vec4(depth, depth, depth, 1.0); } - float
IBL_EXPOSE- Die von der Lichtsonde abgegebene Lichtmenge. Sie stammt von SceneEnvironment::probeExposure.DIFFUSE += AO_FACTOR * IBL_EXPOSE * BASE_COLOR.rgb * textureLod(IBL_TEXTURE, NORMAL, IBL_MAXMIPMAP).rgb;
- float
IBL_HORIZON- Der horizontale Cut-Off-Wert der Reflexionen aus der unteren Hälfte der Umgebung. Dieser Wert stammt von Horizon Cut-Off, wird aber auf [-1, 0) umgerechnet.vec3 diffuse += AO_FACTOR * IBL_EXPOSE * BASE_COLOR.rgb * textureLod(IBL_TEXTURE, NORMAL, IBL_MAXMIPMAP).rgb; if (IBL_HORIZON > -1.0) { float ctr = 0.5 + 0.5 * IBL_HORIZON; float vertWt = smoothstep(ctr * 0.25, ctr + 0.25, NORMAL.y); float wtScaled = mix(1.0, vertWt, IBL_HORIZON + 1.0); diffuse *= wtScaled; } - float
IBL_MAXMIPMAP- Der maximale Mipmap-Pegel von IBL_TEXTURE.
Instanzierung
Beim instanzierten Rendering sind einige der oben genannten Schlüsselwörter nicht anwendbar. Die folgenden Schlüsselwörter sind nur bei Instanzierung verfügbar:
INSTANCE_MODEL_MATRIX-> mat4, Ersatz fürMODEL_MATRIX, einschließlich der Instanztransformation.INSTANCE_MODELVIEWPROJECTION_MATRIX-> mat4, Ersatz fürMODELVIEWPROJECTION_MATRIX, einschließlich der Instanztransformation.INSTANCE_COLOR-> vec4, die Instanzfarbe: zu kombinieren mitCOLOR.INSTANCE_DATA-> vec4, Instanz benutzerdefinierte Daten.INSTANCE_INDEX-> int, die Instanznummer und der Index in der Instanztabelle.
Bildschirm, Tiefe und andere Texturen
Die Rendering-Pipeline kann den benutzerdefinierten Material-Shadern eine Reihe von Texturen mit Inhalten aus speziellen Render-Passes zur Verfügung stellen. Dies gilt sowohl für schattierte als auch für nicht schattierte benutzerdefinierte Materialien.
Beispielsweise kann ein Shader auf eine Tiefentextur zugreifen wollen, die den Inhalt des Tiefenpuffers für die undurchsichtigen Objekte in der Szene enthält. Dies wird durch Sampling DEPTH_TEXTURE erreicht. Eine solche Textur wird normalerweise nicht erzeugt, es sei denn, es besteht ein echter Bedarf dafür. Daher dient das Vorhandensein der folgenden Schlüsselwörter im Vertex- oder Fragment-Shader auch als Umschalter für die - potenziell teuren - Durchläufe zur Erzeugung der fraglichen Textur. (Natürlich kann es sein, dass einige davon aufgrund anderer Einstellungen bereits aktiviert sind, wie z. B. die Ambient-Occlusion-Parameter in SceneEnvironment oder aufgrund eines Post-Processing-Effekts, der sich auf die Tiefen-Textur stützt; in diesem Fall werden die fraglichen Texturen unabhängig vom benutzerdefinierten Material generiert, so dass das Sampling dieser speziellen Texturen im Material keine zusätzlichen Kosten verursacht, abgesehen vom Texturzugriff selbst)
SCREEN_TEXTURE- Wenn vorhanden, wird eine Textur (sampler2Dodersampler2DArray) mit dem Farbpuffer aus einem Rendering-Durchgang, der den Inhalt der Szene enthält, mit Ausnahme aller transparenten Materialien oder aller Materialien, die ebenfalls SCREEN_TEXTURE verwenden, dem Shader unter diesem Namen zur Verfügung gestellt. Die Textur kann für Techniken verwendet werden, die den Inhalt des Framebuffers benötigen, in den sie gerendert werden. Die SCREEN_TEXTURE-Textur verwendet denselben Clear-Modus wie die View3D. Die Größe dieser Texturen entspricht der Größe der View3D in Pixeln. Ein Fragment-Shader könnte zum Beispiel Folgendes enthalten:vec2 uv = FRAGCOORD.xy / vec2(textureSize(SCREEN_TEXTURE, 0)); vec2 displace = vec2(0.1); vec4 c = texture(SCREEN_TEXTURE, uv + displace);
Beachten Sie, dass die Verwendung von
SCREEN_TEXTUREeine angemessene, bewusste Gestaltung der Szene erfordert. Objekte, die solche Materialien verwenden, müssen sorgfältig positioniert werden, normalerweise über allen anderen Objekten, die in der Textur sichtbar sein sollen. Objekte, die in irgendeiner Form Semitransparenz verwenden, sind nie Teil vonSCREEN_TEXTURE. Oft wirdSCREEN_TEXTUREin Kombination mitBASE_COLORinMAINverwendet. Der folgende benutzerdefinierte Fragment-Shader wendet zum Beispiel einen Prägeeffekt an, wobei Fragmente, die nicht von undurchsichtigen Objekten berührt werden, transparent bleiben.Dabei wird davon ausgegangen, dass das Objekt mit dem Material im Vordergrund platziert ist und die Überblendung aktiviert ist.
void MAIN() { vec2 size = vec2(textureSize(SCREEN_TEXTURE, 0)); vec2 uv = FRAGCOORD.xy / size; // basic emboss effect vec2 d = vec2(1.0 / size.x, 1.0 / size.y); vec4 diff = texture(SCREEN_TEXTURE, uv + d) - texture(SCREEN_TEXTURE, uv - d); float c = (diff.x + diff.y + diff.z) + 0.5; float alpha = texture(SCREEN_TEXTURE, uv).a; BASE_COLOR = vec4(vec3(c), alpha); }Beim Multiview-Rendering ist
.SCREEN_TEXTUREeinsampler2DArrayVerwenden Sie
VIEW_INDEX, um die zu verwendende Ebene auszuwählen. Für VR/AR-Anwendungen, die beide Arten des Renderings unterstützen möchten, ist der portable Ansatz der folgende:#if QSHADER_VIEW_COUNT >= 2 vec4 c = texture(SCREEN_TEXTURE, vec3(uv, VIEW_INDEX)); #else vec4 c = texture(SCREEN_TEXTURE, uv); #endifSCREEN_MIP_TEXTURE- Identisch mitSCREEN_TEXTUREin den meisten Punkten, mit dem Unterschied, dass diese Textur Mipmaps generiert hat. Dies kann je nach Bildschirmgröße und aufgrund der Tatsache, dass die Mipmaps jedes Mal, wenn die Szene gerendert wird, generiert werden müssen, ein teures Leistungsmerkmal sein. Verwenden Sie daher lieber immerSCREEN_TEXTURE, es sei denn, das benutzerdefinierte Material implementiert eine Technik, die auf die Mip-Levels der Textur angewiesen ist (z. B. die Verwendung vontextureLodim Shader).DEPTH_TEXTURE- Wenn vorhanden, wird eine Textur (sampler2Dodersampler2DArray) mit dem (nicht linearisierten) Tiefenpufferinhalt dem Shader unter diesem Namen angezeigt. Es werden nur undurchsichtige Objekte einbezogen. Ein Fragment-Shader könnte z. B. Folgendes enthalten:ivec2 dtSize = textureSize(DEPTH_TEXTURE, 0); vec2 dtUV = (FRAGCOORD.xy) / vec2(dtSize); vec4 depthSample = texture(DEPTH_TEXTURE, dtUV); float zNear = CAMERA_PROPERTIES.x; float zFar = CAMERA_PROPERTIES.y; float zRange = zFar - zNear; float z_n = 2.0 * depthSample.r - 1.0; float d = 2.0 * zNear * zFar / (zFar + zNear - z_n * zRange); d /= zFar;
Beim Multiview-Rendering ist
.DEPTH_TEXTUREeinsampler2DArrayVerwenden Sie
VIEW_INDEX, um die zu verwendende Ebene auszuwählen. Für VR/AR-Anwendungen, die beide Arten von Rendering unterstützen möchten, ist der portable Ansatz der folgende:#if QSHADER_VIEW_COUNT >= 2 vec4 depthSample = texture(DEPTH_TEXTURE, vec3(uv, VIEW_INDEX)); #else vec4 depthSample = texture(DEPTH_TEXTURE, uv); #endif-
AO_TEXTURE- Wenn vorhanden und Screen Space Ambient Occlusion aktiviert ist (d.h. wenn die AO-Stärke und der Abstand beide ungleich Null sind) in SceneEnvironment, wird die SSAO-Textur (sampler2Dodersampler2DArray) dem Shader unter diesem Namen ausgesetzt. Die Abtastung dieser Textur kann bei nicht schattierten Materialien nützlich sein. Bei schattierten Materialien ist die Unterstützung von Ambient Occlusion eingebaut. Dies bedeutet, dass der Faktor der Umgebungsokklusion automatisch berücksichtigt wird. In einem Fragment-Shader für ein nicht schattiertes Material könnte man Folgendes schreiben, um das Gleiche zu erreichen:ivec2 aoSize = textureSize(AO_TEXTURE, 0); vec2 aoUV = (FRAGCOORD.xy) / vec2(aoSize); float aoFactor = texture(AO_TEXTURE, aoUV).x;
Beim Multiview-Rendering ist
AO_TEXTUREeinesampler2DArray. Verwenden SieVIEW_INDEX, um die zu verwendende Ebene auszuwählen. Für VR/AR-Anwendungen, die beide Arten von Rendering unterstützen wollen, ist der portable Ansatz der folgende:#if QSHADER_VIEW_COUNT >= 2 ivec2 aoSize = textureSize(AO_TEXTURE, 0).xy; vec2 aoUV = (FRAGCOORD.xy) / vec2(aoSize); float aoFactor = texture(AO_TEXTURE, vec3(aoUV, VIEW_INDEX)).x; #else ivec2 aoSize = textureSize(AO_TEXTURE, 0); vec2 aoUV = (FRAGCOORD.xy) / vec2(aoSize); float aoFactor = texture(AO_TEXTURE, aoUV).x; #endif IBL_TEXTURE- Sie ermöglicht keinen speziellen Rendering-Pass, kann aber verwendet werden, wenn das Material Material::lightProbe hat oder das Modell im Bereich von SceneEnvironment::lightProbe liegt.void IBL_PROBE() { DIFFUSE += AO_FACTOR * BASE_COLOR.rgb * textureLod(IBL_TEXTURE, NORMAL, IBL_MAXMIPMAP).rgb; }VIEW_INDEX- Wenn sie im benutzerdefinierten Shader-Code verwendet wird, ist dies eine (nicht interpolierte) uint-Variable. Wenn Multiview-Rendering nicht verwendet wird, ist der Wert immer 0. Bei Multiview-Rendering ist der Wert der aktuelle View-Index (z. B. gl_ViewIndex). Nützlich vor allem in Kombination mitDEPTH_TEXTUREund ähnlichem, wenn Multiview-Rendering aktiviert ist.
Siehe auch SceneEnvironment::tonemapMode, Verwendung bildbasierter Beleuchtung, Qt Quick 3D - Beispiel für benutzerdefinierte Shader, Qt Quick 3D - Beispiel für benutzerdefinierte Materialien und Programmierbare Materialien, Effekte, Geometrie und Texturdaten.
Eigenschaft Dokumentation
alwaysDirty : bool |
Gibt an, dass der Materialstatus immer schmutzig ist, was bedeutet, dass das Material jedes Mal, wenn es von QtQuick3D verwendet wird, aufgefrischt werden muss.
destinationAlphaBlend : enumeration |
Gibt den Ziel-Alphaüberblendungsfaktor an. Der Standardwert ist CustomMaterial.NoBlend. Dieser Wert wird nur aktiv verwendet, wenn sourceBlend und destinationBlend auf einen anderen Wert als den Standardwert gesetzt sind.
| Konstante | Wert |
|---|---|
CustomMaterial.NoBlend | |
CustomMaterial.Zero | |
CustomMaterial.One | |
CustomMaterial.SrcColor | |
CustomMaterial.OneMinusSrcColor | |
CustomMaterial.DstColor | |
CustomMaterial.OneMinusDstColor | |
CustomMaterial.SrcAlpha | |
CustomMaterial.OneMinusSrcAlpha | |
CustomMaterial.DstAlpha | |
CustomMaterial.OneMinusDstAlpha | |
CustomMaterial.ConstantColor | |
CustomMaterial.OneMinusConstantColor | |
CustomMaterial.ConstantAlpha | |
CustomMaterial.OneMinusConstantAlpha | |
CustomMaterial.SrcAlphaSaturate |
Hinweis: Aus Gründen der Abwärtskompatibilität wird, wenn der Standardwert beibehalten wird, der gleiche Wert wie destinationBlend zugewiesen, wenn sourceBlend und destinationBlend auf Nicht-Standardwerte gesetzt sind.
Diese Eigenschaft wurde in Qt 6.7 eingeführt.
Siehe auch destinationBlend.
destinationBlend : enumeration |
Gibt den Zielüberblendungsfaktor an. Der Standardwert ist CustomMaterial.NoBlend.
| Konstante | Wert |
|---|---|
CustomMaterial.NoBlend | |
CustomMaterial.Zero | |
CustomMaterial.One | |
CustomMaterial.SrcColor | |
CustomMaterial.OneMinusSrcColor | |
CustomMaterial.DstColor | |
CustomMaterial.OneMinusDstColor | |
CustomMaterial.SrcAlpha | |
CustomMaterial.OneMinusSrcAlpha | |
CustomMaterial.DstAlpha | |
CustomMaterial.OneMinusDstAlpha | |
CustomMaterial.ConstantColor | |
CustomMaterial.OneMinusConstantColor | |
CustomMaterial.ConstantAlpha | |
CustomMaterial.OneMinusConstantAlpha | |
CustomMaterial.SrcAlphaSaturate |
Hinweis: Sowohl sourceBlend als auch destinationBlend müssen auf einen anderen Wert als den Standardwert gesetzt werden, bevor die Überblendung aktiviert wird.
Siehe auch sourceBlend.
fragmentShader : url |
Gibt die Datei mit dem Ausschnitt des benutzerdefinierten Fragment-Shader-Codes an.
Der Wert ist eine URL und muss entweder eine lokale Datei sein oder das qrc-Schema verwenden, um auf Dateien zuzugreifen, die über das Qt-Ressourcensystem eingebettet sind. Relative Dateipfade (ohne Schema) werden ebenfalls akzeptiert, in diesem Fall wird die Datei als relativ zur Komponente (der .qml Datei) behandelt.
Warnung: Shader-Snippets werden als vertrauenswürdiger Inhalt angesehen. Anwendungsentwicklern wird empfohlen, die potenziellen Auswirkungen sorgfältig abzuwägen, bevor sie das Laden von benutzerdefinierten Inhalten erlauben, die nicht Teil der Anwendung sind.
Siehe auch vertexShader.
lineWidth : real |
Diese Eigenschaft bestimmt die Breite der gerenderten Linien, wenn die Geometrie einen primitiven Typ von Linien oder Linienstreifen verwendet. Der Standardwert ist 1.0. Diese Eigenschaft ist nicht relevant, wenn andere Geometrietypen gerendert werden, z. B. Dreiecksnetze.
Warnung: Andere Linienbreiten als 1 werden je nach der zugrunde liegenden Grafik-API zur Laufzeit möglicherweise nicht unterstützt. Wenn dies der Fall ist, wird die Anforderung, die Breite zu ändern, ignoriert. Es ist zum Beispiel nicht zu erwarten, dass die folgenden Programme breite Linien unterstützen: Direct3D, Metal, OpenGL mit Kernprofilkontexten.
Hinweis: Im Gegensatz zur Linienbreite, deren Wert Teil des Grafikpipeline-Objekts ist, wird die Punktgröße für Geometrien mit einer Topologie aus Punkten durch den Vertex-Shader gesteuert (sofern unterstützt) und hat daher keine entsprechende QML-Eigenschaft.
shadingMode : enumeration |
Gibt den Typ des Materials an. Der Standardwert ist Shaded.
| Konstante | Wert |
|---|---|
CustomMaterial.Unshaded | |
CustomMaterial.Shaded |
sourceAlphaBlend : enumeration |
Gibt den Quell-Alpha-Überblendfaktor an. Der Standardwert ist CustomMaterial.NoBlend. Dieser Wert wird nur aktiv verwendet, wenn sourceBlend und destinationBlend auf einen anderen Wert als den Standardwert eingestellt sind.
| Konstante | Wert |
|---|---|
CustomMaterial.NoBlend | |
CustomMaterial.Zero | |
CustomMaterial.One | |
CustomMaterial.SrcColor | |
CustomMaterial.OneMinusSrcColor | |
CustomMaterial.DstColor | |
CustomMaterial.OneMinusDstColor | |
CustomMaterial.SrcAlpha | |
CustomMaterial.OneMinusSrcAlpha | |
CustomMaterial.DstAlpha | |
CustomMaterial.OneMinusDstAlpha | |
CustomMaterial.ConstantColor | |
CustomMaterial.OneMinusConstantColor | |
CustomMaterial.ConstantAlpha | |
CustomMaterial.OneMinusConstantAlpha | |
CustomMaterial.SrcAlphaSaturate |
Hinweis: Aus Gründen der Abwärtskompatibilität wird diesem Wert, wenn er auf seinem Standardwert belassen wird, der gleiche Wert wie sourceBlend zugewiesen, wenn sourceBlend und destinationBlend auf Nicht-Standardwerte gesetzt sind.
Diese Eigenschaft wurde in Qt 6.7 eingeführt.
Siehe auch sourceBlend.
sourceBlend : enumeration |
Legt den Überblendfaktor der Quelle fest. Der Standardwert ist CustomMaterial.NoBlend.
| Konstante | Wert |
|---|---|
CustomMaterial.NoBlend | |
CustomMaterial.Zero | |
CustomMaterial.One | |
CustomMaterial.SrcColor | |
CustomMaterial.OneMinusSrcColor | |
CustomMaterial.DstColor | |
CustomMaterial.OneMinusDstColor | |
CustomMaterial.SrcAlpha | |
CustomMaterial.OneMinusSrcAlpha | |
CustomMaterial.DstAlpha | |
CustomMaterial.OneMinusDstAlpha | |
CustomMaterial.ConstantColor | |
CustomMaterial.OneMinusConstantColor | |
CustomMaterial.ConstantAlpha | |
CustomMaterial.OneMinusConstantAlpha | |
CustomMaterial.SrcAlphaSaturate |
Hinweis: Sowohl sourceBlend als auch destinationBlend müssen auf einen anderen Wert als den Standardwert gesetzt werden, bevor die Überblendung aktiviert wird.
Siehe auch destinationBlend.
vertexShader : url |
Gibt die Datei mit dem Ausschnitt des benutzerdefinierten Vertex-Shader-Codes an.
Der Wert ist eine URL und muss entweder eine lokale Datei sein oder das qrc-Schema verwenden, um auf Dateien zuzugreifen, die über das Qt-Ressourcensystem eingebettet sind. Relative Dateipfade (ohne Schema) werden ebenfalls akzeptiert, in diesem Fall wird die Datei als relativ zur Komponente (der .qml Datei) behandelt.
Warnung: Shader-Snippets werden als vertrauenswürdiger Inhalt angesehen. Anwendungsentwicklern wird empfohlen, die potenziellen Auswirkungen sorgfältig abzuwägen, bevor sie das Laden von benutzerdefinierten Inhalten erlauben, die nicht Teil der Anwendung sind.
Siehe auch fragmentShader.
© 2025 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.