Référence de matière personnalisée

Sceneform fournit des définitions Material par défaut (.sfm) pour permettre aux développeurs d'obtenir facilement d'excellents résultats. Les développeurs qui souhaitent personnaliser en profondeur l'apparence de leurs éléments peuvent créer leurs propres définitions Material (fichiers *.mat) et les appliquer à leurs éléments en spécifiant l'attribut source dans leur définition.

Concepts fondamentaux

Matériau
Un matériau définit l'apparence visuelle d'une surface. Pour décrire et afficher complètement une surface, un support fournit les informations suivantes :
  • Modèle Material
  • Ensemble de paramètres nommés contrôlables par l'utilisation
  • État de la trame (mode de fusion, sélection de la face arrière, etc.)
  • Code du nuanceur Vertex
  • Code du nuanceur de fragment
Modèle Material
Également appelé modèle d'ombre ou modèle d'éclairage, le modèle Material définit les propriétés intrinsèques d'une surface. Ces propriétés ont une influence directe sur le mode de calcul de l'éclairage, et donc sur l'apparence d'une surface.
Définition du Material
Fichier texte décrivant toutes les informations requises par un support de cours. Cette page décrit la structure et le format des fichiers de définition Material (*.mat).

Définitions Material

Une définition Material est un fichier texte qui décrit toutes les informations requises par un support:

  • Nom
  • Paramètres utilisateur
  • Modèle Material
  • Attributs obligatoires
  • Interpolants (appelés variables)
  • État de la trame (mode de fusion, etc.)
  • Code du nuanceur (nuanceur fragment, nuanceur Vertex facultatif)

Format

Le format de définition Material est un format qui s'appuie sur JSON, que nous appelons JSONish. Au niveau supérieur, une définition Material est composée de trois blocs différents qui utilisent la notation d'objet JSON:

material {
    // material properties
}

vertex {
    // vertex shader, optional
}

fragment {
    // fragment shader
}

Une définition matérielle viable minimale doit contenir un bloc material et un bloc fragment. Le bloc vertex est facultatif.

Différences avec JSON

Au format JSON, un objet est constitué de paires clé/valeur. Une paire JSON utilise la syntaxe suivante:

"key" : value

Où la valeur peut être une chaîne, un nombre, un objet, un tableau ou un littéral (true, false ou null). Bien que cette syntaxe soit parfaitement valide dans une définition Material, une variante sans guillemets autour des chaînes est également acceptée dans JSONish:

key : value

Les guillemets restent obligatoires lorsque la chaîne contient des espaces.

Les blocs vertex et fragment contiennent du code GLSL sans échappement et sans guillemets, qui n'est pas valide au format JSON.

Les commentaires de style C++ sur une seule ligne sont autorisés.

La clé d'une paire est sensible à la casse.

La valeur d'une paire n'est pas sensible à la casse.

Exemple

Voici un exemple de définition de matière valide : Cette définition utilise le modèle éclairé, utilise le mode de mélange opaque par défaut, nécessite la définition d'un ensemble de coordonnées UV dans le maillage rendu et définit trois paramètres utilisateur. Les sections suivantes de ce document décrivent les blocs material et fragment en détail.

material {
    name : "Textured material",
    parameters : [
        {
           type : sampler2d,
           name : texture
        },
        {
           type : float,
           name : metallic
        },
        {
            type : float,
            name : roughness
        }
    ],
    requires : [
        uv0
    ],
    shadingModel : lit,
    blending : opaque
}

fragment {
    void material(inout MaterialInputs material) {
        prepareMaterial(material);
        material.baseColor = texture(materialParams_texture, getUV0());
        material.metallic = materialParams.metallic;
        material.roughness = materialParams.roughness;
    }
}

Bloc Material

Le bloc Material est un bloc obligatoire qui contient une liste de paires de propriétés pour décrire toutes les données qui ne sont pas des ombres.

name

Type
string
Value
Toute chaîne. Des guillemets doubles sont nécessaires si le nom contient des espaces.
Description
Définit le nom du support. Le nom est conservé au moment de l'exécution pour le débogage.
material {
    name : stone
}

material {
    name : "Wet pavement"
}

shadingModel

Type
string
Value
Les valeurs possibles : lit, cloth, unlit. Valeur par défaut : lit.
Description
Sélectionnez le modèle Material, comme décrit dans la section Modèles Material.
material {
    shadingModel : unlit
}

paramètres

Type
Tableau des objets de paramètre
Value

Chaque entrée est un objet avec les propriétés name et type, de type string. Le nom doit être un identifiant GLSL valide. Le type doit être l'un des types décrits dans le tableau ci-dessous.

Type Description
Bool Booléen
bool2 Vecteur de 2 booléens
bool3 Vecteur de 3 booléens
bool4 Vecteur de 4 booléens
float Flottant simple
Nombre décimal 2 Vecteur de 2 nombres à virgule flottante
Nombre décimal 3 Vecteur de 3 nombres à virgule flottante
Nombre décimal 4 Vecteur de 4 nombres à virgule flottante
int Entier simple
Int2 Vecteur de 2 entiers
Int3 Vecteur de 3 entiers
Int4 Vecteur de 4 entiers
échantillonneur2j Texture 2D
échantillonneur externe Texture externe. Pour en savoir plus, consultez ExternalTexture et setExternalTexture().
Échantillonneurs

Les types d'échantillonneurs peuvent également spécifier un format (float par défaut) et un precision (default par défaut). Le format peut être int ou float. La précision peut être l'une des suivantes : default (meilleure précision pour la plate-forme, généralement high sur ordinateur, medium sur mobile), low, medium, high.

Description

Répertorie les paramètres requis par votre support. Ces paramètres peuvent être définis au moment de l'exécution à l'aide de l'API Materialform de Sceneform. L'accès aux paramètres à partir des shaders varie selon le type de paramètre:

  • Types d'échantillons: utilisez le nom du paramètre précédé de materialParams_. Exemple : materialParams_myTexture.
  • Autres types : utilisez le nom du paramètre comme champ d'une structure appelée materialParams. Exemple : materialParams.myColor.
