CustomMaterial QML Type
Composant de base pour la création de matériaux personnalisés utilisés pour ombrer les modèles. Plus d'informations...
| Import Statement: | import QtQuick3D |
| Inherits: |
Propriétés
- alwaysDirty : bool
- destinationAlphaBlend : enumeration
(since 6.7) - destinationBlend : enumeration
- fragmentShader : url
- lineWidth : real
- shadingMode : enumeration
- sourceAlphaBlend : enumeration
(since 6.7) - sourceBlend : enumeration
- vertexShader : url
Description détaillée
Le matériau personnalisé permet d'utiliser un code de nuanceur personnalisé pour un matériau, ce qui permet la programmabilité au niveau du nuanceur graphique. Un vertex, un fragment ou les deux shaders peuvent être fournis. Les propriétés vertexShader et fragmentShader sont des URL qui renvoient à des fichiers contenant des extraits de shaders et fonctionnent de manière très similaire à ShaderEffect ou Image.source. Seuls les schémas file et qrc sont pris en charge par les matériaux personnalisés. Il est également possible d'omettre le schéma file, ce qui permet de spécifier un chemin relatif de manière pratique. Ce chemin est résolu par rapport à l'emplacement du composant (le fichier .qml ).
Pour un guide de démarrage sur les matériaux personnalisés, voir la page Matériaux programmables, effets, géométrie et données de texture.
Introduction
Considérons les versions suivantes de la même scène. À gauche, le cylindre utilise un matériau intégré non programmable. Ces matériaux sont configurables à l'aide d'un large éventail de propriétés, mais il n'y a pas de contrôle supplémentaire sur les shaders générés sous le capot. À droite, le même cylindre est désormais associé à un CustomMaterial qui fait référence à des extraits de nuanceurs de sommets et de fragments fournis par l'application. Cela permet d'insérer une logique personnalisée et spécifique à l'application dans le nuanceur de sommets afin de transformer la géométrie et de déterminer certaines propriétés de couleur d'une manière personnalisée dans le nuanceur de fragments. Comme il s'agit d'un matériau personnalisé shaded, le cylindre participe toujours normalement à l'éclairage de la scène.
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 } } ] } } |
Supposons que les extraits de shaders dans material.vert et material.frag soient les suivants :
void MAIN()
{
VERTEX.x += sin(uTime + VERTEX.y) * uAmplitude;
} | void MAIN()
{
BASE_COLOR = vec4(0.0, 1.0, 0.0, 1.0);
} |
Remarquez que uTime et uAmplitude sont des propriétés de l'élément CustomMaterial. Ils peuvent changer de valeur et être animés normalement, les valeurs seront exposées aux shaders automatiquement sans autre action de la part du développeur.
Le résultat est un cylindre qui anime ses sommets :

