Sceneform fornisce definizioni di materiali predefinite (.sfm
) per consentire agli sviluppatori di ottenere facilmente ottimi risultati. Gli sviluppatori che vogliono personalizzare l'aspetto dei propri asset possono creare le proprie definizioni di materiali (*.mat
) e applicarle ai propri asset specificando l'attributo source
nella definizione degli asset.
Concetti fondamentali
- Materiale
- Un materiale definisce l'aspetto visivo di una superficie. Per descrivere e visualizzare completamente una superficie, un materiale fornisce le seguenti informazioni:
- Modello del materiale
- Insieme di parametri denominati controllabili dall'uso
- Stato raster (modalità di fusione, attenuazione del backface ecc.)
- Codice Vertex Shar
- Codice shader frammento
- Modello del materiale
- Chiamato anche modello di ombreggiatura o modello di illuminazione, il modello di materiale definisce le proprietà intrinseche di una superficie. Queste proprietà hanno un'influenza diretta sul modo in cui vengono calcolate le luci e quindi sull'aspetto di una superficie.
- Definizione del materiale
- Un file di testo che descrive tutte le informazioni richieste da un materiale. In questa pagina vengono descritti la struttura e il formato dei file di definizione del materiale (
*.mat
).
Definizioni dei materiali
Una definizione di materiale è un file di testo che descrive tutte le informazioni richieste da un materiale:
- Nome
- Parametri utente
- Modello del materiale
- Attributi obbligatori
- Interpolanti (chiamati variabili)
- Stato raster (modalità di fusione ecc.)
- Codice Shader (ombreggiatore di frammento, eventualmente criterio vertex)
Formato
Il formato della definizione del materiale è un formato liberamente basato su JSON che chiamiamo JSONish. Al livello principale, una definizione di materiale è composta da tre diversi blocchi che utilizzano la notazione oggetto JSON:
material {
// material properties
}
vertex {
// vertex shader, optional
}
fragment {
// fragment shader
}
Una definizione di materiale minimo funzionante deve contenere un blocco material
e un blocco fragment
. Il blocco vertex
è facoltativo.
Differenze con JSON
In formato JSON, un oggetto è costituito da coppie chiave/valore. Una coppia JSON presenta la seguente sintassi:
"key" : value
Dove il valore può essere una stringa, un numero, un oggetto, un array o un valore letterale (true
, false
o null
). Sebbene questa sintassi sia perfettamente valida in una definizione di materiale, una
variante senza virgolette attorno alle stringhe è accettata anche in formato JSON:
key : value
Le virgolette rimangono obbligatorie se la stringa contiene spazi.
I blocchi vertex
e fragment
contengono codice GLSL senza caratteri di escape, che non è valido in formato JSON.
Sono consentiti commenti di stile C++ su una riga.
La chiave di una coppia è sensibile alle maiuscole.
Il valore di una coppia non è sensibile alle maiuscole.
Esempio
Il seguente elenco di codice mostra un esempio di definizione di materiale valida. Questa definizione utilizza il modello di materiale lit, utilizza la modalità di fusione opaca predefinita, richiede che un insieme di coordinate UV sia presente nel mesh di cui è stato eseguito il rendering e definisce 3 parametri utente. Le seguenti sezioni di questo documento descrivono in dettaglio i blocchi material
e fragment
.
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;
}
}
Blocco di materiale
Il blocco di materiali è un blocco obbligatorio contenente un elenco di coppie di proprietà per descrivere tutti i dati non Shader.
name
- Tipo
string
- Valore
- Qualsiasi stringa. Se il nome contiene spazi, sono necessarie virgolette doppie.
- Descrizione
- Imposta il nome del materiale. Il nome viene conservato in fase di runtime per scopi di debug.
material {
name : stone
}
material {
name : "Wet pavement"
}
shadingModel
- Tipo
string
- Valore
lit
,cloth
,unlit
. Il valore predefinito èlit
.- Descrizione
- Seleziona il modello di materiale come descritto nella sezione Modelli di materiale.
material {
shadingModel : unlit
}
Parametri
- Tipo
- array di oggetti parametro
- Valore
Ogni voce è un oggetto con le proprietà
name
etype
, entrambe di tipostring
. Il nome deve essere un identificatore GLSL valido. Il tipo deve essere di uno dei tipi descritti nella seguente tabella.Tipo Descrizione bool Singolo booleano bool2 Vettore di 2 booleani bool3 Vettore di 3 booleani bool4 Vettore di 4 booleani numero in virgola mobile Numero in virgola mobile numero in virgola mobile 2 Vettore di 2 floating fluttuare3 Vettore di 3 floating fluttuare4 Vettore di 4 floating int Numero intero singolo int2 Vettore di 2 numeri interi int3 Vettore di 3 numeri interi int4 Vettore di 4 numeri interi campionatore2d Trama 2D campionatoreEsterno Trama esterna. Per scoprire di più, consulta ExternalTexture e setExternalTexture() - Campionatori
I tipi di anteprime possono anche specificare un valore
format
(il valore predefinito èfloat
) e un valoreprecision
(il valore predefinito èdefault
). Il formato può essere uno traint
,float
. Il livello di precisione può esseredefault
(migliore per la piattaforma, in generehigh
su computer desktop,medium
su dispositivo mobile),low
,medium
,high
.- Descrizione
Elenca i parametri richiesti dal tuo materiale. Questi parametri possono essere impostati in fase di esecuzione utilizzando l'API Material Sceneform. L'accesso ai parametri dagli Shader varia in base al tipo di parametro:
- Tipi di anteprime: utilizza il nome del parametro preceduto da
materialParams_
. Ad esempio,materialParams_myTexture
. - Altri tipi: utilizza il nome del parametro come campo di una struttura denominata
materialParams
. Ad esempio,materialParams.myColor
.
- Tipi di anteprime: utilizza il nome del parametro preceduto da
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;
}
}
richiede
- Tipo
- array di
string
- Valore
- Ogni voce deve essere di
uv0
,uv1
,color
,tangents
. - Descrizione
- Elenca gli attributi del vertice richiesti dal materiale. L'attributo
position
viene incluso automaticamente e non deve essere specificato. L'attributotangents
è obbligatorio automaticamente quando si seleziona un modello di ombreggiatura diverso daunlit
. Consulta le sezioni degli shader in questo documento per ulteriori informazioni su come accedere a questi attributi dagli shader.
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
- Tipo
- array di
string
- Valore
- Fino a 4 stringhe, ciascuna deve essere un identificatore GLSL valido.
- Descrizione
- Definisce interpolanti personalizzati (o variabili) generati dallo shader del vertice del materiale. Ogni voce dell'array definisce il nome di un interpolante.
Il nome completo nello shader del frammento è il nome dell'interpolante con il prefisso
variable_
. Ad esempio, se dichiari una variabile denominataeyeDirection
, puoi accedervi nello shader del frammento utilizzandovariable_eyeDirection
. Nello shader vertice, il nome dell'interpolante è semplicemente un membro della strutturaMaterialVertexInputs
(material.eyeDirection
nel tuo esempio). Ogni interpolante è di tipofloat4
(vec4
) negli shader.
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);
}
}
unione
- Tipo
string
- Valore
opaque
,transparent
,fade
,add
,masked
. Il valore predefinito èopaque
.- Descrizione
Definisce come e se l'oggetto sottoposto a rendering viene unito ai contenuti del target di rendering. Le possibili modalità di fusione sono:
- Opaca: l'unione è disattivata, il canale alfa dell'output del materiale viene ignorato.
- Trasparente: l'unione è attivata. L'output del materiale è alpha composto con la destinazione di rendering, utilizzando la regola source over di Porter-Duff. Questa modalità di fusione presuppone una versione alpha moltiplicata.
- Dissolvenza: agisce come
transparent
, ma la trasparenza viene applicata anche all'illuminazione speculare. In modalitàtransparent
, i valori alfa del materiale si applicano solo all'illuminazione diffusa. Questa modalità di fusione è utile per sfumare gli oggetti illuminati all'interno e all'esterno. - Aggiungi: l'unione è attivata. L'output del materiale viene aggiunto ai contenuti della destinazione di rendering.
- Masked (Mascherata): l'unione è disabilitata. Questa modalità di fusione consente il mascheramento alfa. Il canale alfa dell'output del materiale definisce se un frammento viene eliminato o meno. Per ulteriori informazioni, consulta la sezione maskThreshold.
material {
blending : transparent
}
Dominioex
- Tipo
string
- Valore
object
,world
,view
,device
. Il valore predefinito èobject
.- Descrizione
Definisce il dominio (o spazio di coordinazione) del mesh sottoposto a rendering. Il dominio influenza la modalità di trasformazione dei vertici nel filtro di vertice. I domini possibili sono:
- Oggetto: i vertici sono definiti nello spazio di coordinate dell'oggetto (o del modello). I vertici vengono trasformati utilizzando la matrice di trasformazione dell'oggetto sottoposto a rendering
- Mondo: i vertici sono definiti nello spazio di coordinate globali. I vertici non vengono trasformati mediante la trasformazione dell'oggetto sottoposto a rendering.
- Vista: i vertici sono definiti nello spazio di coordinate della vista (o dell'occhio o della fotocamera). I vertici non vengono trasformati mediante la trasformazione dell'oggetto sottoposto a rendering.
- Dispositivo: i vertici sono definiti nello spazio di coordinate del dispositivo (o clip) normalizzato. I vertici non vengono trasformati mediante la trasformazione dell'oggetto sottoposto a rendering.
material {
vertexDomain : device
}
interpolazione
- Tipo
string
- Valore
smooth
suflat
. Il valore predefinito èsmooth
.- Descrizione
- Definisce come le interpolazioni (o le variabili) vengono interpolate tra i vertici.
Quando questa proprietà è impostata su
smooth
, viene eseguita un'interpolazione corretta da una prospettiva. Se viene impostato suflat
, non viene eseguita alcuna interpolazione e tutti i frammenti all'interno di un determinato triangolo vengono ombreggiati allo stesso modo.
material {
interpolation : flat
}
CANNOT TRANSLATE
- Tipo
string
- Valore
none
,front
,back
,frontAndBack
. Il valore predefinito èback
.- Descrizione
- Definisce i triangoli che devono essere tagliati: nessuno, triangoli frontali, triangoli posteriori o tutti.
material {
culling : none
}
coloreScrittura
- Tipo
boolean
- Valore
true
ofalse
. Il valore predefinito ètrue
.- Descrizione
- Abilita o disabilita le scritture nel buffer di colori.
material {
colorWrite : false
}
DepthWrite
- Tipo
boolean
- Valore
true
ofalse
. Il valore predefinito ètrue
.- Descrizione
- Abilita o disabilita le scritture nel buffer di profondità.
material {
depthWrite : false
}
Approfondimento
- Tipo
boolean
- Valore
true
ofalse
. Il valore predefinito ètrue
.- Descrizione
- Abilita o disabilita i test di profondità. Quando il test di profondità è disabilitato, un oggetto sottoposto a rendering con questo materiale verrà sempre visualizzato sopra gli altri oggetti opachi.
material {
depthCulling : false
}
Fronte/retro
- Tipo
boolean
- Valore
true
ofalse
. Il valore predefinito èfalse
.- Descrizione
- Abilita o disabilita il rendering fronte/retro. Se impostato su
true
,culling
viene impostato automaticamente sunone
; se il triangolo è rivolto verso il basso, il normale aspetto del triangolo viene capovolto automaticamente.
material {
doubleSided : true
}
trasparenza
- Tipo
string
- Valore
default
,twoPassesOneSide
otwoPassesTwoSides
. Il valore predefinito èdefault
.- Descrizione
- Controlla come vengono visualizzati gli oggetti trasparenti. È valido solo quando la modalità
blending
non èopaque
. Nessuno di questi metodi è in grado di mostrare con precisione la geometria concisa, ma in pratica sono abbastanza buoni.
Le tre modalità di trasparenza possibili sono:
default
: l'oggetto trasparente viene visualizzato normalmente, in base alla modalitàculling
e così via.twoPassesOneSide
: l'oggetto trasparente viene prima visualizzato nel buffer di profondità, quindi di nuovo nel buffer di colore, in modo da rispettare la modalitàcullling
. In questo modo viene effettivamente visualizzato solo la metà dell'oggetto trasparente come mostrato di seguito.twoPassesTwoSides
: l'oggetto trasparente viene mostrato due volte nel buffer di colore: prima con i visi posteriori, poi con i volti anteriori. Questa modalità ti consente di visualizzare entrambi gli insiemi di volti riducendo o eliminando i problemi di ordinamento, come mostrato di seguito.twoPassesTwoSides
può essere combinato condoubleSided
per un effetto migliore.
material {
transparency : twoPassesOneSide
}
Soglia maschera
- Tipo
number
- Valore
- Un valore compreso tra
0.0
e1.0
. Il valore predefinito è0.4
. - Descrizione
- Imposta il valore alfa minimo che un frammento deve avere da eliminare quando
la modalità
blending
è impostata sumasked
. Quando la modalità di fusione non èmasked
, questo valore viene ignorato. Questo valore può essere utilizzato per controllare l'aspetto degli oggetti con maschera alpha.
material {
blending : masked,
maskThreshold : 0.5
}
ShadowMoltiplicatore
- Tipo
boolean
- Valore
true
ofalse
. Il valore predefinito èfalse
.- Descrizione
- Disponibile solo nel modello di ombreggiatura
unlit
. Se questa proprietà è abilitata, il colore finale calcolato dal materiale viene moltiplicato per il fattore di shadowing (o visibilità). Questo consente di creare oggetti trasparente di ricezione d'ombra (ad esempio un piano di base invisibile in AR).
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);
}
}
varianteFilter
- Tipo
- array di
string
- Valore
- Ogni voce deve essere di
dynamicLighting
,directionalLighting
,shadowReceiver
oskinning
. - Descrizione
- Utilizzato per specificare un elenco di varianti di shader che l'applicazione garantisce
non sarà mai necessaria. Queste varianti di shader vengono ignorate durante la fase di generazione del codice, riducendo così le dimensioni complessive del materiale. Tieni presente che alcune varianti potrebbero essere filtrate automaticamente. Ad esempio, tutte le varianti relative all'illuminazione (
directionalLighting
e così via) vengono filtrate durante la compilazione di un materialeunlit
. Utilizza il filtro delle varianti con cautela, filtrando la variante richiesta in fase di runtime potrebbe verificarsi un arresto anomalo.
Descrizione delle varianti: - directionalLighting
, utilizzata quando è presente una luce
direzionale nella scena - dynamicLighting
, utilizzata quando nella scena è presente una luce
non direzionale (punto, spot e così via) - shadowReceiver
, utilizzata quando
un oggetto può ricevere ombre -skinning
, utilizzata quando un oggetto è animato mediante
sfogliamento GPU
material {
name : "Invisible shadow plane",
shadingModel : unlit,
shadowMultiplier : true,
blending : transparent,
variantFilter : [ skinning ]
}
Blocco Vertex
Il blocco dei vertici è facoltativo e può essere utilizzato per controllare la fase di ombreggiatura dei vertici del materiale. Il blocco vertice deve contenere un codice ESSL 3.0 valido (la versione di GLSL supportata in OpenGL ES 3.0). Puoi creare più funzioni all'interno del blocco di vertici, ma devi dichiarare la funzione materialVertex
:
vertex {
void materialVertex(inout MaterialVertexInputs material) {
// vertex shading code
}
}
Questa funzione verrà richiamata automaticamente durante il runtime dal sistema di ombreggiatura e ti dà la possibilità di leggere e modificare le proprietà dei materiali utilizzando la struttura di MaterialVertexInputs
. Questa definizione completa della struttura è
disponibile nella sezione Input vertice materiale.
Puoi utilizzare questa struttura per calcolare le variabili/interpolanti personalizzati o per modificare il valore degli attributi. Ad esempio, i seguenti vertice modificano sia il colore che le coordinate UV del vertice nel tempo:
material {
requires : [uv0, color]
}
vertex {
void materialVertex(inout MaterialVertexInputs material) {
material.color *= sin(getTime());
material.uv0 *= sin(frameUniforms.time);
}
}
Oltre alla struttura MaterialVertexInputs
, il codice di ombreggiatura dei vertici può utilizzare tutte le API pubbliche elencate nella sezione Shader public APIs (API pubbliche Shader).
Input del vertice del materiale
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
};
Blocco di frammenti
Il blocco di frammenti deve essere utilizzato per controllare la fase di ombreggiatura dei frammenti del materiale. Il blocco di frammenti deve contenere un codice ESSL 3.0 valido (la versione di GLSL supportata in OpenGL ES 3.0). Puoi creare più funzioni all'interno del blocco di vertici, ma devi dichiarare la funzione material
:
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
// fragment shading code
}
}
Questa funzione verrà richiamata automaticamente durante il runtime dal sistema di ombreggiatura e ti dà la possibilità di leggere e modificare le proprietà dei materiali utilizzando la struttura di MaterialInputs
. Questa definizione completa della struttura è disponibile nella sezione Input di frammenti di materiale. La definizione completa dei vari membri della struttura è disponibile nella sezione dei modelli materiali di questo documento.
L'obiettivo della funzione material()
è calcolare le proprietà del materiale specifiche per il modello di ombreggiatura selezionato. Ad esempio, ecco un blocco di frammenti che crea un metallo rosso lucido utilizzando il modello di ombreggiatura illuminato 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;
}
}
funzione preparazioneMaterial
Tieni presente che devi chiamare prepareMaterial(material)
prima di uscire dalla funzione material()
. Questa funzione prepareMaterial
configura lo stato interno del modello di materiale. Alcune API descritte nella sezione delle API di frammenti, come ad esempio shading_normal
, sono accessibili solo dopo la chiamata a prepareMaterial()
.
È importante inoltre ricordare che la proprietà normal
, come descritto nella sezione Input di frammenti di materiale, ha effetto solo quando viene modificata prima di chiamare prepareMaterial()
. Ecco un esempio di
shader con frammenti che modifica correttamente la proprietà normal
per implementare una
plastica rossa lucida con mappatura a contatto:
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;
}
}
Input di frammenti di materiale
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 pubbliche Shader
Tipi
Sebbene i tipi di GLSL possano essere utilizzati direttamente (vec4
o mat4
), consigliamo di utilizzare i seguenti alias di tipo:
Nome | Tipo GLSL | Descrizione |
---|---|---|
bool2 | bc2 | Un vettore di 2 booleani |
bool3 | bc3 | Un vettore di 3 booleani |
bool4 | bvec4 | Un vettore di 4 booleani |
int2 | Ivec2 | Un vettore di 2 numeri interi |
int3 | I3C | Un vettore di 3 numeri interi |
int4 | Ivec4 | Un vettore di 4 numeri interi |
Uint2 | uvec2 | Vettore di 2 numeri interi senza segno |
Uint3 | Uecec3 | Un vettore di 3 numeri interi senza segno |
Uint4 | UVEC4 | Un vettore di 4 numeri interi senza segno |
decimale 2 | numero in virgola mobile 2 | Vettore di 2 floating |
fluttuare3 | fluttuare3 | Vettore di 3 floating |
decimale 4 | fluttuare4 | Vettore di 4 floating |
fluttuare 4 x 4 | mat4 | Una matrice mobile 4x4 |
fluttuare 3 x 3 | Mat3 | Una matrice mobile di 3x3 |
Matematica
Nome | Tipo | Descrizione |
---|---|---|
PI | numero in virgola mobile | Una costante che rappresenta \(\pi\) |
HALF_PI | numero in virgola mobile | Una costante che rappresenta\(\frac{\pi}{2}\) |
saturare(fluttuare x) | numero in virgola mobile | Limita il valore specificato tra 0,0 e 1,0 |
pow5(fluttuante x) | numero in virgola mobile | Compute \(x^5\) |
sq(decimale x) | numero in virgola mobile | Compute \(x^2\) |
max3(fluttuante v) | numero in virgola mobile | Restituisce il valore massimo del float3 specificato |
mulMat4x4Float3(decimale4x4 m, numero in virgola mobile v) | fluttuare4 | Restituisce \(m * v\) |
mulMat3x3Float3(decimale4x4 m, numero in virgola mobile v) | fluttuare4 | Restituisce \(m * v\) |
Matrici
Nome | Tipo | Descrizione |
---|---|---|
getViewFromWorldMatrix() | floating4x4 | Matrice che converte da spazio mondiale a spazio visivo/oculare |
getWorldFromViewMatrix() | floating4x4 | Matrice che converte da visualizzazione/spazio oculare in spazio internazionale |
getClipFromViewMatrix() | floating4x4 | Matrice che converte da spazio di visualizzazione/occhio in spazio a clip (NDC) |
getViewFromClipMatrix() | floating4x4 | Matrice che converte da spazio clip (NDC) in spazio visivo/occhio |
getClipFromWorldMatrix() | floating4x4 | Matrice che converte da mondo a clip (spazio NDC) |
Costanti frame
Nome | Tipo | Descrizione |
---|---|---|
getResolution() | fluttuare4 | Risoluzione della visualizzazione in pixel: width , height , 1 / width , 1 / height |
getWorldCameraPosition() | fluttuare3 | Posizione della videocamera/dell'occhio nello spazio |
getTime() | numero in virgola mobile | Tempo in secondi da quando il motore Sceneform è stato inizializzato e potrebbe essere reimpostato regolarmente per evitare perdite di precisione. |
getEsposizione() | numero in virgola mobile | Esposizione fotometrica della fotocamera |
getEV100() | numero in virgola mobile | Valore di esposizione a 100 ISO della fotocamera |
Solo Vertex
Le seguenti API sono disponibili solo nel blocco di vertici:
Nome | Tipo | Descrizione |
---|---|---|
getPosition() | fluttuare4 | Posizione Vertex nel dominio definito dal materiale (valore predefinito: spazio oggetto/modello) |
getWorldFromModelMatrix() | floating4x4 | Matrice che converte da spazio del modello (oggetto) a spazio del mondo |
getWorldFromModelNormalMatrix() | fluttuante 3 x 3 | Matrice che converte le normalità dallo spazio del modello (oggetto) allo spazio mondiale |
Solo frammenti
Le API seguenti sono disponibili solo nel blocco di frammenti:
Nome | Tipo | Descrizione |
---|---|---|
getWorldTangentFrame() | fluttuante 3 x 3 | Matrice contenente in ogni colonna tangent (frame[0] ),
bi-tangent (frame[1] ) e
normal (frame[2] ) del
vertice nello spazio mondiale. Se il materiale non calcola uno spazio tangente normale per la mappatura a urto o se l'ombreggiatura non è anisotropica, in questa matrice è valido solo normal . |
getWorldPosition() | fluttuare3 | Posizione del frammento nello spazio |
getWorldViewVector() | fluttuare3 | Vettore normalizzato nello spazio mondiale dalla posizione del frammento all'occhio |
getWorldNormalVector() | fluttuare3 | Normalizzato normale nello spazio del mondo, dopo la mappatura di emergenza (da utilizzare dopo il giorno prepareMaterial() ) |
getWorldReflectedVector() | fluttuare3 | Riflessione del vettoriale della vista sul normale (da utilizzare dopo il giorno prepareMaterial() ) |
getNdotV() | numero in virgola mobile | Il risultato di dot(normal,
view) , sempre rigorosamente maggiore di 0 (deve essere utilizzato dopo prepareMaterial() ) |
getColor() | fluttuare4 | Colore interpolato del frammento, se l'attributo colore è obbligatorio |
getUV0() | numero in virgola mobile 2 | Primo insieme interpolato di coordinate UV, se l'attributo uv0 è obbligatorio |
getUV1() | numero in virgola mobile 2 | Primo insieme interpolato di coordinate UV, se l'attributo uv1 è obbligatorio |
inverseTonemap(decimale 3) | fluttuare3 | Applica l'operatore di mappatura dei toni inversi al colore lineare sRGB specificato. Questa operazione potrebbe essere un'approssimazione |
inverseTonemapSRGB(decimale3) | fluttuare3 | Applica l'operatore di mappatura dei toni inversi al colore sRGB non lineare specificato. Questa operazione può essere un'approssimazione |
luminanza(decimale mobile) | numero in virgola mobile | Calcola la luminanza del colore sRGB lineare specificato |
Modelli di materiale
I materiali di scena possono utilizzare uno dei seguenti modelli:
- Acceso (o standard)
- Tessuto
- Illuminato
Modello illuminato
Il modello illuminato è il modello di materiale standard di Sceneform. Questo modello di ombreggiatura basato su fisica è stato progettato per offrire una buona interoperabilità con altri strumenti e motori comuni come Unity 5, Unreal Engine 4, Substance Designer o Marmoset Toolbag.
Questo modello di materiale può essere utilizzato per descrivere un elevato numero di superfici non metalliche (dielettrici) o superfici metalliche (conduttori).
L'aspetto di un materiale che utilizza il modello standard viene controllato utilizzando le proprietà descritte nella tabella seguente.
Proprietà del modello standard
Proprietà | Definizione |
---|---|
colore base | Diffusione di albedo per superfici non metalliche e colore speculare per superfici metalliche |
metallico | Indica se una superficie appare dielettrica (0,0) o conduttore (1,0). Spesso utilizzato come valore binario (0 o 1) |
ruvidezza | Fluidità percepita (1.0) o rugosità (0.0) di una superficie. Le superfici levigate mostrano riflessi nitidi |
riflessione | Riflessione di Fresnel alla normale incidenza delle superfici dielettriche. Questa controlla direttamente l'efficacia delle riflessioni. |
clearCoat | Intensità dello strato trasparente |
ruvidezzacoat chiara | Fluida o rugosità percepita dello strato di rivestimento trasparente |
anisotropia | Quantità di anisotropia in direzione tangente o bitangente |
anisotropiaDirezione | Direzione della superficie locale |
ambientumoclusion | Definisce la quantità di luce ambientale accessibile a un punto della superficie. È un fattore di shadowing per pixel compreso tra 0,0 e 1,0 |
normale | Un normale dettaglio utilizzato per perturbarare la superficie utilizzando la mappatura normale (mappatura normale) |
clearCoatNormal | Un dettaglio normale utilizzato per perturbarare lo strato di rivestimento trasparente utilizzando la mappatura normale (mappatura normale). |
eissivo | Un ulteriore albedo diffuso per simulare superfici emissive (come i neon e così via) Questa proprietà è principalmente utile in una pipeline HDR con un pass bloom |
Il tipo e l'intervallo di ciascuna proprietà sono descritti nella tabella riportata di seguito.
Proprietà | Tipo | Intervallo | Nota |
---|---|---|---|
colore base | fluttuare4 | [0..10] | RGB lineare pre-moltiplicato |
metallico | numero in virgola mobile | [0..10] | Deve essere 0 o 1 |
ruvidezza | numero in virgola mobile | [0..10] | |
riflessione | numero in virgola mobile | [0..10] | Preferenza valori > 0,35 |
clearCoat | numero in virgola mobile | [0..10] | Deve essere 0 o 1 |
ruvidezzacoat chiara | numero in virgola mobile | [0..10] | Rimappa a [0..0.6] |
anisotropia | numero in virgola mobile | [-1..1] | Quando questo valore è positivo, l'anitrotropia è nella direzione della tangente |
anisotropiaDirezione | fluttuare3 | [0..10] | RGB lineare, codifica un vettore di direzione in uno spazio tangente |
ambientumoclusion | numero in virgola mobile | [0..10] | |
normale | fluttuare3 | [0..10] | RGB lineare, codifica un vettore di direzione in uno spazio tangente |
clearCoatNormal | fluttuare3 | [0..10] | RGB lineare, codifica un vettore di direzione in uno spazio tangente |
eissivo | fluttuare4 | rgb=[0..1], a=[-n..n] | Alfa è la compensazione dell'esposizione |
Colore di base
La proprietà baseColor
definisce il colore percepito di un oggetto (a volte chiamato albedo). L'effetto di baseColor
dipende dalla natura della superficie,
controllata dalla proprietà metallic
descritta nella sezione Metallico.
- Non metallici (dielettrici)
Definisce il colore diffuso della superficie. I valori reali si trovano in genere nell'intervallo [10..240] se il valore è codificato tra 0 e 255 o nell'intervallo [0.04..0.94] tra 0 e 1. Di seguito sono riportati alcuni esempi di colori di base per le superfici non metalliche.
Metal sRGB Esadecimale Colore Carbone 0,19, 0,19, 0,19 #323232 Gomma 0,21, 0,21, 0,21 #353535 Fango 0,33, 0,24, 0,19 #553d31 Legno 0,53, 0,36, 0,24 #875c3c Vegetazione 0,48, 0,51, 0,31 #7b824e Brick 0,58, 0,49, 0,46 #947d75 Sabbia 0,69, 0,66, 0,52 #b1a884 Concrete 0,75, 0,75, 0,73 #c0bfbb - Metalli (conduttori)
Definisce il colore speculare della superficie. I valori reali si trovano in genere nell'intervallo [170..255] se il valore è codificato tra 0 e 255 o nell'intervallo [0.66..1.0] tra 0 e 1. Di seguito sono riportati alcuni esempi di colori di base per le superfici metalliche.
Metal sRGB Esadecimale Colore Argento 0,98, 0,98, 0,96 #faf9f5 Alluminio 0,96, 0,96, 0,96 #f4f5f5 Titanio 0,81, 0,78, 0,76 #cec8c2 Ferro da stiro 0,76, 0,74, 0,73 #c0bdba Platinum 0,84, 0,82, 0,79 #d6d1c8 Oro 1,00, 0,87, 0,62 #fedc9d Ottone 0,96, 0,89, 0,68 #f4e4ad Rame 0,98, 0,85, 0,72 #fbd8b8
Tessuto metallizzato
La proprietà metallic
definisce se la superficie è una superficie metallica (conduttore) o non metallica (dielettrica). Questa proprietà deve essere utilizzata come valore binario, impostato su 0 o su 1. I valori intermedi sono davvero utili solo per creare transizioni tra diversi tipi di piattaforme quando vengono utilizzate le texture.
Questa proprietà può modificare notevolmente l'aspetto di una superficie. Le superfici non metalliche hanno un riflesso diffuso cromatico e un riflesso speculare acromatico (la luce riflessa non cambia colore). Le superfici metalliche non hanno riflessi diffusi e riflessi speculari cromatici (la luce riflessa assume il colore della superficie definita da baseColor
).
L'effetto di metallic
è mostrato di seguito (fai clic sull'immagine per visualizzare una versione più grande).
Ruvidezza
La proprietà roughness
controlla la fluidità percepita della superficie. Se
roughness
è impostato su 0, la superficie è perfettamente liscia e molto lucida. Più
è grezza la superficie, il "blurrier"; i riflessi sono. Questa proprietà è spesso chiamata glossiness in altri motori e strumenti ed è semplicemente l'opposto della rugosità (roughness = 1 - glossiness
).
Non metalli
L'effetto di roughness
sulle superfici non metalliche è mostrato di seguito (fai clic sull'immagine per visualizzare una versione più grande).
Metalli
L'effetto di roughness
sulle superfici metalliche è mostrato di seguito (fai clic sull'immagine per visualizzarne una versione più grande).
Riflesso
La proprietà reflectance
interessa solo le piattaforme non metalliche. Questa proprietà può essere utilizzata per controllare l'intensità speculare. Questo valore è definito tra 0 e 1
e rappresenta una rimappatura di una percentuale di riflettanza. Ad esempio, il valore predefinito di 0,5 corrisponde a una riflessione del 4%. I valori inferiori a 0,35 (2% di riflessione) dovrebbero essere evitati, in quanto nessun materiale reale presenta una bassa riflessione.
L'effetto di reflectance
sulle superfici non metalliche è mostrato di seguito (fai clic sull'immagine per visualizzare una versione più grande).
Il grafico seguente mostra valori comuni e la loro relazione con la funzione di mappatura.
Nella tabella che segue vengono riportati i valori di riflettanza accettabili per vari tipi di materiali (nessun materiale reale ha un valore inferiore al 2%).
Materiale | Riflesso | Valore della proprietà |
---|---|---|
Acqua | 2% | 0,35 |
Tessuti | Da 4% a 5,6% | Da 0,5 a 0,59 |
Liquidi comuni | dal 2% al 4% | Da 0,35 a 0,5 |
Gemme comuni | Dal 5% al 16% | Da 0,56 a 1,0 |
Plastica, vetro | Dal 4% al 5% | Da 0,5 a 0,56 |
Altri materiali dielettrici | dal 2% al 5% | Da 0,35 a 0,56 |
Occhi | 2,5% | 0,39 |
Skin | 2,8% | 0,42 |
Capelli | 4,6% | 0,54 |
Denti | 5,8% | 0,6 |
Valore predefinito | 4% | 0,5 |
Trasparente
I materiali multistrato sono abbastanza comuni, in particolare i materiali con un sottile strato traslucido su uno strato di base. Esempi reali di tali materiali includono vernici per auto, lattine, bilanciere e acrilico.
La proprietà clearCoat
può essere utilizzata per descrivere i materiali su due livelli. Lo strato trasparente sarà sempre isotropico e dielettrico. L'immagine seguente
confronta un materiale in fibra di carbonio sotto il modello di materiale standard (a sinistra) e il modello di rivestimento trasparente (a destra).
La proprietà clearCoat
controlla l'intensità del livello di rivestimento trasparente. Questo valore deve essere considerato come un valore binario, impostato su 0 o 1. I valori intermedi sono utili per controllare le transizioni tra le parti della superficie con livelli di rivestimento chiari e parti che non lo sono.
L'effetto di clearCoat
su un metallo grezzo è mostrato di seguito (fai clic sull'immagine per visualizzare una versione più grande).
Trasparente che presenta ruvidità
La proprietà clearCoatRoughness
è simile alla proprietà roughness
, ma si applica solo al livello di rivestimento trasparente. Inoltre, poiché gli strati di rivestimento trasparente non sono mai completamente ruvidi, il valore compreso tra 0 e 1 viene rimappato internamente per una rugosità effettiva da 0 a 0,6.
L'effetto di clearCoatRoughness
su un metallo grezzo è mostrato di seguito (fai clic sull'immagine per visualizzarne una versione più grande).
Anisotropia
Molti materiali reali, come il metallo spazzolato, possono essere replicati solo utilizzando un modello di riflettenza anisotropico. Puoi modificare un materiale da modello isotropico predefinito a modello anisotropico utilizzando la proprietà anisotropy
. L'immagine seguente mette a confronto un materiale isotropico (a sinistra) e un materiale isotropico (a destra).
L'effetto della variazione di anisotropy
da 0,0 (sinistra) a 1,0 (destra) su un metallo
ruvido è mostrato di seguito (fai clic sull'immagine per visualizzare una versione più grande).
L'immagine seguente mostra come si può controllare la direzione delle evidenziazioni anisotropiche utilizzando valori positivi o negativi: i valori positivi (a sinistra) definiscono l'anisotropia nella direzione della tangente e i valori negativi (a destra) nella direzione bitangente.
Direzione anisotropia
La proprietà anisotropyDirection
definisce la direzione della superficie in un determinato punto, quindi controlla la forma delle evidenziazioni specifiche. È specificato come vettore di 3 valori che solitamente provengono da una texture, codificando le indicazioni locali alla superficie.
L'effetto del rendering di anisotropyDirection
su un metallo con una mappa delle indicazioni stradali è mostrato di seguito (fai clic sull'immagine per visualizzare una versione più grande).
Di seguito è riportata la mappa delle indicazioni stradali utilizzata per il rendering dell'immagine.
Occupazione ambientale
La proprietà ambientOcclusion
definisce quanta luce ambientale è accessibile a un punto della superficie. Il fattore di shadowing per pixel è compreso tra 0,0 (completamente ombrato) e 1,0 (completamente illuminato). Questa proprietà interessa solo l'illuminazione indiretta diffusa (illuminazione basata su immagini), non luci dirette come direzioni, punti e faretti, né illuminazione speculare. L'immagine seguente confronta i materiali senza occlusione ambientale diffusa (a sinistra) e con quelli con questa (a destra).
Normale
La proprietà normal
definisce la normalità della superficie in un determinato punto. In genere proviene da una texture di mappa normale, che consente di variare la proprietà per pixel. Il normale viene fornito in uno spazio tangente, il che significa che +Z punti
al di fuori della superficie.
Ad esempio, immaginiamo di voler visualizzare un mobile rivestito in pelle trapuntata. Per modellare la geometria in modo da rappresentare con precisione il modello trapuntato, sarebbero necessari troppi triangoli, quindi impieghiamo invece una rete mesh molto poligonale in una mappa normale. Puoi poi applicare la mappa base a un mesh semplificato. L'immagine seguente confronta un mesh semplice senza mappature normali (a sinistra) e con questo (a destra).
Tenete presente che la proprietà normal
influisce sul livello base e non sul livello di rivestimento trasparente.
Trasparente normale
La proprietà clearCoatNormal
definisce la normalità del livello di rivestimento trasparente in un determinato punto. Il suo comportamento è simile a quello della proprietà normal
.
Emissiva
La proprietà emissive
può essere utilizzata per simulare un'ulteriore luce emessa dalla superficie. È definito come un valore float4
che contiene un colore RGB (nello spazio lineare) e un valore di compensazione dell'esposizione (nel canale alfa).
Sebbene un valore di esposizione indichi effettivamente le combinazioni di impostazioni della fotocamera, viene spesso utilizzato dai fotografi per descrivere l'intensità della luce. Ecco perché le fotocamere consentono ai fotografi di applicare un compenso all'esposizione in caso di sovraesposizione o sovraesposizione di un'immagine. Questa impostazione può essere utilizzata per il controllo artistico, ma anche per ottenere un'esposizione appropriata (la neve, ad esempio, verrà mostrata per il 18% di grigio medio).
Il valore di compensazione dell'esposizione della proprietà emissiva può essere utilizzato per far sì che il colore emissivo sia più luminoso (valori positivi) o più scuro (valori negativi) dell'esposizione corrente. Se l'effetto di fioritura è attivato, l'utilizzo di una compensazione dell'esposizione positiva può far apparire la superficie.
Modello di stoffa
Tutti i modelli di materiali descritti in precedenza sono progettati per simulare superfici dense, sia a livello di macro sia a livello di micro. I vestiti e i tessuti, tuttavia, sono spesso realizzati con fili che sono assorbiti e disperdono la luce. Rispetto alle superfici dure, il panno è caratterizzato da un lob speculare più morbido, con un ampio ribasso e la presenza di un'illuminazione fuzz, causata dalla dispersione in avanti/indietro. Alcuni tessuti mostrano anche colori speculativi a due tonalità, ad esempio il velluto.
L'immagine seguente confronta il tessuto denim con il modello standard (a sinistra) e il modello in tessuto (a destra). Osserva come il modello di materiale standard non riesce a catturare l'aspetto di un campione di tessuto denim (a sinistra). La superficie appare rigida (quasi in plastica), più simile a un telo che a un pezzo di tessuto. Questo dimostra anche quanto sia importante il lobo speculare più morbido causato dall'assorbimento e dalla dispersione rispetto alla fedele ricreazione del tessuto.
Il velluto è un caso d'uso interessante per un modello in tessuto. Come mostrato nell'immagine di seguito, questo tipo di tessuto presenta una forte illuminazione del bordo dovuta alla dispersione del modello in avanti e all'indietro. Questi eventi di dispersione sono causati da fibre che si trovano dritte sulla superficie del tessuto. Quando la luce incidente proviene dalla direzione opposta alla direzione della visuale, le fibre si disperdono in avanti. Allo stesso modo, quando la luce incidente proviene dalla stessa direzione della direzione di visualizzazione, le fibre disperdono la luce all'indietro.
È importante notare che ci sono tipi di tessuti che vengono ancora modellati meglio dai modelli di materiali di superficie dura. Ad esempio, pelle, seta e satinato possono essere ricreati utilizzando i modelli di materiale standard o anisotropici.
Il modello del materiale in tessuto comprende tutti i parametri definiti in precedenza per la modalità del materiale standard, ad eccezione di metallico e riflessione. Sono disponibili anche due parametri aggiuntivi descritti nella tabella seguente.
Parametro | Definizione |
---|---|
coloro luce | Tinta speculare per creare tessuto speculare bicolore (il valore predefinito è \(\sqrt{baseColor}\)) |
SubsurfaceColor | Tinteggiatura per il colore diffuso dopo dispersione e assorbimento attraverso il materiale |
Il tipo e l'intervallo di ciascuna proprietà sono descritti nella tabella riportata di seguito.
Proprietà | Tipo | Intervallo | Nota |
---|---|---|---|
coloro luce | fluttuare3 | [0..10] | RGB lineare |
SubsurfaceColor | fluttuare3 | [0..10] | RGB lineare |
Per creare un materiale simile al velluto, il colore di base può essere impostato sul nero (o su un colore scuro). Le informazioni sulla cromaticità devono essere impostate sul colore della lucentezza. Per creare tessuti più comuni come jeans, cotone e così via, utilizza il colore di base per la cromaticità e utilizza il colore della lucentezza predefinito o imposta il colore della lucentezza sulla luminosità del colore di base.
Grigio chiaro
La proprietà sheenColor
può essere utilizzata per modificare direttamente la riflessione speculare. Offre un migliore controllo sull'aspetto del panno e offre la possibilità di creare materiali speculari a due toni.
L'immagine seguente confronta il tessuto blu con e senza (sinistra) e con (destra) lucentezza (fai clic sull'immagine per visualizzare una versione più grande).
Colore della superficie
La proprietà subsurfaceColor
non si trova fisicamente e può essere utilizzata per simulare la dispersione, l'assorbimento parziale e la riemissione di luce in determinati tipi di tessuti. Ciò è particolarmente utile per creare tessuti più morbidi.
La seguente immagine mostra l'effetto di subsurfaceColor
. Mostra panni bianchi (colonna a sinistra) e un panno bianco con scatti del secondo piano marroni (colonna destra). Fai clic sull'immagine per visualizzarne una versione più grande.
Modello illuminato
Il modello con materiale illuminato può essere utilizzato per spegnere tutti i calcoli dell'illuminazione. Il suo scopo principale è eseguire il rendering di elementi illuminati come cubemap, contenuti esterni (come uno stream video o videocamera), interfacce utente, visualizzazione/debug e così via. Il modello illuminato mostra solo due proprietà descritte nella tabella riportata di seguito.
Proprietà | Definizione |
---|---|
colore base | Colore diffuso in superficie |
eissivo | Colore diffuso aggiuntivo per simulare le superfici emissive. Questa proprietà è utile soprattutto in una pipeline HDR con un pass bloom |
Il tipo e l'intervallo di ciascuna proprietà sono descritti nella tabella riportata di seguito.
Proprietà | Tipo | Intervallo | Nota |
---|---|---|---|
colore base | fluttuare4 | [0..10] | RGB lineare pre-moltiplicato |
eissivo | fluttuare4 | rgb=[0..1], a=N/A | RGB lineare pre-moltiplicato, alfa viene ignorato |
Il valore di emissive
viene semplicemente aggiunto a baseColor
quando presente. L'uso
principale di emissive
consiste nel forzare la fioritura di una superficie illuminata se la pipeline HDR è
configurata con un pass bloom.
L'immagine seguente mostra un esempio del modello di materiale non illuminato utilizzato per visualizzare le informazioni di debug (fai clic sull'immagine per visualizzarne una versione più grande).
Gestire i colori
Colori lineari
Se i dati colore provengono da una texture, assicurati di utilizzare una texture sRGB per trarre vantaggio dalla conversione hardware automatica da sRGB a lineare. Se i dati relativi al colore vengono passati come parametro al materiale che puoi convertire da sRGB a lineare, esegui il seguente algoritmo su ciascun canale di colore:
float sRGB_to_linear(float color) {
return color <= 0.04045 ? color / 12.92 : pow((color + 0.055) / 1.055, 2.4);
}
In alternativa, puoi utilizzare una delle due versioni più economiche ma meno accurate mostrate di seguito:
// Cheaper
linearColor = pow(color, 2.2);
// Cheapest
linearColor = color * color;
Alfa precompilato
Un colore utilizza alfa precompilata se i suoi componenti RGB vengono moltiplicati per il canale alfa:
// Compute pre-multiplied color
color.rgb *= color.a;
Se il colore è campionato da una texture, puoi semplicemente assicurarti che i dati della texture vengano precompilati in anticipo. Su Android, qualsiasi texture caricata da una mappe bit viene precompilata per impostazione predefinita.