material {
    parameters : [
        {
           type : float4,
           name : albedo
        },
        {
           type      : sampler2d,
           format    : float,
           precision : high,
           name      : roughness
        },
        {
            type : float2,
            name : metallicReflectance
        }
    ],
    requires : [
        uv0
    ],
    shadingModel : lit,
}

fragment {
    void material(inout MaterialInputs material) {
        prepareMaterial(material);
        material.baseColor = materialParams.albedo;
        material.roughness = texture(materialParams_roughness, getUV0());
        material.metallic = materialParams.metallicReflectance.x;
        material.reflectance = materialParams.metallicReflectance.y;
    }
}

nécessite

Type
tableau de string
Value
Chaque entrée doit être uv0, uv1, color, tangents.
Description
Répertorie les attributs de sommet requis par le support. L'attribut position est automatiquement inclus et n'a pas besoin d'être spécifié. L'attribut tangents est automatiquement requis lorsque vous sélectionnez un modèle d'ombrage autre que unlit. Consultez les sections du nuanceur de ce document pour savoir comment accéder à ces attributs depuis les nuanceurs.
material {
    parameters : [
        {
           type : sampler2d,
           name : texture
        },
    ],
    requires : [
        uv0
    ],
    shadingModel : lit,
}

fragment {
    void material(inout MaterialInputs material) {
        prepareMaterial(material);
        material.baseColor = texture(materialParams_texture, getUV0());
    }
}

variables

Type
tableau de string
Value
Jusqu'à quatre chaînes, chacune doit être un identifiant GLSL valide.
Description
Définit des interpolants (ou variables) personnalisés générés par le nuanceur Material Ex. Chaque entrée du tableau définit le nom d'un interpolant. Le nom complet du nuanceur de fragment est le nom de l'interpolant avec le préfixe variable_. Par exemple, si vous déclarez une variable appelée eyeDirection, vous pouvez y accéder dans le nuanceur de fragment à l'aide de variable_eyeDirection. Dans le nuanceur Vertex, le nom interpolant est simplement un membre de la structure MaterialVertexInputs (material.eyeDirection dans votre exemple). Chaque interpolant est de type float4 (vec4) dans les nuanceurs.
material {
    name : Skybox,
    parameters : [
        {
           type : sampler2d,
           name : skybox
        }
    ],
    variables : [
         eyeDirection
    ],
    vertexDomain : device,
    depthWrite : false,
    shadingModel : unlit
}

fragment {
    void material(inout MaterialInputs material) {
        prepareMaterial(material);
        float theta = acos(variable_eyeDirection.y);
        float phi = atan(variable_eyeDirection.z / variable_eyeDirection.x) +
            (variable_eyeDirection.x > 0.0 ? 0.0 : PI);
        material.baseColor = texture(materialParams_skybox,
            vec2((phi + PI / 2.0) / (2.0 * PI), theta / PI));
    }
}

vertex {
    void materialVertex(inout MaterialVertexInputs material) {
        float3 p = getPosition().xyz;
        float3 u = mulMat4x4Float3(getViewFromClipMatrix(), p).xyz;
        material.eyeDirection.xyz = mulMat3x3Float3(getWorldFromViewMatrix(), u);
    }
}

combinaison

Type
string
Value
Les valeurs possibles : opaque, transparent, fade, add et masked. La valeur par défaut est opaque.
Description

Définit comment/si l'objet rendu est mélangé au contenu de la cible de rendu. Les modes de fusion possibles sont les suivants:

  • Opaque: la combinaison est désactivée. Le canal alpha de la sortie du support est ignoré.
  • Transparent : la combinaison est activée. La sortie du support est alphaisée avec la cible de rendu, à l'aide de la règle de source sur Porter-Duff. Ce mode de combinaison nécessite une version alpha prémultipliée.
  • Fondu : il joue le rôle de transparent, mais la transparence est également appliquée à l'éclairage spéculatif. En mode transparent, les valeurs alpha du Material ne s'appliquent qu'à la luminosité diffuse. Ce mode de fusion est utile pour effectuer un fondu entre les objets.
  • Ajouter: la combinaison est activée. La sortie du Material est ajoutée au contenu de la cible de rendu.
  • Masqué: la combinaison est désactivée. Ce mode de fusion permet le masquage alpha. Le canal alpha de la sortie du Material définit si un fragment est supprimé ou non. Consultez la section maskThreshold pour en savoir plus.
material {
    blending : transparent
}

VertexDomain

Type
string
Value
Valeurs possibles : object, world, view, device. La valeur par défaut est object.
Description

Définit le domaine (ou l'espace de coordonnées) du maillage affiché. Le domaine influence la transformation des sommets dans le nuanceur de sommet. Les domaines possibles sont les suivants:

  • Objet: les sommets sont définis dans l'espace de coordonnées de l'objet (ou du modèle). Les sommets sont transformés à l'aide de la matrice de transformation des objets rendus.
  • Monde : les sommets sont définis dans l'espace de coordonnées mondiales. Les sommets ne sont pas transformés à l'aide de la transformation de l'objet rendu.
  • Vue : les sommets sont définis dans l'espace de coordonnées de la vue (ou de l'œil ou de la caméra). Les sommets ne sont pas transformés à l'aide de la transformation de l'objet rendu.
  • Appareil : les sommets sont définis dans un espace de coordonnées normalisé d'un appareil (ou clip). Les sommets ne sont pas transformés à l'aide de la transformation de l'objet rendu.
material {
    vertexDomain : device
}

interpolation

Type
string
Value
N'importe lequel des smooth, flat. La valeur par défaut est smooth.
Description
Définit l'interpolation des interpolants (ou variables) entre les sommets. Lorsque cette propriété est définie sur smooth, une interpolation correcte en perspective est effectuée sur chaque interpolant. Lorsque ce paramètre est défini sur flat, aucune interpolation n'est effectuée et tous les fragments d'un triangle donné sont ombrés de la même manière.
material {
    interpolation : flat
}