Deux types de matériaux personnalisés
Il existe deux types principaux de matériaux personnalisés. Ceci est spécifié par la propriété shadingMode. Dans les matériaux personnalisés unshaded, le nuanceur de fragment produit une seule couleur vec4, ignorant les lumières, les sondes lumineuses et les ombres de la scène. Dans les matériaux shaded, le nuanceur est censé mettre en œuvre certaines fonctions et travailler avec des variables intégrées pour tenir compte de l'éclairage et de la contribution des ombres.
Le choix par défaut est généralement un matériau ombré, ce qui se reflète dans la valeur par défaut de la propriété shadingMode. Cela convient aux matériaux qui doivent transformer les sommets ou d'autres données provenant de la géométrie, ou déterminer des valeurs telles que BASE_COLOR ou EMISSIVE_COLOR d'une manière personnalisée, par exemple en échantillonnant SCREEN_TEXTURE ou DEPTH_TEXTURE, tout en continuant à recevoir les contributions de la lumière et de l'ombre de la scène. En outre, ces matériaux peuvent également remplacer et réimplémenter les équations utilisées pour calculer les contributions des lumières directionnelles, ponctuelles et autres. Les snippets de shaders fournis par l'application sont fortement modifiés par le moteur 3D de Qt Quick, afin de fournir les fonctionnalités, telles que l'éclairage, dont disposent les matériaux standard.
Les matériaux non nuancés sont utiles lorsque l'apparence de l'objet est entièrement déterminée par le code de nuanceur personnalisé. Les shaders de ces matériaux ne reçoivent qu'un minimum d'ajouts de la part du moteur, et c'est donc au shader de déterminer la couleur finale du fragment. Cela donne plus de liberté, mais limite également les possibilités d'intégration avec d'autres éléments de la scène, tels que les lumières.
Remarque : le code des shaders est toujours fourni en utilisant le GLSL de style Vulkan, quelle que soit l'API graphique utilisée par Qt au moment de l'exécution.
Remarque : le code de nuanceur de sommets et de fragments fourni par le matériel n'est pas un nuanceur GLSL complet en soi. Ils fournissent plutôt un ensemble de fonctions, qui sont ensuite modifiées par le moteur avec d'autres codes de shaders.
Exposition des données aux nuanceurs
Les propriétés dynamiques du CustomMaterial peuvent être modifiées et animées à l'aide des fonctions QML et Qt Quick, et les valeurs sont automatiquement exposées aux shaders. Dans la pratique, cela est très similaire à ShaderEffect. La liste suivante montre comment les propriétés sont mises en correspondance :
- bool, int, real -> bool, int, float
- QColor color -> vec4, et la couleur est convertie en linéaire, en supposant l'espace sRGB pour la valeur de couleur spécifiée dans QML. Les couleurs Qt XML intégrées, telles que , sont également dans l'espace sRGB, et la même conversion est effectuée pour toutes les propriétés de couleur de DefaultMaterial et , de sorte que le comportement de CustomMaterial correspond à ces propriétés. Contrairement à , pour la linéarisation 3D est essentielle car il y aura typiquement un tonemapping effectué sur la scène 3D.
"green"PrincipledMaterial Qt Quick Qt Quick - 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, la valeur scalaire est
w - TextureInput -> sampler2D ou samplerCube, selon que Texture ou CubeMapTexture est utilisé dans la propriété de texture de TextureInput. Définir la propriété enabled à false conduit à exposer une texture factice au shader, ce qui signifie que les shaders sont toujours fonctionnels mais échantillonneront une texture avec un contenu d'image noir opaque. Faites attention au fait que les propriétés des échantillonneurs doivent toujours faire référence à un objet TextureInput, et non à un objet Texture directement. En ce qui concerne les propriétés de Texture, les propriétés liées à la source, au tuilage et au filtrage sont les seules qui sont prises en compte implicitement avec les matériaux personnalisés, le reste (comme les transformations UV) étant à la charge des shaders personnalisés qui doivent les mettre en œuvre comme ils l'entendent.
Note : Lorsqu'un uniforme référencé dans le code du shader n'a pas de propriété correspondante, cela provoquera une erreur de compilation du shader lors du traitement du matériau au moment de l'exécution. Il existe quelques exceptions à cette règle, comme les uniformes d'échantillonneurs, qui obtiennent une texture fictive lorsqu'aucune propriété QML correspondante n'est présente, mais en règle générale, tous les uniformes et échantillonneurs doivent avoir une propriété correspondante déclarée dans l'objet CustomMaterial.
Matériaux personnalisés non nuancés
Voici un exemple de matériau personnalisé 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" }
Avec l'exemple ci-dessus, les snippets de vertex et de fragment shaders de unshaded pourraient ressembler à ce qui suit. Notez que les shaders ne déclarent pas, et ne doivent pas déclarer, les uniformes ou les entrées de vertex, car Qt s'en charge lors de l'assemblage du code final du shader.
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;
}Les mots-clés spéciaux suivants, en majuscules, sont disponibles :
- MAIN -> le nom du point d'entrée dans l'extrait de nuanceur de sommets ou de fragments doit toujours être
MAIN. Cette fonction est obligatoire dans les extraits de shaders pour les matériaux personnalisés non ombrés. - VARYING -> déclare une sortie du vertex shader ou une entrée du fragment shader
- POSITION -> vec4, la sortie du nuanceur de sommets
- FRAGCOLOR -> vec4, la sortie du nuanceur de fragments. Disponible uniquement pour les matériaux personnalisés non ombrés.
- VERTEX -> vec3, la position du vertex dans le nuanceur de vertex.
- NORMAL -> vec3, la normale du sommet dans le vertex shader. Lorsque le maillage du modèle associé ne fournit pas de normales, la valeur est vec3(0.0).
- UV0 -> vec2, le premier ensemble de coordonnées de texture dans le vertex shader. Lorsque le maillage du modèle associé ne fournit pas de coordonnées de texture, la valeur est vec2(0.0).
- UV1 -> vec2, le deuxième ensemble de coordonnées de texture dans le nuanceur de sommets. Lorsque le maillage du modèle associé ne fournit pas de second jeu de coordonnées de texture, la valeur est vec2(0.0).
- COLOR -> vec4, la couleur du vertex dans le vertex shader. Lorsque le maillage du modèle associé ne fournit pas de couleurs par sommet, la valeur est vec4(1.0).
- TANGENT -> vec3, tangente dans le nuanceur de sommets. Lorsque le maillage du modèle associé ne fournit pas de données tangentes, la valeur est vec3(0.0).
- BINORMAL -> vec3, binormal dans le vertex shader. Lorsque le maillage du modèle associé ne fournit pas de données binormales, la valeur est vec3(0.0).
- JOINTS -> ivec4, index des joints dans le nuanceur de sommets. Lorsque le maillage du modèle associé ne fournit pas de données d'indexation des joints, la valeur est ivec4(0).
- WEIGHTS -> vec4, poids des articulations dans le vertex shader. Lorsque le maillage du modèle associé ne fournit pas de données sur les poids des articulations, la valeur est vec4(0.0).
- MORPH_POSITION(n) -> vec3, la n+1èmeposition de la cible morph dans le vertex shader. Le modèle associé doit fournir les données appropriées.
- MORPH_NORMAL(n) -> vec3, la normale du n+1èmemorph target dans le vertex shader. Le modèle associé doit fournir les données appropriées.
- MORPH_TANGENT(n) -> vec3, la n+1èmemorph target tangent dans le vertex shader. Le modèle associé doit fournir les données appropriées.
- MORPH_BINORMAL(n) -> vec3, le n+1èmemorph target binormal dans le vertex shader. Le modèle associé doit fournir les données appropriées.
- MODELVIEWPROJECTION_MATRIX -> mat4, la matrice de projection modèle-vue. Les matrices de projection suivent toujours les conventions OpenGL, avec une transformation intégrée pour la direction de l'axe Y et la profondeur du clip, en fonction de l'API graphique utilisée au moment de l'exécution.
- VIEWPROJECTION_MATRIX -> mat4, la matrice de projection de la vue
- PROJECTION_MATRIX -> mat4, la matrice de projection
- INVERSE_PROJECTION_MATRIX -> mat4, la matrice de projection inverse
- VIEW_MATRIX -> mat4, matrice de vue (caméra)
- MODEL_MATRIX -> mat4, matrice du modèle (monde)
- NORMAL_MATRIX -> mat3, la matrice normale (la transposée de l'inverse de la partie supérieure gauche 3x3 de la matrice du modèle)
- BONE_TRANSFORMS -> mat4[], le tableau des matrices osseuses du modèle
- BONE_NORMAL_TRANSFORMS -> mat3[], le tableau des matrices normales des os du modèle (la transposée de l'inverse de la partie supérieure gauche 3x3 des matrices de chaque os)
- MORPH_WEIGHTS -> float[], le tableau des poids des morphes. Le modèle associé doit fournir les données appropriées. Par sécurité, QT_MORPH_MAX_COUNT est défini à la taille de ce tableau.
- CAMERA_POSITION -> vec3, la position de la caméra dans l'espace mondial
- CAMERA_DIRECTION -> vec3, vecteur de direction de la caméra
- CAMERA_PROPERTIES -> vec2, les valeurs de clip proche et lointain pour la caméra
- POINT_SIZE -> float, accessible uniquement dans le vertex shader. Lors du rendu d'une géométrie avec une topologie de points, le vertex shader personnalisé doit définir cette valeur à 1.0 ou à une autre valeur, à la fois dans les matériaux personnalisés ombrés et non ombrés. Voir PrincipledMaterial::pointSize pour plus d'informations sur la prise en charge de tailles différentes de 1.
Matériaux personnalisés ombrés
Un matériau shaded augments le code du shader qui serait généré par un PrincipledMaterial. Contrairement aux matériaux non ombrés, qui fournissent presque toute la logique des fonctions principales du vertex et du fragment shader par eux-mêmes, empêchant l'ajout de code généré pour l'éclairage, l'ombrage, l'illumination globale, etc, les matériaux ombrés laissent la génération de shaders se dérouler normalement, comme si le CustomMaterial était un PrincipledMaterial. Les snippets de shaders de sommets et de fragments sont censés fournir des fonctions optionnelles qui sont ensuite invoquées à certains moments, ce qui leur donne la possibilité de personnaliser les couleurs et autres valeurs qui sont ensuite utilisées pour calculer l'éclairage et la couleur finale des fragments.
Plutôt que d'implémenter une seule fonction MAIN, le fragment shader d'un matériau personnalisé ombré peut implémenter plusieurs fonctions. Toutes les fonctions, y compris MAIN, sont facultatives dans les matériaux personnalisés ombrés. Un extrait de shader vide, ou même le fait de ne pas spécifier du tout les propriétés vertexShader ou fragmentShader, peut également être parfaitement valable.
Extraits de nuanceur de sommet dans un matériau personnalisé ombré
Les fonctions suivantes peuvent être mises en œuvre dans un extrait de nuanceur de sommet :
void MAIN()Lorsqu'elle est présente, cette fonction est appelée pour définir la valeur dePOSITION, la sortie vec4 du nuanceur de sommets, et, éventuellement, pour modifier les valeurs deVERTEX,COLOR,NORMAL,UV0,UV1,TANGENT,BINORMAL,JOINTS, etWEIGHTS. Contrairement aux matériaux non ombrés, il est utile d'écrire à ces endroits, car les valeurs modifiées sont alors prises en compte dans le reste du code de nuanceur généré (alors que pour les matériaux non ombrés, aucun code de nuanceur supplémentaire n'est généré). Par exemple, si le nuanceur de sommets personnalisé déplace les sommets ou les normales, il devra stocker les valeurs modifiées dansVERTEXouNORMAL, afin d'obtenir des calculs d'éclairage corrects par la suite. En outre, la fonction peut écrire dans des variables définies à l'adresseVARYINGafin de transmettre des données interpolées au nuanceur de fragments. En l'absence de cette fonction ou d'une redéfinition dePOSITION,POSITIONest calculé sur la base deVERTEXetMODELVIEWPROJECTION_MATRIX, comme le ferait PrincipledMaterial.Exemple, en s'appuyant à la fois sur les propriétés QML exposées en tant qu'uniformes et en transmettant des données au fragment shader :
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); }Remarque : dans l'exemple ci-dessus, l'attribution d'une valeur à
POSITIONest facultative, car l'utilisation dans ce cas est identique au comportement par défaut.
Remarque : pour transmettre des données sans interpolation du sommet à l'étape du fragment, ajoutez le mot-clé flat avant le type dans les déclarations VARYING.
Extraits de shader de fragment dans un matériau personnalisé ombré
Les fonctions suivantes peuvent être mises en œuvre dans un extrait de nuanceur de fragment :
void MAIN()Lorsqu'elle est présente, cette fonction est appelée pour définir les valeurs des variables spéciales inscriptiblesBASE_COLOR,METALNESS,ROUGHNESS,SPECULAR_AMOUNT, NORMAL, CLEARCOAT_FRESNEL_POWER, CLEARCOAT_FRESNEL_SCALE, CLEARCOAT_FRESNEL_BIAS, CLEARCOAT_AMOUNT, CLEARCOAT_ROUGHNESS, CLEARCOAT_NORMAL, FRESNEL_BIAS, FRESNEL_SCALE, FRESNEL_POWER, IOR,TRANSMISSION_FACTOR, THICKNESS_FACTOR, ATTENUATION_COLOR, ATTENUATION_DISTANCE etOCCLUSION_AMOUNT.Un cas d'utilisation courant consiste à définir la valeur de
BASE_COLORen fonction de l'échantillonnage d'une texture, qu'il s'agisse d'une carte de couleurs de base,SCREEN_TEXTURE, ou d'un autre type de source. Cela peut s'avérer utile et pratique, en particulier lorsqu'aucune fonction personnalisée de traitement de la lumière n'est mise en œuvre. DéfinirBASE_COLOR.aà une valeur autre que la valeur par défaut de 1,0 permet d'affecter la valeur alpha finale du fragment. (Notez que cela nécessitera souvent d'activer également le mélange alpha dans sourceBlend et destinationBlend).Un autre cas de figure se présente lorsqu'aucune fonction personnalisée
SPECULAR_LIGHTn'est fournie ou lorsqu'une sonde lumineuse est définie dans SceneEnvironment. La métallisation, la rugosité et d'autres valeurs qui affectent le calcul de la contribution spéculaire peuvent être définies dansMAINavec les valeurs personnalisées souhaitées.La fonction peut écrire dans les variables spéciales suivantes. Les valeurs écrites dans ces variables seront typiquement soit codées en dur, soit calculées sur la base des propriétés QML mappées sur les uniformes. La sémantique est identique à celle de PrincipledMaterial.
- vec4
BASE_COLOR- La couleur de base et la valeur alpha du matériau. Correspond à built-in materials' color property. Lorsque les fonctions du processeur de lumière ne sont pas implémentées, il peut être pratique de définir une couleur de base personnalisée dansMAIN, car elle est alors prise en compte dans les calculs d'éclairage par défaut. La valeur par défaut estvec4(1.0), ce qui signifie blanc avec un alpha de 1,0. La valeur alpha influe sur l'alpha final du fragment. La valeur alpha finale est l'opacité de l'objet (modèle) multipliée par la couleur de base alpha. Lorsque vous spécifiez la valeur directement dans le code du shader, sans vous appuyer sur les valeurs uniformes exposées à partir des propriétés de couleur dans QML, sachez qu'il appartient au shader d'effectuer la conversion sRGB-linéaire, si nécessaire. Par exemple, en supposant quevec3 coloretfloat alpha, cela peut être réalisé comme suit :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- La couleur de l'auto-illumination. Correspond à la couleur d'émission des matériaux intégrés qui est combinée par built-in materials's emissiveFactor property et built-in materials's emissiveMap property. La valeur par défaut estvec3(0.0). Si vous spécifiez la valeur directement dans le code du shader, sans vous appuyer sur les valeurs uniformes exposées à partir des propriétés de couleur dans QML, sachez qu'il appartient au shader d'effectuer la conversion sRGB en linéaire, le cas échéant. - float
IORSpécifie l'indice de réfraction du matériau. Une valeur typique, et aussi la valeur par défaut, est1.5, car c'est ce qu'utiliserait PrincipledMaterial. - float
TRANSMISSION_FACTORIndique le degré de translucidité. Une valeur typique serait1.0et la valeur par défaut est0.0, car c'est ce qu'utiliserait PrincipledMaterial. - float
THICKNESS_FACTORIndique l'épaisseur du matériau translucide. La valeur type est10.0et la valeur par défaut est0.0, car c'est ce qu'utiliserait PrincipledMaterial. - vec3
ATTENUATION_COLORSpécifie le décalage de couleur du matériau translucide en fonction de la distance. Une valeur typique seraitvec3(1.0, 0.0, 0.0)et la valeur par défaut estvec3(1.0), car c'est ce qu'utiliserait PrincipledMaterial. - float
ATTENUATION_DISTANCESpécifie l'atténuation du changement de couleur du matériau translucide en fonction de la distance. Une valeur typique serait100.0et la valeur par défaut est0.0, car c'est ce qu'utiliserait PrincipledMaterial. - float
METALNESSValeur de la métallicité comprise entre 0,0 et 1,0. La valeur par défaut est 0. Elle doit être fixée à une valeur non nulle pour avoir un effet. - float
ROUGHNESSValeur de rugosité comprise entre 0,0 et 1,0. La valeur par défaut est 0. - float
CLEARCOAT_FRESNEL_POWERSpécifie la puissance de fresnel de la couche de vernis. Une valeur typique, et également la valeur par défaut, est5.0, car c'est ce qu'utiliserait un site PrincipledMaterial. - float
CLEARCOAT_FRESNEL_SCALEIndique l'échelle de fresnel de la couche transparente. Une valeur typique, et aussi la valeur par défaut, est1.0, car c'est ce qu'utiliserait un PrincipledMaterial. - float
CLEARCOAT_FRESNEL_BIASSpécifie le biais de fresnel de la couche de vernis. Une valeur typique, et aussi la valeur par défaut, est0.0, car c'est ce qu'utiliserait un PrincipledMaterial. - float
CLEARCOAT_AMOUNTSpécifie la quantité de couche transparente sur le matériau. Une valeur typique serait1.0et la valeur par défaut est0.0car c'est ce qu'utiliserait PrincipledMaterial. - float
CLEARCOAT_ROUGHNESSSpécifie la rugosité de la couche de vernis. Une valeur typique serait1.0pour une couche de vernis complètement floue et la valeur par défaut est0.0car c'est ce qu'utiliserait PrincipledMaterial. - vec3
CLEARCOAT_NORMAL- La normale de la couche de vernis qui provient du vertex shader dans l'espace mondial. Bien que cette propriété ait la même valeur initiale queVAR_WORLD_NORMAL, seule la modification de la valeur deCLEARCOAT_NORMALaura un effet sur la normale de la couche de vernis. - float
FRESNEL_POWERSpécifie la puissance de Fresnel. Une valeur typique, et également la valeur par défaut, est5.0, car c'est ce qu'utiliserait PrincipledMaterial. - float
FRESNEL_SCALESpécifie l'échelle de fresnel. Une valeur typique, et aussi la valeur par défaut, est1.0car c'est ce qu'un PrincipledMaterial utiliserait. - float
FRESNEL_BIASSpécifie le biais de fresnel. Une valeur typique, et aussi la valeur par défaut, est0.0, car c'est ce qu'utiliserait un PrincipledMaterial. - float
SPECULAR_AMOUNTQuantité spéculaire comprise entre 0,0 et 1,0. La valeur par défaut est0.5, correspondant à PrincipledMaterial::specularAmount. La valeur doit être différente de zéro pour avoir un effet. - float
OCCLUSION_AMOUNTSpécifie le facteur AO. Une valeur typique, et également la valeur par défaut, est1.0car c'est ce qu'utiliserait PrincipledMaterial. - vec3
NORMAL- La normale provenant du vertex shader dans l'espace mondial. Bien que cette propriété ait la même valeur initiale queVAR_WORLD_NORMAL, seule la modification de la valeur deNORMALaura un effet sur l'éclairage. - vec3
TANGENT- La tangente qui provient du nuanceur de sommets dans l'espace mondial. Cette valeur est potentiellement ajustée pour la double face. - vec3
BINORMAL- La binormale provenant du vertex shader dans l'espace mondial. Cette valeur est potentiellement ajustée pour la double face. - vec2
UV0- Le premier ensemble de coordonnées de texture provenant du nuanceur de sommets. Cette propriété est en lecture seule dans le fragment shader. - vec2
UV1- Le deuxième ensemble de coordonnées de texture du nuanceur de sommets. Cette propriété est en lecture seule dans le fragment shader.
Remarque : contrairement aux matériaux non ombrés, le fragment
MAINd'un matériau ombré n'a pas de contrôle direct surFRAGCOLOR. Ce sont plutôt les valeursDIFFUSEetSPECULARécrites dans les fonctions du processeur de lumière qui déterminent la couleur finale du fragment. Lorsqu'une fonction de traitement de la lumière n'est pas mise en œuvre, les calculs d'ombrage par défaut pertinents sont effectués comme pour une PrincipledMaterial, en tenant compte deBASE_COLORet d'autres valeurs de la liste ci-dessus.Voici un exemple de nuanceur de matériau simple et métallique personnalisé :
void MAIN() { METALNESS = 1.0; ROUGHNESS = 0.5; FRESNEL_POWER = 5.0; }Un autre exemple, où la couleur de base et l'alpha sont définis par l'échantillonnage d'une texture :
VARYING vec2 texcoord; void MAIN() { BASE_COLOR = texture(uColorMap, texcoord); }- vec4
void AMBIENT_LIGHT()Lorsqu'elle est présente, cette fonction est appelée une fois pour chaque fragment. La tâche de la fonction est d'ajouter la contribution ambiante totale à une variable spéciale inscriptibleDIFFUSE. Elle peut bien sûr choisir de calculer une valeur différente, ou de ne pas toucher du tout àDIFFUSE(pour ignorer complètement l'éclairage ambiant). PrincipledMaterialLa fonction peut écrire dans les variables spéciales suivantes :
- vec3
DIFFUSEAccumule les contributions de la lumière diffuse, par fragment. Les fonctions de traitement de la lumière y ajoutent généralement (+=), car l'écrasement de la valeur entraînerait la perte de la contribution des autres lumières.
La fonction peut lire les variables spéciales suivantes, en plus des uniformes matriciels (tels que
MODEL_MATRIX) et vectoriels (tels queCAMERA_POSITION) du tableau ci-dessus :- vec3
TOTAL_AMBIENT_COLORLa contribution ambiante totale dans la scène.
Exemple :
void AMBIENT_LIGHT() { DIFFUSE += TOTAL_AMBIENT_COLOR; }- vec3
void DIRECTIONAL_LIGHT()Lorsqu'elle est présente, cette fonction est appelée pour chaque lumière directionnelle active dans la scène, pour chaque fragment. La fonction a pour tâche d'ajouter la contribution diffuse à une variable spéciale inscriptibleDIFFUSE. La fonction peut également choisir de ne rien faire, auquel cas les contributions diffuses des lumières directionnelles sont ignorées. Lorsque la fonction n'est pas présente du tout, les contributions diffuses des lumières directionnelles sont accumulées normalement, comme le ferait un site PrincipledMaterial.La fonction peut écrire dans les variables spéciales suivantes :
- vec3
DIFFUSEAccumule les contributions lumineuses diffuses, par fragment.
- Les fonctions de traitement de la lumière y ajoutent généralement (
+=
- , car l'écrasement de la valeur entraînerait la perte de la contribution des autres lumières.
La fonction peut lire les variables spéciales suivantes, en plus des uniformes matriciels (tels que
)MODEL_MATRIXet vectoriels (tels que
)CAMERA_POSITIONdu tableau ci-dessus :
- vec3
LIGHT_COLORCouleur de la lumière diffuse. - float
SHADOW_CONTRIBContribution de l'ombre, ou 1.0 s'il n'y a pas d'ombre du tout ou s'il ne reçoit pas d'ombre. - vec3
- vec3
- Vecteur pointant vers la source lumineuse.
- vec3
NORMALVecteur normal dans l'espace mondial. - vec4
BASE_COLORCouleur de base et valeur alpha du matériau. - float
METALNESSQuantité de métal. - float
ROUGHNESSQuantité de rugosité.
Exemple :
void DIRECTIONAL_LIGHT() { DIFFUSE += LIGHT_COLOR * SHADOW_CONTRIB * vec3(max(0.0, dot(normalize(VAR_WORLD_NORMAL), TO_LIGHT_DIR))); }void POINT_LIGHT()Lorsqu'elle est présente, cette fonction est appelée pour chaque lumière ponctuelle active dans la scène, pour chaque fragment. La fonction a pour tâche d'ajouter la contribution diffuse à une variable spéciale inscriptibleDIFFUSE. La fonction peut également choisir de ne rien faire, auquel cas les contributions diffuses des lumières ponctuelles sont ignorées. Lorsque la fonction n'est pas présente du tout, les contributions diffuses des lumières ponctuelles sont accumulées normalement, comme le ferait un site PrincipledMaterial- .
La fonction peut écrire dans les variables spéciales suivantes :
- vec3
DIFFUSEAccumule les contributions lumineuses diffuses, par fragment.
La fonction peut lire les variables spéciales suivantes, en plus des uniformes matriciels (tels que
)MODEL_MATRIXet vectoriels (tels que
)CAMERA_POSITIONdu tableau ci-dessus :
- vec3
LIGHT_COLORDiffuse light color (couleur de la lumière diffuse). - float
LIGHT_ATTENUATIONAtténuation de la lumière. - float
SHADOW_CONTRIBContribution à l'ombre, ou 1,0 s'il n'y a pas d'ombre du tout ou s'il n'en reçoit pas. vec3
- Vecteur pointant vers la source lumineuse.
- vec3
NORMALVecteur normal dans l'espace mondial. - vec4
BASE_COLORCouleur de base et valeur alpha du matériau. - float
METALNESSQuantité de métal. - float
ROUGHNESSQuantité de rugosité.
Exemple :
void POINT_LIGHT() { DIFFUSE += LIGHT_COLOR * LIGHT_ATTENUATION * SHADOW_CONTRIB * vec3(max(0.0, dot(normalize(VAR_WORLD_NORMAL), TO_LIGHT_DIR))); }void SPOT_LIGHT()Lorsqu'elle est présente, cette fonction est appelée pour chaque lumière ponctuelle active dans la scène, pour chaque fragment. La fonction a pour tâche d'ajouter la contribution diffuse à une variable spéciale inscriptibleDIFFUSE. La fonction peut également choisir de ne rien faire, auquel cas les contributions diffuses des projecteurs sont ignorées. Lorsque la fonction n'est pas présente du tout, les contributions diffuses des lumières ponctuelles sont accumulées normalement, comme le ferait un site PrincipledMaterial- .
La fonction peut écrire dans les variables spéciales suivantes :
- vec3
DIFFUSEAccumule les contributions lumineuses diffuses, par fragment.
La fonction peut lire les variables spéciales suivantes, en plus des uniformes matriciels (tels que
)MODEL_MATRIXet vectoriels (tels que
)CAMERA_POSITIONdu tableau ci-dessus :
- vec3
LIGHT_COLORCouleur de la lumière diffuse. - float
LIGHT_ATTENUATIONAtténuation de la lumière. - float
SHADOW_CONTRIBContribution de l'ombre, ou 1,0 s'il n'y a pas d'ombre du tout ou s'il n'en reçoit pas. - vec3
TO_LIGHT_DIRVecteur pointant vers la source de lumière. - float
SPOT_FACTORFacteur de lumière ponctuelle. - vec3
NORMALVecteur de normalité dans l'espace mondial. - vec4
BASE_COLORLa couleur de base et la valeur alpha du matériau. - float
METALNESSLa quantité de métal. - float
ROUGHNESSLa quantité de rugosité.
Exemple :
void SPOT_LIGHT() { DIFFUSE += LIGHT_COLOR * LIGHT_ATTENUATION * SPOT_FACTOR * SHADOW_CONTRIB * vec3(max(0.0, dot(normalize(VAR_WORLD_NORMAL), TO_LIGHT_DIR))); }void SPECULAR_LIGHT()Lorsqu'elle est présente, cette fonction est appelée pour chaque lumière active dans la scène pour chaque fragment. La tâche de la fonction est d'ajouter la contribution spéculaire à une variable spéciale inscriptibleSPECULAR. La fonction peut également choisir de ne rien faire, auquel cas les contributions spéculaires des lumières sont ignorées. Lorsque la fonction n'est pas présente du tout, les contributions spéculaires des lumières sont accumulées normalement, comme le ferait un site PrincipledMaterial.La fonction peut écrire dans les variables spéciales suivantes :
- vec3
SPECULARAccumule les contributions spéculaires de la lumière, par fragment.
- Les fonctions de traitement de la lumière y ajoutent généralement (
+=
- , car l'écrasement de la valeur entraînerait la perte de la contribution des autres lumières.
La fonction peut lire les variables spéciales suivantes, en plus des uniformes matriciels (tels que
)MODEL_MATRIXet vectoriels (tels que
)CAMERA_POSITIONdu tableau ci-dessus :
- vec3
LIGHT_COLORCouleur de la lumière spéculaire. - float
LIGHT_ATTENUATIONAtténuation de la lumière. Pour les lumières directionnelles, la valeur est de 1,0. - Pour les lumières ponctuelles, la valeur est la même que
LIGHT_ATTENUATION * SPOT_FACTORdevoid SPOT_LIGHT(). - float
SHADOW_CONTRIBContribution à l'ombre, ou 1,0 si l'ombre n'est pas du tout présente ou si elle ne reçoit pas d'ombre. - vec3
FRESNEL_CONTRIBContribution de Fresnel à partir du calcul de Fresnel intégré. - vec3
TO_LIGHT_DIRVecteur pointant vers la source de lumière. - vec3
NORMALLe vecteur normal dans l'espace mondial. - vec4
BASE_COLORLa couleur de base et la valeur alpha du matériau. - float
METALNESSLa quantité de métal. - float
ROUGHNESSLa quantité de rugosité. - float
SPECULAR_AMOUNTLa quantité de lumière spéculaire. Cette valeur est comprise entre 0,0 et 1,0 et correspond à la valeur définie dans la fonction personnaliséeMAIN. Cette valeur sera utile pour calculer les contributions de Fresnel lorsque vous n'utilisez pas la contribution de Fresnel intégrée fournie parFRESNEL_CONTRIB
.- 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()Lorsqu'elle est présente, cette fonction est appelée à la fin du pipeline de fragments. La tâche de cette fonction est de finaliserCOLOR_SUMavec les termes diffus, spéculaires et émissifs finaux. Contrairement àFRAGCOLORpour un matériau non ombré,COLOR_SUMsera automatiquement tonématisé avant d'être écrit dans le framebuffer. À des fins de débogage, il est parfois utile de sortir une valeur qui ne doit pas être traitée comme une couleur. Pour éviter que le tonemapping ne déforme cette valeur, il est possible de la désactiver en réglant la propriété tonemapMode surTonemapModeNone. La fonction peut écrire dans les variables spéciales suivantes :
- vec4
COLOR_SUMla sortie du fragment shader.
- La valeur par défaut est vec4(DIFFUSE.rgb + SPECULAR + EMISSIVE, DIFFUSE.a)
La fonction peut lire les variables spéciales suivantes :
- vec4
DIFFUSELe terme diffus final du pipeline de fragments. - vec3
SPECULARLe terme spéculaire final du pipeline de fragments. - vec3
EMISSIVELe terme émissif final du pipeline de fragments. - vec2
UV0- Le premier ensemble de coordonnées de texture du nuanceur de sommets. - vec2
UV1- Le deuxième ensemble de coordonnées de texture du nuanceur de sommets.
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()Lorsqu'elle est présente, cette fonction est appelée pour l'éclairage basé sur l'image (IBL). La fonction a pour tâche d'ajouter les contributions diffuses et spéculaires de l'IBL aux variables spéciales inscriptiblesDIFFUSEetSPECULAR. La fonction peut écrire dans les variables spéciales suivantes :
- vec3
DIFFUSEAccumule les contributions lumineuses diffuses, par fragment. - vec3
SPECULARAccumule les contributions lumineuses spéculaires, par fragment.
La fonction peut lire les variables spéciales suivantes :
- vec4
BASE_COLORLa couleur de base et la valeur alpha du matériau. - float
AO_FACTORLe facteur d'occlusion de l'espace écran. - float
SPECULAR_AMOUNTLa quantité spéculaire. - float
ROUGHNESSLe terme émissif final du pipeline de fragments. - vec3
NORMALLe vecteur normal dans l'espace monde. - vec3
VIEW_VECTORPointe vers la caméra. - mat3
IBL_ORIENTATIONL'orientation de la sonde lumineuse. Elle provient de SceneEnvironment::probeOrientation
.- vec3
void IBL_PROBE() { vec3 smpDir = IBL_ORIENTATION * NORMAL; DIFFUSE += AO_FACTOR * BASE_COLOR.rgb * textureLod(IBL_TEXTURE, smpDir, IBL_MAXMIPMAP).rgb; }
TO_LIGHT_DIR TO_LIGHT_DIR Variables personnalisées entre les fonctions
Des variables supplémentaires peuvent être transmises de la fonction MAIN aux autres fonctions. Le mot-clé SHARED_VARS peut être utilisé pour définir de nouvelles variables personnalisées. Ces variables définies par l'utilisateur sont accessibles avec SHARED.<nom de la variable>.
Par exemple, un matériau personnalisé ombré peut récupérer une valeur partagée dans la fonction MAIN et l'utiliser dans d'autres fonctions.
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;
}Remarque : SHARED peut être écrit dans toutes les fonctions sans POST_PROCESS, mais il est prudent de l'écrire dans MAIN et de le lire dans les autres fonctions.
Remarque : il est recommandé d'écrire SHARED dans les fonctions LIGHT en le réinitialisant d'abord dans MAIN, puis en l'accumulant dans chaque fonction LIGHT.
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;
}Note : MAIN est appelé avant les autres, et POST_PROCESS après tous les autres, mais il n'y a aucune garantie d'un autre ordre pour les processeurs légers.
Mots clés spéciaux supplémentaires
Le code du nuanceur de fragments personnalisé peut accéder librement aux uniformes (tels que CAMERA_DIRECTION ou CAMERA_POSITION) et aux variations transmises par le nuanceur de sommets personnalisé. En outre, il existe un certain nombre de variations intégrées disponibles sous forme de mots-clés spéciaux. Certains d'entre eux sont facultatifs dans le sens où un vertex MAIN pourrait les calculer et les transmettre lui-même, mais pour réduire la duplication des données, les nuanceurs de fragment peuvent également s'appuyer sur ces éléments intégrés. Ces modules sont disponibles dans les fonctions du processeur de lumière et dans le fragment MAIN.
- vec3
VAR_WORLD_NORMAL- Normale interpolée transformée parNORMAL_MATRIX. - vec3
VAR_WORLD_TANGENT- Tangente interpolée transformée parMODEL_MATRIX. - vec3
VAR_WORLD_BINORMAL- Interpolation de la binormale transformée parMODEL_MATRIX - vec3
NORMAL- Contrairement àVAR_WORLD_NORMAL, qui est la normale interpolée telle quelle, cette valeur est potentiellement ajustée pour la double face : lors du rendu avec le culling désactivé, la normale sera inversée si nécessaire. Par conséquent, il est recommandé d'utiliserNORMALau lieu deVAR_WORLD_NORMALpour les calculs d'éclairage et autres afin de se comporter correctement avec tous les modes d'abattage. - vec3
TANGENT- CommeNORMAL, cette valeur est potentiellement ajustée pour la double face : lorsque le rendu est effectué avec le culling désactivé, la tangente sera inversée si nécessaire. - vec3
BINORMAL- CommeNORMAL, cette valeur est potentiellement ajustée pour la double face : lorsque le rendu est désactivé, la binormale sera inversée si nécessaire. - vec3
VAR_WORLD_POSITION- Position interpolée du sommet dans l'espace mondial ((MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz) - vec4
VAR_COLOR- La couleur interpolée du sommet lorsque les couleurs sont fournies dans le maillage.vec4(1.0)dans le cas contraire. - vec3
VIEW_VECTOR- Pointe vers la caméra. Il s'agit en fait du vecteurCAMERA_POSITION - VAR_WORLD_POSITIONnormalisé. - vec4
FRAGCOORD- Contient les coordonnées relatives à la fenêtre du fragment actuel. - float
FRAMEBUFFER_Y_UP- La valeur est1lorsque l'axe Y pointe vers le haut dans le système de coordonnées des framebuffers (textures), ce qui signifie que(0, 0)est le coin inférieur gauche. La valeur est-1lorsque l'axe Y pointe vers le bas,(0, 0)étant le coin supérieur gauche. De telles différences dans les API graphiques sous-jacentes ne concernent pas la plupart des matériaux personnalisés. Une exception notable est l'échantillonnage deSCREEN_TEXTUREavec des coordonnées de texture non basées surFRAGCOORD. L'orientation deSCREEN_TEXTUREétant par nature liée à l'API graphique sous-jacente, l'utilisation des coordonnées de texture d'un maillage peut nécessiter des ajustements appropriés de la coordonnée Y.Par exemple, le fragment shader suivant, adapté aux maillages Rectangle ou Cube, affichera les objets opaques de la scène sur le modèle :
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); }Lors de l'échantillonnage de textures autres que
SCREEN_TEXTURE, etDEPTH_TEXTURE, ou lorsqueFRAGCOORDest utilisé pour calculer la coordonnée de texture (ce qui serait le cas d'utilisation typique pour accéder aux textures d'écran et de profondeur), un tel ajustement n'est pas nécessaire. - float
NDC_Y_UP- La valeur est1lorsque l'axe Y pointe vers le haut dans l'espace de coordonnées normalisé du périphérique, et-1lorsque l'axe Y pointe vers le bas. L'axe Y pointant vers le bas est le cas lorsque le rendu se fait avec Vulkan. La plupart des matériaux n'ont pas besoin d'être concernés par cela, mais être capable de brancher en fonction de cela peut devenir utile dans certains cas d'utilisation avancés. - float
NEAR_CLIP_VALUE- La valeur est-1lorsque la plage du plan d'écrêtage commence à-1et va jusqu'à1. Ceci est vrai lorsque l'on utilise OpenGL pour le rendu. Pour les autres systèmes de rendu, la valeur de cette propriété sera0, ce qui signifie que le plan d'écrêtage se situe entre0et1. Cette valeur est utile pour certaines techniques impliquant le plan d'écrêtage.DEPTH_TEXTUREPar exemple, le fragment shader suivant démontre une technique de reconstruction de la position d'une valeur à partir du tampon de profondeur pour déterminer la distance par rapport à la position actuelle en cours de rendu. Lorsqu'elle est utilisée en combinaison avec
INVERSE_PROJECTION_MATRIX, la valeur de la profondeur doit être exprimée en coordonnées normalisées, il est donc important de s'assurer que la plage de la valeur de la profondeur le reflète. LorsqueNEAR_CLIP_VALUEest-1, la valeur de la profondeur est mise à l'échelle pour être comprise entre-1et1.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- La quantité de lumière émise par la sonde lumineuse. Elle provient de SceneEnvironment::probeExposure.DIFFUSE += AO_FACTOR * IBL_EXPOSE * BASE_COLOR.rgb * textureLod(IBL_TEXTURE, NORMAL, IBL_MAXMIPMAP).rgb;
- float
IBL_HORIZON- La valeur de coupure horizontale des réflexions provenant de la moitié inférieure de l'environnement. Elle provient de Horizon Cut-Off mais est remappée à [-1, 0].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- Le niveau maximum de mipmap de IBL_TEXTURE.
Instanciation
Lors d'un rendu instancié, certains des mots-clés ci-dessus ne s'appliquent pas. Les mots-clés suivants ne sont disponibles qu'avec l'instanciation :
INSTANCE_MODEL_MATRIX-> mat4, remplacement deMODEL_MATRIX, y compris la transformation d'instanciation.INSTANCE_MODELVIEWPROJECTION_MATRIX-> mat4, remplacement deMODELVIEWPROJECTION_MATRIX, y compris la transformation d'instanciation.INSTANCE_COLOR-> vec4, la couleur de l'instance : à combiner avecCOLOR.INSTANCE_DATA-> vec4, les données personnalisées de l'instance.INSTANCE_INDEX-> int, le numéro de l'instance et l'index dans la table d'instanciation.
Écran, profondeur et autres textures
Le pipeline de rendu peut exposer un certain nombre de textures aux shaders de matériaux personnalisés avec le contenu de passes de rendu spéciales. Cela s'applique à la fois aux matériaux personnalisés ombrés et non ombrés.
Par exemple, un shader peut vouloir accéder à une texture de profondeur qui contient le contenu du tampon de profondeur pour les objets opaques de la scène. Ceci est possible en échantillonnant DEPTH_TEXTURE. Une telle texture n'est normalement pas générée, sauf en cas de besoin réel. Par conséquent, la présence des mots-clés suivants dans le vertex ou le fragment shader agit également comme une bascule pour opter pour les passes - potentiellement coûteuses - de génération de la texture en question. (Bien sûr, il se peut que certains de ces paramètres soient déjà activés en raison d'autres réglages, tels que les paramètres d'occlusion ambiante dans SceneEnvironment ou en raison d'un effet de post-traitement reposant sur la texture de profondeur, auquel cas les textures en question sont générées indépendamment du matériau personnalisé et l'échantillonnage de ces textures spéciales dans le matériau n'entraîne aucun coût supplémentaire en dehors de l'accès à la texture elle-même).
SCREEN_TEXTURE- Lorsqu'elle est présente, une texture (sampler2Dousampler2DArray) avec le tampon de couleur d'une passe de rendu contenant le contenu de la scène à l'exclusion de tout matériau transparent ou de tout matériau utilisant également la SCREEN_TEXTURE est exposée au shader sous ce nom. La texture peut être utilisée pour des techniques qui nécessitent le contenu du framebuffer sur lequel elles sont rendues. La texture SCREEN_TEXTURE utilise le même mode d'effacement que la texture View3D. La taille de ces textures correspond à la taille de View3D en pixels. Par exemple, un nuanceur de fragment peut contenir ce qui suit :vec2 uv = FRAGCOORD.xy / vec2(textureSize(SCREEN_TEXTURE, 0)); vec2 displace = vec2(0.1); vec4 c = texture(SCREEN_TEXTURE, uv + displace);
Soyez conscient que l'utilisation de
SCREEN_TEXTUREnécessite une conception appropriée et consciente de la scène. Les objets utilisant ces matériaux doivent être positionnés avec soin, généralement au-dessus de tous les autres objets qui devraient être visibles dans la texture. Les objets qui utilisent la semi-transparence sous une forme ou une autre ne font jamais partie deSCREEN_TEXTURE. Souvent,SCREEN_TEXTUREsera utilisé en combinaison avecBASE_COLORdansMAIN. Par exemple, le fragment shader personnalisé suivant applique un effet de gaufrage, tout en gardant transparents les fragments qui ne sont pas touchés par des objets opaques.Cela suppose que l'objet avec le matériau est placé à l'avant et que le mélange est activé.
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); }Avec le rendu multivue,
.SCREEN_TEXTUREest unsampler2DArrayUtilisez
VIEW_INDEXpour sélectionner le calque à utiliser. Pour les applications VR/AR qui souhaitent prendre en charge les deux types de rendu, l'approche portable est la suivante :#if QSHADER_VIEW_COUNT >= 2 vec4 c = texture(SCREEN_TEXTURE, vec3(uv, VIEW_INDEX)); #else vec4 c = texture(SCREEN_TEXTURE, uv); #endifSCREEN_MIP_TEXTURE- Identique àSCREEN_TEXTUREsur la plupart des points, la différence étant que cette texture a des mipmaps générés. Cette fonctionnalité peut s'avérer coûteuse en termes de performances, en fonction de la taille de l'écran, et parce qu'il faut générer les mipmaps à chaque fois que la scène est rendue. Il est donc préférable d'utiliser toujoursSCREEN_TEXTURE, à moins qu'une technique reposant sur les niveaux de mip de la texture (par exemple, l'utilisation detextureLoddans le shader) ne soit mise en œuvre par le matériau personnalisé.DEPTH_TEXTURE- Lorsqu'elle est présente, une texture (sampler2Dousampler2DArray) avec le contenu du tampon de profondeur (non linéarisé) est exposée au shader sous ce nom. Seuls les objets opaques sont inclus. Par exemple, un nuanceur de fragment peut contenir ce qui suit :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;
Avec le rendu multivue,
.DEPTH_TEXTUREest unsampler2DArrayUtilisez
VIEW_INDEXpour sélectionner la couche à utiliser. Pour les applications VR/AR qui souhaitent prendre en charge les deux types de rendu, l'approche portable est la suivante :#if QSHADER_VIEW_COUNT >= 2 vec4 depthSample = texture(DEPTH_TEXTURE, vec3(uv, VIEW_INDEX)); #else vec4 depthSample = texture(DEPTH_TEXTURE, uv); #endifNORMAL_ROUGHNESS_TEXTURE- Lorsqu'elle est présente, une texture (sampler2D) avec les normales de l'espace-monde et la rugosité du matériau est exposée au nuanceur sous ce nom. Seuls les objets opaques sont inclus. La rugosité est stockée dans le canal alpha. Par exemple, un shader de fragment peut contenir les éléments suivants :vec3 N = normalize(texture(NORMAL_ROUGHNESS_TEXTURE, uv).rgb);
-
AO_TEXTURE- Lorsqu'elle est présente et que l'occlusion ambiante de l'espace-écran est activée (c'est-à-dire lorsque la force AO et la distance sont toutes deux non nulles) dans SceneEnvironment, la texture SSAO (sampler2Dousampler2DArray) est exposée au shader sous ce nom. L'échantillonnage de cette texture peut être utile dans les matériaux non ombrés. Les matériaux ombrés intègrent la prise en charge de l'occlusion ambiante. Cela signifie que le facteur d'occlusion ambiante est pris en compte automatiquement. Alors que dans un nuanceur de fragment pour un matériau non ombré, on pourrait écrire ce qui suit pour obtenir le même résultat :ivec2 aoSize = textureSize(AO_TEXTURE, 0); vec2 aoUV = (FRAGCOORD.xy) / vec2(aoSize); float aoFactor = texture(AO_TEXTURE, aoUV).x;
Avec le rendu multivue,
AO_TEXTUREest unsampler2DArray. UtilisezVIEW_INDEXpour sélectionner la couche à utiliser. Pour les applications VR/AR qui souhaitent prendre en charge les deux types de rendu, l'approche portable est la suivante :#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- Elle ne permet pas d'effectuer une passe de rendu spéciale, mais elle peut être utilisée lorsque le matériau est Material::lightProbe ou que le modèle se trouve dans le champ d'application de SceneEnvironment::lightProbe.void IBL_PROBE() { DIFFUSE += AO_FACTOR * BASE_COLOR.rgb * textureLod(IBL_TEXTURE, NORMAL, IBL_MAXMIPMAP).rgb; }MOTION_VECTOR_TEXTURE- Active une passe de rendu dédiée qui calcule les vecteurs de mouvement par objet pour la scène. La sortie est une texture à quatre canaux : les composantes R et G contiennent les vecteurs de mouvement mis à l'échelle des modèles, tandis que les composantes B et A stockent les vecteurs de mouvement non mis à l'échelle.VIEW_INDEX- Lorsqu'elle est utilisée dans le code du shader personnalisé, il s'agit d'une variable uint (non interpolée). Lorsque le rendu multi-vues n'est pas utilisé, la valeur est toujours 0. Avec le rendu multi-vues, la valeur est l'index de la vue actuelle (par exemple, gl_ViewIndex). Utile en particulier en combinaison avecDEPTH_TEXTUREet similaires lorsque le rendu multi-vues est activé.
Voir également SceneEnvironment::tonemapMode, Using Image-Based Lighting, Qt Quick 3D - Custom Shaders Example, Qt Quick 3D - Custom Materials Example, et Programmable Materials, Effects, Geometry, and Texture data.
Documentation sur les propriétés
alwaysDirty : bool
Spécifie que l'état du matériau est toujours sale, ce qui indique que le matériau doit être rafraîchi chaque fois qu'il est utilisé par le site QtQuick3D.
destinationAlphaBlend : enumeration [since 6.7]
Spécifie le facteur de fusion alpha de la destination. La valeur par défaut est CustomMaterial.NoBlend. Cette valeur n'est activement utilisée que si sourceBlend et destinationBlend ont une valeur autre que la valeur par défaut.
| Constante | Valeur |
|---|---|
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 |
Remarque : pour des raisons de compatibilité ascendante, la valeur par défaut sera attribuée à la même valeur que destinationBlend lorsque sourceBlend et destinationBlend sont définis sur des valeurs autres que la valeur par défaut.
Cette propriété a été introduite dans Qt 6.7.
Voir aussi destinationBlend.
destinationBlend : enumeration
Spécifie le facteur de fusion de destination. La valeur par défaut est CustomMaterial.NoBlend.
| Constante | Valeur |
|---|---|
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 |
Remarque : sourceBlend et destinationBlend doivent tous deux être définis sur une valeur autre que la valeur par défaut avant que le mélange ne soit activé.
Voir également sourceBlend.
fragmentShader : url
Spécifie le fichier contenant l'extrait de code de nuanceur de fragment personnalisé.
La valeur est une URL et doit être un fichier local ou utiliser le schéma qrc pour accéder aux fichiers intégrés via le système de ressources Qt. Les chemins d'accès relatifs (sans schéma) sont également acceptés, auquel cas le fichier est traité comme relatif au composant (le fichier .qml ).
Attention : Les extraits de shaders sont supposés être des contenus de confiance. Il est conseillé aux développeurs d'applications d'examiner attentivement les implications potentielles avant d'autoriser le chargement d'un contenu fourni par l'utilisateur qui ne fait pas partie de l'application.
Voir également vertexShader.
lineWidth : real
Cette propriété détermine la largeur des lignes rendues, lorsque la géométrie utilise un type primitif de lignes ou de bandes de lignes. La valeur par défaut est 1.0. Cette propriété n'est pas pertinente pour le rendu d'autres types de géométrie, tels que les maillages triangulaires.
Attention : Les largeurs de ligne autres que 1 peuvent ne pas être prises en charge au moment de l'exécution, en fonction de l'API graphique sous-jacente. Si c'est le cas, la demande de modification de la largeur est ignorée. Par exemple, aucune des API suivantes ne prend en charge les lignes larges : Direct3D, Metal, OpenGL avec des contextes de profil de base.
Remarque : contrairement à la largeur des lignes, dont la valeur fait partie de l'objet du pipeline graphique, la taille des points pour les géométries avec une topologie de points est contrôlée par le vertex shader (lorsqu'il est pris en charge), et n'a donc pas de propriété QML correspondante.
shadingMode : enumeration
Spécifie le type de matériau. La valeur par défaut est Shaded.
| Constante | Valeur |
|---|---|
CustomMaterial.Unshaded | |
CustomMaterial.Shaded |
sourceAlphaBlend : enumeration [since 6.7]
Spécifie le facteur de fusion alpha de la source. La valeur par défaut est CustomMaterial.NoBlend. Cette valeur n'est activement utilisée que si sourceBlend et destinationBlend ont une valeur différente de la valeur par défaut.
| Constante | Valeur |
|---|---|
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 |
Remarque : pour des raisons de compatibilité ascendante, la valeur par défaut sera attribuée à la même valeur que sourceBlend lorsque sourceBlend et destinationBlend sont définis sur des valeurs autres que la valeur par défaut.
Cette propriété a été introduite dans Qt 6.7.
Voir aussi sourceBlend.
sourceBlend : enumeration
Spécifie le facteur de fusion de la source. La valeur par défaut est CustomMaterial.NoBlend.
| Constante | Valeur |
|---|---|
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 |
Remarque : SourceBlend et destinationBlend doivent tous deux être définis sur une valeur autre que la valeur par défaut avant que le mélange ne soit activé.
Voir également destinationBlend.
vertexShader : url
Spécifie le fichier contenant l'extrait de code du vertex shader personnalisé.
La valeur est une URL et doit être un fichier local ou utiliser le schéma qrc pour accéder aux fichiers intégrés via le système de ressources Qt. Les chemins d'accès relatifs (sans schéma) sont également acceptés, auquel cas le fichier est traité comme relatif au composant (le fichier .qml ).
Attention : Les extraits de shaders sont supposés être des contenus de confiance. Il est conseillé aux développeurs d'applications d'examiner attentivement les implications potentielles avant d'autoriser le chargement d'un contenu fourni par l'utilisateur qui ne fait pas partie de l'application.
Voir également fragmentShader.
© 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.