Culling

Type
string
Value
Valeurs possibles : none, front, back, frontAndBack. La valeur par défaut est back.
Description
Définit les triangles à tronquer: aucun, à l'avant, à l'arrière ou à l'envers.
material {
    culling : none
}

Écriture couleur

Type
boolean
Value
true ou false. La valeur par défaut est true.
Description
Active ou désactive l'écriture dans le tampon de couleur.
material {
    colorWrite : false
}

écritureÉcriture

Type
boolean
Value
true ou false. La valeur par défaut est true.
Description
Active ou désactive l'écriture dans le tampon de profondeur.
material {
    depthWrite : false
}

Culture

Type
boolean
Value
true ou false. La valeur par défaut est true.
Description
Active ou désactive les tests de profondeur. Lorsque les tests de profondeur sont désactivés, un objet rendu avec ce matériau apparaît toujours au-dessus des autres objets opaques.
material {
    depthCulling : false
}

Recto verso

Type
boolean
Value
true ou false. La valeur par défaut est false.
Description
Active ou désactive l'affichage recto verso. Lorsque la valeur est true, culling est automatiquement défini sur none. Si le triangle est orienté vers l'arrière, le normal est automatiquement retourné pour devenir orienté vers l'avant.
material {
    doubleSided : true
}

transparence

Type
string
Value
default, twoPassesOneSide ou twoPassesTwoSides. La valeur par défaut est default.
Description
Contrôle l'affichage des objets transparents. Elle n'est valide que lorsque le mode blending n'est pas opaque. Aucune de ces méthodes ne peut effectuer un rendu précis de la géométrie concave, mais en pratique, elles sont souvent suffisamment performantes.

Voici les trois modes de transparence possibles:

  • default : l'objet transparent s'affiche normalement et respecte le mode culling.

  • twoPassesOneSide : l'objet transparent est d'abord affiché dans la tampon de profondeur, puis de nouveau dans la mémoire tampon de couleur, en respectant le mode cullling. De ce fait, seule la moitié de l'objet transparent s'affiche, comme illustré ci-dessous.

  • twoPassesTwoSides : l'objet transparent est affiché deux fois dans la mémoire tampon de couleur: d'abord avec ses faces arrières, puis avec ses faces avant. Ce mode vous permet d'afficher les deux ensembles de visages tout en réduisant ou en éliminant les problèmes de tri, comme indiqué ci-dessous. twoPassesTwoSides peut être associé à doubleSided pour un meilleur effet.

material {
    transparency : twoPassesOneSide
}

MaskThreshold (Seuil de masque)

Type
number
Value
Valeur comprise entre 0.0 et 1.0. La valeur par défaut est 0.4.
Description
Définit la valeur alpha minimale à laquelle un fragment ne doit pas être supprimé lorsque le mode blending est défini sur masked. Lorsque le mode de fusion n'est pas masked, cette valeur est ignorée. Cette valeur peut être utilisée pour contrôler l'apparition d'objets masqués en version alpha.
material {
    blending : masked,
    maskThreshold : 0.5
}

ShadowMultiplicateur

Type
boolean
Value
true ou false. La valeur par défaut est false.
Description
Disponible uniquement dans le modèle d'ombrage unlit. Si cette propriété est activée, la couleur finale calculée par le matériau est multipliée par le facteur d'ombre (ou visibilité). Cela permet de créer des objets transparents recevant des ombres (par exemple, un plan de sol invisible en RA).
material {
    name : "Invisible shadow plane",
    shadingModel : unlit,
    shadowMultiplier : true,
    blending : transparent
}

fragment {
    void material(inout MaterialInputs material) {
        prepareMaterial(material);
        // baseColor defines the color and opacity of the final shadow
        material.baseColor = vec4(0.0, 0.0, 0.0, 0.7);
    }
}

Variante de filtre

Type
tableau de string
Value
Chaque entrée doit être dynamicLighting, directionalLighting, shadowReceiver ou skinning.
Description
Permet de spécifier une liste de variantes du nuanceur dont l'application garantit qu'elles ne seront jamais nécessaires. Ces variantes du nuanceur sont ignorées pendant la phase de génération du code, ce qui réduit la taille globale du matériau. Notez que certaines variantes peuvent être automatiquement filtrées. Par exemple, toutes les variantes liées à l'éclairage (directionalLighting, etc.) sont filtrées lors de la compilation d'un matériau unlit. Utilisez le filtre de variante avec prudence, car le filtrage d'une variante requise au moment de l'exécution peut entraîner des plantages.

Description des variantes : directionalLighting, utilisé lorsqu'une lumière directionnelle est présente dans la scène, dynamicLighting, utilisé lorsqu'une lumière non directionnelle (point, point, etc.) est présente dans la scène, shadowReceiver, utilisé lorsqu'un objet peut recevoir des ombres, skinning lorsqu'un objet est animé à l'aide d'un habillage de GPU.

material {
    name : "Invisible shadow plane",
    shadingModel : unlit,
    shadowMultiplier : true,
    blending : transparent,
    variantFilter : [ skinning ]
}

Bloc Vertex

Le bloc Vertex est facultatif et peut être utilisé pour contrôler l'étape d'ombrage des sommets du matériau. Le bloc Vertex doit contenir un code ESSL 3.0 valide (version de GLSL compatible avec OpenGL ES 3.0). Vous êtes libre de créer plusieurs fonctions dans le bloc Vertex, mais vous devez déclarer la fonction materialVertex:

vertex {
    void materialVertex(inout MaterialVertexInputs material) {
        // vertex shading code
    }
}

Cette fonction est appelée automatiquement au moment de l'exécution par le système d'ombrage. Elle vous permet de lire et de modifier les propriétés de Material à l'aide de la structure MaterialVertexInputs. Vous trouverez cette définition complète de la structure dans la section Entrées de sommet Material.

Vous pouvez utiliser cette structure pour calculer vos variables/interpolants personnalisés ou pour modifier la valeur des attributs. Par exemple, les blocs de sommets suivants modifient à la fois la couleur et les coordonnées UV du sommet au fil du temps:

material {
    requires : [uv0, color]
}
vertex {
    void materialVertex(inout MaterialVertexInputs material) {
        material.color *= sin(getTime());
        material.uv0 *= sin(frameUniforms.time);
    }
}

Outre la structure MaterialVertexInputs, votre code d'ombrage par sommet peut utiliser toutes les API publiques répertoriées dans la section API publiques Shader.

Entrées Material Vertex

struct MaterialVertexInputs {
    float4 color;         // if the color attribute is required
    float2 uv0;           // if the uv0 attribute is required
    float2 uv1;           // if the uv1 attribute is required
    float3 worldNormal;   // only if the shading model is not unlit
    float4 worldPosition; // always available
    // variable* names are replaced with actual names
    float4 variable0;     // if 1 or more variables is defined
    float4 variable1;     // if 2 or more variables is defined
    float4 variable2;     // if 3 or more variables is defined
    float4 variable3;     // if 4 or more variables is defined
};

Bloc fragment

Le bloc de fragment doit être utilisé pour contrôler l'étape d'ombrage des fragments du matériau. Le bloc de fragment doit contenir un code ESSL 3.0 valide (version de GLSL compatible avec OpenGL ES 3.0). Vous êtes libre de créer plusieurs fonctions dans le bloc Vertex, mais vous devez déclarer la fonction material:

fragment {
    void material(inout MaterialInputs material) {
        prepareMaterial(material);
        // fragment shading code
    }
}

Cette fonction est appelée automatiquement au moment de l'exécution par le système d'ombrage. Elle vous permet de lire et de modifier les propriétés de Material à l'aide de la structure MaterialInputs. Cette définition complète se trouve dans la section des entrées de fragment Material. La définition complète des différents membres de la structure est disponible dans la section "Modèles Material" de ce document.

L'objectif de la fonction material() est de calculer les propriétés de matière spécifiques au modèle d'ombrage sélectionné. Par exemple, voici un bloc de fragment qui crée un métal rouge brillant à l'aide du modèle d'ombre éclairée standard:

fragment {
    void material(inout MaterialInputs material) {
        prepareMaterial(material);
        material.baseColor.rgb = vec3(1.0, 0.0, 0.0);
        material.metallic = 1.0;
        material.roughness = 0.0;
    }
}

Fonction préparerMaterial

Notez que vous devez appeler prepareMaterial(material) avant de quitter la fonction material(). Cette fonction prepareMaterial configure l'état interne du modèle Material. Certaines API décrites dans la section sur les API Fragment (comme shading_normal) ne sont accessibles qu'après avoir appelé prepareMaterial().

N'oubliez pas non plus que la propriété normal, décrite dans la section Entrées de fragment Material, n'a d'effet qu'en cas de modification avant d'appeler prepareMaterial(). Voici un exemple de nuanceur de fragment qui modifie correctement la propriété normal pour mettre en œuvre un plastique rouge brillant avec mappage des bosses:

fragment {
    void material(inout MaterialInputs material) {
        // fetch the normal in tangent space
        vec3 normal = texture(materialParams_normalMap, getUV0()).xyz;
        material.normal = normal * 2.0 - 1.0;

        // prepare the material
        prepareMaterial(material);

        // from now on, shading_normal, etc. can be accessed
        material.baseColor.rgb = vec3(1.0, 0.0, 0.0);
        material.metallic = 0.0;
        material.roughness = 1.0;
    }
}

Entrées de fragment Material

struct MaterialInputs {
    float4 baseColor;           // default: float4(1.0)
    float4 emissive;            // default: float4(0.0)

    // no other field is available with the unlit shading model
    float  roughness;           // default: 1.0
    float  metallic;            // default: 0.0, not available with cloth
    float  reflectance;         // default: 0.5, not available with cloth
    float  ambientOcclusion;    // default: 0.0

    // not available when the shading model is cloth
    float  clearCoat;           // default: 1.0
    float  clearCoatRoughness;  // default: 0.0
    float3 clearCoatNormal;     // default: float3(0.0, 0.0, 1.0)
    float  anisotropy;          // default: 0.0
    float3 anisotropyDirection; // default: float3(1.0, 0.0, 0.0)


    // only available when the shading model is cloth
    float3 sheenColor;         // default: sqrt(baseColor)
    float3 subsurfaceColor;    // default: float3(0.0)

    // not available when the shading model is unlit
    // must be set before calling prepareMaterial()
    float3 normal;             // default: float3(0.0, 0.0, 1.0)
}

API Shader Public

Types

Bien que les types GLSL puissent être utilisés directement (vec4 ou mat4), nous vous recommandons d'utiliser les alias de type suivants:

Nom Type GLSL Description
bool2 bvec2 Vecteur de 2 booléens
bool3 bvec3 Vecteur de 3 booléens
bool4 bvec4 Vecteur de 4 booléens
int2 Ivec2 Vecteur de 2 entiers
int3 Ivec3 Vecteur de 3 entiers
Int4 Ivec4 Vecteur de 4 entiers
uint2. UVEC2 Vecteur de 2 entiers non signés
uint3. uvec3 Vecteur de 3 entiers non signés
uint4 uvec4 Vecteur de 4 entiers non signés
float2 Nombre décimal 2 Vecteur de 2 floats
float3 Nombre décimal 3 Un vecteur de 3 floats
float4 Nombre décimal 4 Un vecteur de 4 nombres décimaux
float4x4, Mat4 Matrice flottante 4x4
float3x3. Mat 3 Une matrice flottante 3x3

Mathématiques

Nom Type Description
PI float Une constante qui représente \(\pi\)
HALF_PI float Une constante qui représente\(\frac{\pi}{2}\)
saturate(float x) float Fixe la valeur spécifiée entre 0,0 et 1,0
pow5(float x) float Calculs \(x^5\)
sq(float x) float Calculs \(x^2\)
max3(float3 v) float Renvoie la valeur maximale de l'élément float3 spécifié.
mulMat4x4Float3(float4x4 m, float3 v) Nombre décimal 4 Retours \(m * v\)
mulMat3x3Float3(float4x4 m, float3 v) Nombre décimal 4 Retours \(m * v\)

Matrices

Nom Type Description
getViewFromWorldMatrix() Flash transparent 4x4 Matrice qui se transforme d'un espace mondial à un espace d'affichage/œil
getWorldFromViewMatrix() Flash transparent 4x4 Matrice convertissant un espace de vue/œil en espace mondial
getClipFromViewMatrix() Flash transparent 4x4 Matrice de conversion de l'espace de vue/d'œil à l'espace d'extrait vidéo (NDC)
getViewFromClipMatrix() Flash transparent 4x4 Matrice convertissant un espace en NDC en espace de vue/œil
getClipFromWorldMatrix() Flash transparent 4x4 Matrice qui se transforme de l'espace terrestre à l'espace

Constantes de frame

Nom Type Description
getResolution(). Nombre décimal 4 Résolution de la vue en pixels : width, height, 1 / width, 1 / height
getWorldCameraPosition() Nombre décimal 3 Position de la caméra/de l'œil dans l'espace
getTime(). float Durée en secondes depuis l'initialisation du moteur Sceneform. Possibilité de la réinitialiser régulièrement pour éviter toute perte de précision.
getExposure(). float Exposition de la photo de l'appareil photo
getEV100() float Valeur d'exposition à ISO 100

Vertex uniquement

Les API suivantes ne sont disponibles qu'à partir du bloc Vertex:

Nom Type Description
getPosition() Nombre décimal 4 Position de Vertex dans le domaine défini par le support (par défaut : espace objet/modèle)
getWorldFromModelMatrix() Flash transparent 4x4 Matrice qui convertit un modèle (objet) en espace mondial
getWorldFromModelNormalMatrix() Flash transparent3x3 Matrice qui convertit les valeurs normales de l'espace (objet) en espace mondial

Fragment uniquement

Les API suivantes ne sont disponibles qu'à partir du bloc de fragment:

Nom Type Description
getWorldTangentFrame() Flash transparent3x3 Matrice contenant dans chaque colonne les valeurs tangent (frame[0]), bi-tangent (frame[1]) et normal (frame[2]) du verbe dans l'espace. Si le matériau ne calcule pas un espace tangente normal pour le mappage des bosses ou si l'ombrage n'est pas anisotrope, seule la valeur normal est valide dans cette matrice.
getWorldPosition(). Nombre décimal 3 Position du fragment dans l'espace mondial
getWorldViewVector() Nombre décimal 3 Vecteur normalisé dans l'espace mondial de la position du fragment à l'œil
getWorldNormalVector() Nombre décimal 3 Normalisé dans l'espace normal, après le mappage des bosses (doit être utilisé après prepareMaterial())
getWorldReflectedVector() Nombre décimal 3 Reflet du vecteur de vue par rapport à la norme (doit être utilisé après prepareMaterial()).
getNdotV(). float Le résultat de dot(normal, view), toujours strictement supérieur à 0 (doit être utilisé après prepareMaterial())
getColor() Nombre décimal 4 Couleur interpolée du fragment, si l'attribut de couleur est requis
getUV0(). Nombre décimal 2 Premier ensemble interpolé de coordonnées UV, si l'attribut uv0 est requis
getUV1(). Nombre décimal 2 Premier ensemble interpolé de coordonnées UV, si l'attribut uv1 est requis
inverseTonemap(float3) Nombre décimal 3 Applique l'opérateur de mise en correspondance des tons inverses à la couleur linéaire linéaire spécifiée. Cette opération peut être approximative
inverseTonemapSRGB(float3) Nombre décimal 3 Applique l'opérateur de mise en correspondance des tons inverses à la couleur sRGB non linéaire spécifiée. Cette opération peut être approximative
luminance(float3) float Calcule la luminance de la couleur sRGB linéaire spécifiée

Modèles Material

Les supports de scène peuvent utiliser l'un des modèles Material suivants:

  • Lit (ou standard)
  • Cloth
  • Éteinte

Modèle Lit

Le modèle éclairé est le modèle Material Standard de Sceneform. Ce modèle d'ombre physique a été conçu pour offrir une bonne interopérabilité avec d'autres outils et moteurs courants, tels que Unity 5, Unreal Engine 4, Substance Designer ou Marmoset Toolbag.

Ce modèle Material peut être utilisé pour décrire un grand nombre de surfaces non métalliques (diélectrique) ou de surfaces métalliques (conducteurs).

L'apparence d'un support à l'aide du modèle standard est contrôlée à l'aide des propriétés décrites dans le tableau ci-dessous.

Propriétés du modèle standard

Propriété Définition
baseColor Indice albédo pour les surfaces non métalliques et couleur spéculative pour les surfaces métalliques
métallique Indique si une surface semble diélectrique (0,0) ou conducteur (1,0). Souvent utilisé comme valeur binaire (0 ou 1)
rugosité Fluidité perçue (1,0) ou rugosité (0,0) de la surface. Les surfaces lisses présentent des reflets nets
de la réflexion Réflectance à la fresque à l'incidence normale pour les surfaces diélectriques. Cela permet de contrôler l'intensité des réflexions
clairCoat Intensité de la couche transparente
clearCoatRoughness La perception de la fluidité ou de la rugosité de la couche de couche transparente
anisotrope Quantité d'anisotropie dans la direction de la tangente ou du débit
AnisotropyDirection Direction de la surface locale
ambientOcclusion Définit la quantité de lumière ambiante accessible à un point de surface. Il s'agit d'un facteur d'ombre par pixel compris entre 0,0 et 1,0
normal Un détail normal utilisé pour bouleverser la surface à l'aide du mappage de bosses (mappage normale)
EffacerCoatNormal Un détail normal utilisé pour bouleverser la couche de couche transparente à l'aide de la mappage des bosses (mappage normale)
émission albédo diffuse supplémentaire pour simuler des surfaces émissives (comme des néons, etc.) Cette propriété est surtout utile dans un pipeline HDR doté d'un pass de fleurs

Le type et la plage de chaque propriété sont décrits dans le tableau ci-dessous.

Propriété Type Range Remarque
baseColor Nombre décimal 4 [0...1] RVB linéaire prémultiplié
métallique float [0...1] Doit être 0 ou 1
rugosité float [0...1]
de la réflexion float [0...1] Préférence pour les valeurs > 0.35
clairCoat float [0...1] Doit être 0 ou 1
clearCoatRoughness float [0...1] Nouveau mappage pour [0..0.6]
anisotrope float [-1 à 1] L'anatomie est dans la direction tangente lorsque cette valeur est positive
AnisotropyDirection Nombre décimal 3 [0...1] Le code RVB linéaire encode un vecteur de direction dans l'espace tangente
ambientOcclusion float [0...1]
normal Nombre décimal 3 [0...1] Le code RVB linéaire encode un vecteur de direction dans l'espace tangente
EffacerCoatNormal Nombre décimal 3 [0...1] Le code RVB linéaire encode un vecteur de direction dans l'espace tangente
émission Nombre décimal 4 rgb=[0..1], a=[-n..n] "alpha" représente la compensation de l'exposition

Couleur de la base

La propriété baseColor définit la couleur perçue d'un objet (parfois appelé albédo). L'effet de baseColor dépend de la nature de la surface, contrôlée par la propriété metallic expliquée dans la section Métallique.

Non métalliques (diélectrique)

Définit la couleur diffuse de la surface. Les valeurs réelles se trouvent généralement dans la plage [10..240] si la valeur est encodée entre 0 et 255 ou dans la plage [0.04..0.94] entre 0 et 1. Vous trouverez plusieurs exemples de couleurs de base pour les surfaces non métalliques dans le tableau ci-dessous.

Metal sRVB Hexadécimal Couleur
Charbon 0,19, 0,19, 0,19 #323232
 
De caoutchouc 0,21, 0,21, 0,21 #353535
 
Boue 0,33, 0,24, 0,19 #553d31
 
Wood 0,53, 0,36, 0,24 #875c3c
 
Végétation 0,48, 0,51, 0,31 #7b824e
 
Brick 0,58, 0,49, 0,46 #947d75
 
Sable 0,69, 0,66, 0,52 #b1a884
 
Concrete 0,75, 0,75, 0,73 #c0bfbb
 
Métaux (conducteurs)

Définit la couleur spéculative de la surface. Les valeurs réelles se trouvent généralement dans la plage [170..255] si la valeur est encodée entre 0 et 255 ou dans la plage [0.66..1.0] entre 0 et 1. Vous trouverez plusieurs exemples de couleurs de base pour les surfaces métalliques dans le tableau ci-dessous.

Metal sRVB Hexadécimal Couleur
Noir et blanc 0,98, 0,98, 0,96 #faf9f5
 
Aluminium 0,96, 0,96, 0,96 #f4f5f5
 
Titanium 0,81, 0,78, 0,76 #cec8c2
 
Fer 0,76, 0,74, 0,73 #c0bdba
 
Platinum 0,84, 0,82, 0,79 #d6d1c8
 
Gold 1,00, 0,87, 0,62 #fedc9d
 
Laiton 0,96, 0,89, 0,68 #f4e4ad
 
Cuivre 0,98, 0,85, 0,72 #fbd8b8
 

Métallique

La propriété metallic définit si la surface est une surface métallique (conducteur) ou non métallique (diélectrique). Cette propriété doit être utilisée comme valeur binaire, définie sur 0 ou 1. Les valeurs intermédiaires ne sont vraiment utiles que pour créer des transitions entre différents types de surfaces lorsque vous utilisez des textures.

Cette propriété peut modifier considérablement l'apparence d'une surface. Les surfaces non métallisées présentent une réflexion diffuse chromatique et une réflexion spéculative achromatique (la lumière réfléchie ne change pas de couleur). Les surfaces métalliques ne présentent aucune réflexion différenciée ni réflexion chromatique (la lumière reflétée reflète la couleur de la surface telle que définie par baseColor).

L'effet de metallic est illustré ci-dessous (cliquez sur l'image pour afficher une version plus grande).

Rugosité

La propriété roughness contrôle la régularité perçue de la surface. Lorsque roughness est défini sur 0, la surface est parfaitement lisse et extrêmement brillante. Plus la surface est nette, plus le reflet est net. Cette propriété est souvent appelée brillance dans d'autres moteurs et outils, et est l'opposé de la rugosité (roughness = 1 - glossiness).

Non métalliques

L'effet de roughness sur les surfaces non métalliques est illustré ci-dessous (cliquez sur l'image pour afficher une version plus grande).

Métaux

L'effet de roughness sur les surfaces métalliques est illustré ci-dessous (cliquez sur l'image pour afficher une version plus grande).

Réflexion

La propriété reflectance n'affecte que les surfaces non métalliques. Cette propriété peut être utilisée pour contrôler l'intensité spéculative. Cette valeur est définie entre 0 et 1 et représente un remappage d'un pourcentage de réflectance. Par exemple, la valeur par défaut de 0,5 correspond à un reflet de 4%. Les valeurs inférieures à 0,35 (la réflectance de 2 %) doivent être évitées, car aucun matériau réel ne présente une si faible réflexion.

L'effet de reflectance sur les surfaces non métalliques est illustré ci-dessous (cliquez sur l'image pour afficher une version plus grande).

Le graphique ci-dessous montre les valeurs courantes et leur relation avec la fonction de mappage.

Le tableau ci-dessous décrit les valeurs de réflectance acceptables pour différents types de matériaux (une valeur réelle inférieure à 2 % n'est indiquée pour un matériau réel).

Matériau Réflexion Valeur de propriété
Eau 2 % 0.35
Tissu 4% à 5,6% 0,5 à 0,59
Liquides courants 2% à 4% 0,35 à 0,5
Pierres précieuses courantes 5 à 16 % 0,56 à 1,0
Plastique, verre 4% à 5% 0,5 à 0,56
Autres matériaux diélectriques 2% à 5% 0,35 à 0,56
Yeux 2,5 % 0,39
Peau 2,8% 0,42
Coiffure 4,6 % 0,54
Les dents 5,8% 0,6
Valeur par défaut 4 % 0.5

Vernis transparent

Les matériaux à plusieurs couches sont assez courants, en particulier les matériaux avec une couche translucide fine sur une couche de base. Ces peintures peuvent être des peintures, des canettes à soda, des bois laqués et de l'acrylique, par exemple.

La propriété clearCoat permet de décrire des matériaux à deux couches. La couche transparente sera toujours isotrope et diélectrique. L'image ci-dessous compare un matériau en fibre de carbone issu du modèle Material standard (à gauche) et celui du revêtement transparent (à droite).

La propriété clearCoat contrôle l'intensité de la couche transparente. Il doit être traité comme une valeur binaire définie sur 0 ou 1. Les valeurs intermédiaires sont utiles pour contrôler les transitions entre des parties de la surface présentant des couches de couche transparentes et des parties non dénudées.

L'effet de clearCoat sur un gros métal est illustré ci-dessous (cliquez sur l'image pour en afficher une version plus grande).

Effacer la rugosité du manteau

La propriété clearCoatRoughness est semblable à la propriété roughness, mais ne s'applique qu'à la couche transparente. De plus, comme les couches transparentes ne sont jamais complètement rugueuses, la valeur comprise entre 0 et 1 est reconstituée en interne avec une rugosité réelle comprise entre 0 et 0,6.

L'effet de clearCoatRoughness sur un métal brut est illustré ci-dessous (cliquez sur l'image pour afficher une version plus grande).

Anisotropie

De nombreux matériaux réels, tels que le métal brossé, ne peuvent être reproduits qu'à l'aide d'un modèle de réflectance anisotrope. Un matériau peut passer du modèle isotrope par défaut à un modèle anisotrope à l'aide de la propriété anisotropy. L'image suivante compare un matériau isotrope (à gauche) et un matériau anistropic (à droite).

L'effet d'une variation de anisotropy de 0,0 (gauche) à 1,0 (droite) sur un métal brut est illustré ci-dessous (cliquez sur l'image pour afficher une version plus grande).

L'image ci-dessous montre comment contrôler la direction des tons clairs anisotropes en utilisant des valeurs positives ou négatives: les valeurs positives (gauche) définissent l'anisotropie dans la direction tangente et les valeurs négatives (à droite) dans la direction des bits.

Direction de l'anisotropie

La propriété anisotropyDirection définit la direction de la surface à un point donné et contrôle donc la forme des tons clairs spéculaires. Il est spécifié sous forme de vecteur de 3 valeurs provenant généralement d'une texture, codant les itinéraires locaux jusqu'à la surface.

L'effet du rendu anisotropyDirection sur un métal avec une carte de direction est illustré ci-dessous (cliquez sur l'image pour en afficher une version plus grande).

La carte de direction utilisée pour afficher l'image ci-dessus est indiquée ci-dessous.

Occlusion ambiante

La propriété ambientOcclusion définit dans quelle mesure la lumière ambiante est accessible à un point de surface. Il s'agit d'un facteur d'ombre par pixel compris entre 0 (totalement bloqué) et 1 (totalement éclairé). Cette propriété n'affecte que la lumière indirecte (éclairage basé sur une image). Elle ne s'applique pas aux lumières directes comme les lumières directionnelles, à point et à lumière, ni aux lumières spéculaires. L'image suivante compare des matériaux sans occlusion ambiante de l'environnement (gauche) et avec elle (droite).

Normal

La propriété normal définit la normale de la surface à un point donné. Elle provient généralement d'une texture de carte normale, ce qui permet de faire varier la propriété par pixel. La normale est fournie dans l'espace tangente, ce qui signifie que les +Z pointent en dehors de la surface.

Par exemple, imaginons que nous voulions afficher un meuble recouvert de cuir capitonné. La modélisation de la géométrie pour représenter avec précision le motif capitonné nécessiterait un trop grand nombre de triangles. Nous allons donc recouper plutôt un réseau maillé avec un polygone élevé dans une carte normale. Vous pouvez ensuite appliquer la carte de base à un maillage simplifié. L'image suivante compare un réseau maillé simple sans mappage normal (gauche) et avec celui-ci (droite).

Notez que la propriété normal affecte la couche de base, et non la couche transparente.

Couche transparente

La propriété clearCoatNormal définit la normale de la couche manteau transparent à un point donné. Il se comporte comme la propriété normal.

Émissive

La propriété emissive peut être utilisée pour simuler une lumière supplémentaire émise par la surface. Il est défini comme une valeur float4 contenant une couleur RVB (dans l'espace linéaire) et une valeur de compensation d'exposition (dans le canal alpha).

Bien qu'une valeur d'exposition indique en réalité des combinaisons de paramètres d'appareil photo, elle est souvent utilisée par les photographes pour décrire l'intensité de la lumière. C'est pourquoi les appareils photo permettent aux photographes d'appliquer une compensation d'exposition à une image par-dessus ou sous-exposant. Ce paramètre peut être utilisé à des fins artistiques, mais aussi pour assurer une exposition appropriée (par exemple, 18 % de la gris clair sera exposé à la neige).

La valeur de compensation d'exposition de la propriété émissive peut être utilisée pour forcer la couleur émissive à être plus lumineuse (valeurs positives) ou plus sombre (valeurs négatives) que l'exposition actuelle. Si l'effet de floraison est activé, l'utilisation d'une compensation d'exposition positive peut forcer l'épanouissement de la surface.

Modèle en tissu

Tous les modèles Material décrits précédemment sont conçus pour simuler des surfaces denses à la fois à une macro et à un niveau micro. Les vêtements et les tissus sont toutefois souvent constitués de fils desserrés qui absorbent et diffusent la lumière de l'incident. Par rapport aux surfaces dures, le tissu est caractérisé par un lobe spéculaire plus mou, avec un grand retombée et la présence d'un éclairage flou. Ce phénomène est dû à la dispersion avant/arrière. Certains tissus présentent également des couleurs spéculaires bicolores (velours, par exemple).

L'image suivante compare le tissu en jean affiché à l'aide du modèle standard (à gauche) et du modèle en tissu (à droite). Notez que le modèle Material Design standard ne parvient pas à capturer l'apparence d'un échantillon de tissu en jean (à gauche). La surface semble rigide (presque en plastique), semblable à une bâche plutôt qu'à un vêtement. Cela démontre également l'importance du lobe spéculaire plus doux causé par l'absorption et la dispersion dans la reconstitution fidèle du tissu.

Le velours est un cas d'utilisation intéressant pour un modèle en tissu. Comme illustré dans l'image ci-dessous, ce type de tissu présente un fort éclairage de la jante en raison de la dispersion avant et arrière. Ces événements de dispersion sont dus à l'utilisation de fibres debout directement à la surface du tissu. Lorsque la lumière d'incident provient de la direction opposée à la direction de la vue, les fibres diffusent la lumière. De même, lorsque la lumière d'incident provient de la même direction que la direction de la vue, les fibres diffusent la lumière vers l'arrière.

Il est important de noter que certains types de tissus sont encore mieux modélisés par des modèles de matière dure. Par exemple, le cuir, la soie et le satin peuvent être recréés à l'aide des modèles de matériaux standards ou anisotropes.

Le modèle "matière" inclut tous les paramètres précédemment définis pour le mode "matière standard", à l'exception de metallic et reflectance. Deux paramètres supplémentaires décrits dans le tableau ci-dessous sont également disponibles.

Paramètre Définition
teinte colorée Teinte spéculaire pour créer des tissus spéculaires bicolores (par défaut : \(\sqrt{baseColor}\))
subsurfaceColor Teinte pour la couleur diffuse après la diffusion et l'absorption du matériau

Le type et la plage de chaque propriété sont décrits dans le tableau ci-dessous.

Propriété Type Range Remarque
teinte colorée Nombre décimal 3 [0...1] RVB linéaire
subsurfaceColor Nombre décimal 3 [0...1] RVB linéaire

Pour créer un matériau de type velours, la couleur de base peut être définie sur noir (ou sur une couleur sombre). Les informations de chromaticité doivent plutôt être définies sur la couleur éclatante. Pour créer des tissus plus courants tels que le jean, le coton, etc., choisissez la couleur de base pour la chromaticité. Utilisez la couleur de teinte par défaut ou définissez la nuance de couleur sur la luminosité de la couleur de la base.

Couleur de l'éclat

La propriété sheenColor peut être utilisée pour modifier directement la réflectance spéculaire. Il permet de mieux contrôler l'apparence des tissus et de créer des matériaux bicolores.

L'image suivante compare le tissu bleu avec et sans (gauche) et avec un éclat transparent (cliquez sur l'image pour voir une version plus grande).

Couleur de la surface

La propriété subsurfaceColor n'est pas basée sur l'état physique et peut être utilisée pour simuler la dispersion, l'absorption partielle et la réémission de lumière dans certains types de tissus. Cela est particulièrement utile pour créer des tissus plus doux.

L'image suivante illustre l'effet de subsurfaceColor. Elle représente un chiffon blanc (colonne de gauche) par rapport à un chiffon blanc avec nuage de points bruns (colonne de droite). Cliquez sur l'image pour l'agrandir.

Modèle non éclairé

Ce modèle peut être utilisé pour désactiver tous les calculs d'éclairage. Son objectif principal est d'afficher des éléments pré-éclairés tels qu'un cube, du contenu externe (tel qu'un flux vidéo ou d'appareil photo), des interfaces utilisateur, la visualisation/le débogage, etc. Le modèle non éclairé n'expose que deux des propriétés décrites dans le tableau ci-dessous.

Propriété Définition
baseColor Couleur diffuse de la surface
émission Couleur diffuse supplémentaire pour simuler des surfaces à émission. Cette propriété est principalement utile dans un pipeline HDR doté d'un pas de fleuriste

Le type et la plage de chaque propriété sont décrits dans le tableau ci-dessous.

Propriété Type Range Remarque
baseColor Nombre décimal 4 [0...1] RVB linéaire prémultiplié
émission Nombre décimal 4 rgb=[0..1], a=N/A RVB linéaire pré-multiplié, version alpha ignorée

La valeur emissive est simplement ajoutée à baseColor lorsqu'elle est présente. L'utilisation principale de emissive consiste à forcer l'émergence d'une surface non éclairée si le pipeline HDR est configuré avec une carte bloom.

L'image suivante montre un exemple du modèle Material Unliter utilisé pour le rendu des informations de débogage (cliquez sur l'image pour en afficher une version plus grande).

Gérer les couleurs

Couleurs linéaires

Si les données de couleur proviennent d'une texture, assurez-vous simplement d'utiliser une texture sRVB pour bénéficier de la conversion matérielle automatique du format sRVB au format linéaire. Si les données de couleur sont transmises en tant que paramètre au matériau que vous pouvez convertir de sRVB à linéaire, exécutez l'algorithme suivant sur chaque canal de couleur:

float sRGB_to_linear(float color) {
    return color <= 0.04045 ? color / 12.92 : pow((color + 0.055) / 1.055, 2.4);
}

Vous pouvez également utiliser l'une des deux versions moins chères, mais moins précises présentées ci-dessous:

// Cheaper
linearColor = pow(color, 2.2);
// Cheapest
linearColor = color * color;

Valeurs alpha pré-multipliées

Une couleur utilise un alpha pré-multiplié si ses composants RVB sont multipliés par le canal alpha:

// Compute pre-multiplied color
color.rgb *= color.a;

Si la couleur est échantillonnée à partir d'une texture, vous pouvez simplement vous assurer que les données de texture sont prémultipliées à l'avance. Sur Android, toute texture importée à partir d'un Bitmap est prémultipliée par défaut.