Sceneform proporciona definiciones de material predeterminadas (.sfm
) para que los desarrolladores obtengan fácilmente resultados atractivos. Los desarrolladores que quieran personalizar profundamente el aspecto de sus elementos pueden crear sus propias definiciones de materiales (archivos *.mat
) y aplicarlas a sus elementos mediante la especificación del atributo source
en la definición del elemento.
Conceptos básicos
- Material
- Un material define la apariencia visual de una superficie. Para describir y renderizar por completo una superficie, un material proporciona la siguiente información:
- Modelo de Material
- Conjunto de parámetros con nombre controlados por el uso
- Estado de trama (modo de fusión, selección de fondo, etc.)
- Código de sombreador de vértices
- Código de sombreador de fragmento
- Modelo de Material
- También se denomina modelo de sombreado o modelo de iluminación, y el modelo de material define las propiedades intrínsecas de una superficie. Estas propiedades influyen de manera directa en la forma en que se calcula la iluminación y, por lo tanto, en la apariencia de una superficie.
- Definición de Material
- Archivo de texto que describe toda la información que requiere un material. En esta página, se describe la estructura y el formato de los archivos de definición de material (
*.mat
).
Definiciones de materiales
Una definición de material es un archivo de texto que describe toda la información que requiere un material:
- Nombre
- Parámetros de usuario
- Modelo de Material
- Atributos obligatorios
- Interpolantes (llamados variables)
- Estado de la trama (modo de fusión, etc.)
- Código de sombreador (sombreador de fragmentos, opcionalmente vértice de vértice)
Formato
El formato de definición de material es un formato basado en JSON que llamamos JSONish. En el nivel superior, una definición de material consta de 3 bloques diferentes que usan la notación de objetos JSON:
material {
// material properties
}
vertex {
// vertex shader, optional
}
fragment {
// fragment shader
}
Una definición de material viable mínima debe contener un bloque material
y un bloque fragment
. El bloque vertex
es opcional.
Diferencias con JSON
En JSON, un objeto está formado por pares de clave-valor. Un par JSON tiene la siguiente sintaxis:
"key" : value
Donde el valor puede ser una string, un número, un objeto, un arreglo o un literal (true
, false
o null
). Si bien esta sintaxis es perfectamente válida en una definición material, una variante sin comillas alrededor de las strings también se acepta en JSONish:
key : value
Las comillas siguen siendo obligatorias cuando la string contiene espacios.
Los bloques vertex
y fragment
contienen código GLSL sin escape, sin comillas, que no es válido en JSON.
Se permiten los comentarios de estilo C++ de una línea.
La clave de un par distingue entre mayúsculas y minúsculas.
El valor de un par no distingue entre mayúsculas y minúsculas.
Ejemplo
La siguiente lista de códigos muestra un ejemplo de una definición de material válida. Esta definición usa el modelo de material lit, usa el modo de fusión opaco predeterminado, requiere que un conjunto de coordenadas UV se presenten en la malla procesada y define 3 parámetros de usuario. En las siguientes secciones de este documento, se describen los bloques material
y fragment
en detalle.
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;
}
}
Bloqueo de material
El bloque de material es un bloque obligatorio que contiene una lista de pares de propiedades para describir todos los datos que no son sombreados.
name
- Tipo
string
- Valor
- Cualquier string. Las comillas dobles son obligatorias si el nombre contiene espacios.
- Descripción
- Establece el nombre del material. El nombre se retiene en el entorno de ejecución para la depuración.
material {
name : stone
}
material {
name : "Wet pavement"
}
shadingModel
- Tipo
string
- Valor
- Cualquiera de
lit
,cloth
,unlit
. El valor predeterminado eslit
. - Descripción
- Selecciona el modelo de material como se describe en la sección Modelos de material.
material {
shadingModel : unlit
}
Parámetros
- Tipo
- arreglo de objetos de parámetros
- Valor
Cada entrada es un objeto con las propiedades
name
ytype
, ambas del tipostring
. El nombre debe ser un identificador GLSL válido. El tipo debe ser uno de los que se describen en la siguiente tabla.Tipo Descripción bool Booleano único booleano2 Vector de 2 booleanos booleano3 Vector de 3 booleanos booleano4 Vector de 4 booleanos float Punto flotante número de punto flotante2 Vector de 2 flotantes número de punto flotante3 Vector de 3 números de punto flotante número de punto flotante4 Vector de 4 números de punto flotante int Número entero único interno2 Vector de 2 números enteros int3 Vector de 3 números enteros Int4 Vector de 4 números enteros muestra2d Textura en 2D samplerExternal Textura externa. Para obtener más información, consulta ExternalTexture y setExternalTexture() - Muestras
Los tipos de muestra también pueden especificar un
format
(el valor predeterminado esfloat
) y unprecision
(el valor predeterminado esdefault
). El formato puede ser uno deint
,float
. La precisión puede ser una de lasdefault
(la mejor precisión para la plataforma, que suele serhigh
en computadoras de escritorio,medium
en dispositivos móviles),low
,medium
yhigh
.- Descripción
Enumera los parámetros que requiere tu material. Estos parámetros se pueden configurar en el entorno de ejecución con la API de Material de Sceneform. El acceso a los parámetros desde los sombreadores varía según el tipo de parámetro:
- Tipos de muestra: usa el nombre del parámetro con el prefijo
materialParams_
. Por ejemplo,materialParams_myTexture
. - Otros tipos: Usa el nombre del parámetro como el campo de una estructura llamada
materialParams
. Por ejemplo,materialParams.myColor
.
- Tipos de muestra: usa el nombre del parámetro con el prefijo
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;
}
}
requiere
- Tipo
- arreglo de
string
- Valor
- Cada entrada debe ser
uv0
,uv1
,color
otangents
. - Descripción
- Enumera los atributos de vértice que requiere el material. El atributo
position
se incluye de forma automática y no es necesario especificarlo. El atributotangents
es obligatorio de forma automática cuando se selecciona cualquier modelo de sombreado que no seaunlit
. Consulta las secciones del sombreador de este documento para obtener más información sobre cómo acceder a estos atributos desde los sombreadores.
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
- arreglo de
string
- Valor
- Hasta 4 strings, cada una debe ser un identificador GLSL válido.
- Descripción
- Define los interpoladores personalizados (o variables) que genera el sombreador de
material del material. Cada entrada del arreglo define el nombre de un interpolador.
El nombre completo en el sombreador de fragmentos es el nombre del interpolador con el prefijo
variable_
. Por ejemplo, si declaras una variable llamadaeyeDirection
, puedes acceder a ella en el sombreador de fragmentos mediantevariable_eyeDirection
. En el sombreador de vértices, el nombre del interpolador es simplemente un miembro de la estructuraMaterialVertexInputs
(material.eyeDirection
en tu ejemplo). Cada interpolador es del tipofloat4
(vec4
) en los sombreadores.
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);
}
}
fusión
- Tipo
string
- Valor
- Cualquiera de
opaque
,transparent
,fade
,add
,masked
La configuración predeterminada esopaque
. - Descripción
Define cómo y si el objeto procesado se combina con el contenido del destino de renderización. Los modos de fusión posibles son:
- Opaco: la combinación está inhabilitada, se ignora el canal alfa del resultado del material.
- Transparente: La combinación está habilitada. El resultado del material se compone en composición alfa con el objetivo de renderización, mediante la regla de fuente sobre de Porter-Duff. Este modo de fusión supone un valor alfa premultiplicado.
- Atenuación: Actúa como
transparent
, pero la transparencia también se aplica a la iluminación especular. En el modotransparent
, los valores alfa del material solo se aplican a la iluminación difusa. Este modo de fusión es útil para atenuar los objetos iluminados. - Agregar: La combinación está habilitada. La salida del material se agrega al contenido del destino de procesamiento.
- Enmascarado: la combinación está inhabilitada. Este modo de combinación habilita el enmascaramiento alfa. El canal alfa del resultado del material define si un fragmento se descarta o no. Consulta la sección maskThreshold para obtener más información.
material {
blending : transparent
}
Dominio de vértice
- Tipo
string
- Valor
- Cualquiera de
object
,world
,view
,device
La configuración predeterminada esobject
. - Descripción
Define el dominio (o el espacio de coordenadas) de la malla procesada. El dominio influye en cómo se transforman los vértices en el sombreador de vértices. Los dominios posibles son los siguientes:
- Objeto: Los vértices se definen en el espacio de coordenadas del objeto (o modelo). Los vértices se transforman mediante la matriz de transformación del objeto procesado.
- Mundo: Los vértices se definen en el espacio de coordenadas del mundo. Los vértices no se transforman con la transformación del objeto procesado.
- Vista: Los vértices se definen en el espacio de coordenadas de la vista (del ojo o de la cámara). Los vértices no se transforman con la transformación del objeto procesado.
- Dispositivo: Los vértices se definen en el espacio normal de coordenadas del dispositivo (o clip). Los vértices no se transforman con la transformación de objeto procesado.
material {
vertexDomain : device
}
interpolación
- Tipo
string
- Valor
- Cualquiera de
smooth
,flat
. La configuración predeterminada essmooth
. - Descripción
- Define cómo se interpolan los interpoladores (o variables) entre vértices.
Cuando esta propiedad se establece en
smooth
, se realiza una interpolación correcta de perspectiva en cada interpolador. Cuando se establece enflat
, no se realiza ninguna interpolación y todos los fragmentos dentro de un triángulo determinado se sombrean de la misma manera.
material {
interpolation : flat
}
selectivo
- Tipo
string
- Valor
- Cualquiera de
none
,front
,back
,frontAndBack
La configuración predeterminada esback
. - Descripción
- Define qué triángulos deben seleccionarse: ninguno, triángulo hacia el frente, hacia atrás o todos.
material {
culling : none
}
Escribir con color
- Tipo
boolean
- Valor
true
ofalse
. La configuración predeterminada estrue
.- Descripción
- Habilita o inhabilita las escrituras en el búfer de color.
material {
colorWrite : false
}
depthWrite
- Tipo
boolean
- Valor
true
ofalse
. La configuración predeterminada estrue
.- Descripción
- Habilita o inhabilita las escrituras en el búfer de profundidad.
material {
depthWrite : false
}
pelolargo
- Tipo
boolean
- Valor
true
ofalse
. La configuración predeterminada estrue
.- Descripción
- Habilita o inhabilita las pruebas de profundidad. Cuando las pruebas de profundidad están inhabilitadas, un objeto procesado con este material siempre aparecerá sobre otros objetos opacos.
material {
depthCulling : false
}
doble cara
- Tipo
boolean
- Valor
true
ofalse
. La configuración predeterminada esfalse
.- Descripción
- Habilita o inhabilita el procesamiento bilateral. Cuando se establece en
true
,culling
se establece automáticamente ennone
; si el triángulo está orientado hacia atrás, el valor normal del triángulo se gira de forma automática para que quede frontal.
material {
doubleSided : true
}
transparencia
- Tipo
string
- Valor
- Cualquiera de
default
,twoPassesOneSide
otwoPassesTwoSides
. La configuración predeterminada esdefault
. - Descripción
- Controla cómo se renderizan los objetos transparentes. Solo es válido cuando el modo
blending
no esopaque
. Ninguno de estos métodos puede procesar geometría cóncava con precisión, pero en la práctica suelen ser lo suficientemente buenos.
Los tres modos de transparencia posibles son los siguientes:
default
: El objeto transparente se renderiza con normalidad y respeta el modoculling
, entre otros.twoPassesOneSide
: El objeto transparente primero se renderiza en el búfer de profundidad y, luego, nuevamente en el búfer de color, en honor al modocullling
. De esta manera, solo se renderiza la mitad del objeto transparente, como se muestra a continuación.twoPassesTwoSides
: El objeto transparente se renderiza dos veces en el búfer de color: primero con sus caras posteriores y, luego, con sus rostros frontales. Este modo te permite procesar ambos conjuntos de rostros y reducir o eliminar los problemas de orden, como se muestra a continuación.twoPassesTwoSides
se puede combinar condoubleSided
para lograr un mejor efecto.
material {
transparency : twoPassesOneSide
}
umbraldemáscara
- Tipo
number
- Valor
- Un valor entre
0.0
y1.0
. La configuración predeterminada es0.4
. - Descripción
- Establece el valor alfa mínimo que un fragmento debe tener para que no se descarte cuando el modo
blending
se establece enmasked
. Cuando el modo de combinación no esmasked
, este valor se ignora. Este valor se puede usar para controlar la apariencia de los objetos con máscara alfa.
material {
blending : masked,
maskThreshold : 0.5
}
Multiplicador de sombras
- Tipo
boolean
- Valor
true
ofalse
. La configuración predeterminada esfalse
.- Descripción
- Solo está disponible en el modelo de sombreado
unlit
. Si esta propiedad está habilitada, el color final que calcula el material se multiplica por el factor de sombras (o visibilidad). Esto permite crear objetos transparentes que reciban sombras (por ejemplo, un plano terrestre 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);
}
}
Filtro de variante
- Tipo
- arreglo de
string
- Valor
- Cada entrada debe ser
dynamicLighting
,directionalLighting
,shadowReceiver
oskinning
. - Descripción
- Se usa para especificar una lista de variantes del sombreador que la aplicación garantizará nunca será necesaria. Estas variantes del sombreador se omiten durante la fase de generación del código, lo que reduce el tamaño general del material. Ten en cuenta que algunas variantes pueden filtrarse automáticamente. Por ejemplo, todas las variantes relacionadas con la iluminación (
directionalLighting
, etc.) se filtran cuando se compila un material deunlit
. Usa el filtro de variantes con precaución, ya que filtrar una variante requerida en el tiempo de ejecución puede generar fallas.
Descripción de las variantes: directionalLighting
, que se usa cuando hay una luz direccional en la escena, dynamicLighting
, que se usa cuando hay una luz no direccional (punto, punto, etc.) en la escena, shadowReceiver
, que se usa cuando un objeto puede recibir sombras, skinning
, que se usa cuando se anima un objeto mediante el diseño de la GPU
material {
name : "Invisible shadow plane",
shadingModel : unlit,
shadowMultiplier : true,
blending : transparent,
variantFilter : [ skinning ]
}
Bloque de vértices
El bloque de vértices es opcional y se puede usar para controlar la etapa de sombreado del vértice del material. El bloque de vértices debe contener un código ESSL 3.0 válido (la versión de GLSL compatible con OpenGL ES 3.0). Tienes la libertad de crear varias funciones dentro del bloque de vértices, pero debes declarar la función materialVertex
:
vertex {
void materialVertex(inout MaterialVertexInputs material) {
// vertex shading code
}
}
El sistema de sombreado invoca esta función automáticamente durante el tiempo de ejecución y te permite leer y modificar las propiedades del material con la estructura MaterialVertexInputs
. Esta definición completa de la estructura se puede encontrar en la sección Entradas de vértices de Material.
Puedes usar esta estructura para calcular tus variables o interpoladores personalizados, o para modificar el valor de los atributos. Por ejemplo, los siguientes bloques de vértices modifican el color y las coordenadas UV del vértice a lo largo del tiempo:
material {
requires : [uv0, color]
}
vertex {
void materialVertex(inout MaterialVertexInputs material) {
material.color *= sin(getTime());
material.uv0 *= sin(frameUniforms.time);
}
}
Además de la estructura MaterialVertexInputs
, tu código de sombreado del vértice puede usar todas las API públicas que se enumeran en la sección API públicas del sombreador.
Entradas de vértices de Material
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
};
Fragmento de bloque
El bloque de fragmento debe usarse para controlar la etapa de sombreado del fragmento del material. El bloque de fragmentos debe contener un código ESSL 3.0 válido (la versión de GLSL compatible con OpenGL ES 3.0). Tienes la libertad de crear varias funciones dentro del bloque de vértices, pero debes declarar la función material
:
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
// fragment shading code
}
}
El sistema de sombreado invoca esta función automáticamente durante el tiempo de ejecución y te permite leer y modificar las propiedades del material con la estructura MaterialInputs
. Esta definición completa de la estructura se puede encontrar en la sección de entradas de fragmentos de Material. La definición completa de los distintos miembros de la estructura se puede encontrar en la sección Modelos de Material de este documento.
El objetivo de la función material()
es calcular las propiedades del material específicas del modelo de sombreado seleccionado. Por ejemplo, a continuación, se muestra un bloque de fragmento que crea un metal rojo brillante mediante el modelo de sombreado estándar estándar:
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;
}
}
Preparar función Material
Ten en cuenta que debes llamar a prepareMaterial(material)
antes de salir de la función material()
. Esta función prepareMaterial
configura el estado interno del modelo de material. Algunas de las API que se describen en la sección de las API de Fragment, como shading_normal
, por ejemplo, solo se puede acceder después de invocar prepareMaterial()
.
También es importante recordar que la propiedad normal
, como se describe en la sección Entradas de fragmentos de Material, solo tiene efecto cuando se modifica antes de llamar a prepareMaterial()
. A continuación, se muestra un ejemplo de un sombreador de fragmentos que modifica correctamente la propiedad normal
para implementar un plástico rojo brillante con asignación de cambio de prioridad:
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;
}
}
Entradas de fragmentos de 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 públicas del sombreador
Tipos
Si bien los tipos de GLSL se pueden usar directamente (vec4
o mat4
), recomendamos el uso de los siguientes alias de tipo:
Nombre | Tipo GLSL | Descripción |
---|---|---|
boluto2 | bvec2 | Vector de 2 booleanos |
bolita3 | bvec3 | Vector de 3 booleanos |
boludo4 | BVEC4 | Vector de 4 booleanos |
int2 | ivec2 | Vector de 2 números enteros |
int3 | ivec3 | Vector de 3 números enteros |
int4 | ivec4 | Vector de 4 números enteros |
uint2 | uvec2 | Vector de 2 números enteros sin firma |
uint3 | uvec3 | Vector de 3 números enteros sin firma |
uint4 | uvec4 | Vector de 4 números enteros sin firma |
float2 | número de punto flotante2 | Vector de 2 números de punto flotante |
float3 | número de punto flotante3 | Vector de 3 flotantes |
float4 | número de punto flotante4 | Vector de 4 números de punto flotante |
float4x4 | mat4 | Una matriz flotante de 4 x 4 |
float3x3 | mat3 | Una matriz flotante de 3 x 3 |
Matemáticas
Nombre | Tipo | Descripción |
---|---|---|
PI | float | Una constante que representa \(\pi\) |
HALF_PI | float | Una constante que representa\(\frac{\pi}{2}\) |
saturación(x flotante) | float | Fija el valor especificado entre 0.0 y 1.0. |
pow5(float x) | float | Procesamiento \(x^5\) |
sq(float x) | float | Procesamiento \(x^2\) |
max3(float3 v) | float | Muestra el valor máximo del float3 especificado. |
mulMat4x4Float3(float4x4 m, float3 v) | número de punto flotante4 | Muestra \(m * v\) |
mulMat3x3Float3(float4x4m, float3 v) | número de punto flotante4 | Muestra \(m * v\) |
Matrices
Nombre | Tipo | Descripción |
---|---|---|
getViewFromWorldMatrix() | float4x4 | La matriz que convierte el espacio del mundo en el espacio visual y visual |
getWorldFromViewMatrix() | float4x4 | Matriz que convierte del espacio visual y visual al espacio |
getClipFromViewMatrix() | float4x4 | La matriz que convierte el espacio visual o ojos al espacio del clip (NDC) |
getViewFromClipMatrix() | float4x4 | Matriz que convierte el espacio de clip (NDC) en el espacio para ver/ojos |
getClipFromWorldMatrix() | float4x4 | La matriz que convierte el espacio del mundo en un clip (NDC) |
Constantes de fotogramas
Nombre | Tipo | Descripción |
---|---|---|
getResolution(). | número de punto flotante4 | Resolución de la vista en píxeles: width , height , 1 / width , 1 / height |
getWorldCameraPosition() | número de punto flotante3 | Posición de la cámara o del ojo en el espacio mundial |
getTime(). | float | El tiempo en segundos desde que se inicializó el motor de Sceneform se puede restablecer con regularidad para evitar la pérdida de precisión. |
getExposure(). | float | Exposición fotométrica de la cámara |
getEV100(). | float | Valor de exposición en ISO 100 de la cámara |
Solo Vertex
Las siguientes API solo están disponibles en el bloque de vértices:
Nombre | Tipo | Descripción |
---|---|---|
getPosition() | número de punto flotante4 | Posición de Vertex en el dominio definido por el material (valor predeterminado: espacio de objeto o modelo) |
getWorldFromModelMatrix() | float4x4 | Matriz que convierte el espacio modelo (objeto) en el espacio mundial |
getWorldFromModelNormalMatrix(). | número de punto flotante3x3 | Matriz que convierte las normales del espacio del modelo (objeto) en el espacio del mundo |
Solo fragmento
Las siguientes API solo están disponibles desde el bloque de fragmentos:
Nombre | Tipo | Descripción |
---|---|---|
getWorldTangentFrame() | número de punto flotante3x3 | Matriz que contiene en cada columna los tangent (frame[0] ), bi-tangent (frame[1] ) y normal (frame[2] ) del vértice en el espacio del mundo. Si el material no calcula un espacio tangencial normal para la asignación de cambio de prioridad o si el sombreado no es anisotrópico, solo el normal es válido en esta matriz. |
getWorldPosition() | número de punto flotante3 | Posición del fragmento en el espacio mundial |
getWorldViewVector(). | número de punto flotante3 | Vector normalizado en el espacio mundial, desde la posición del fragmento hasta el ojo |
getWorldNormalVector(). | número de punto flotante3 | Normalización normalizada en el espacio mundial, después de la asignación de cambio de prioridad (debe usarse después de prepareMaterial() ) |
getWorldReflectedVector(). | número de punto flotante3 | Reflejo del vector de vista sobre lo normal (se debe usar después de prepareMaterial() ) |
getNdotV(). | float | El resultado de dot(normal,
view) , siempre mayor que 0 (debe usarse después de prepareMaterial() ) |
getColor() | número de punto flotante4 | Color interpolado del fragmento, si se requiere el atributo de color |
getUV0(). | número de punto flotante2 | Primer conjunto interpolado de coordenadas UV, si se requiere el atributo uv0 |
getUV1(). | número de punto flotante2 | Primer conjunto interpolado de coordenadas UV, si el atributo uv1 es obligatorio |
inverseTonemap(float3) | número de punto flotante3 | Aplica el operador de asignación de tonos inverso al color sRGB lineal especificado. Esta operación puede ser una aproximación |
inverseTonemapSRGB(float3) | número de punto flotante3 | Aplica el operador de asignación de tonos inverso al color sRGB no lineal especificado. Esta operación puede ser una aproximación |
luminancia(float3) | float | Calcula la luminancia del color sRGB lineal especificado. |
Modelos de Material
Los materiales con formato de escena pueden usar uno de los siguientes modelos de material:
- Lit (o estándar)
- Tela
- Sin iluminación
Modelo de Lit
El modelo iluminado es el modelo de material estándar de Sceneform. Este modelo de sombreado basado en la física se diseñó para ofrecer una buena interoperabilidad con otros motores y herramientas comunes, como Unity 5, Unreal Engine 4, Substance Designer o Marmoset Toolbag.
Este modelo de material se puede usar para describir una gran cantidad de superficies no metálicas (dieléctricos) o superficies metálicas (conductores).
La apariencia de un material con el modelo estándar se controla mediante las propiedades que se describen en la siguiente tabla.
Propiedades del modelo estándar
Propiedad | Definición |
---|---|
color base | Difusa albedo para superficies no metálicas y color especular para superficies metálicas |
metálico | Si una superficie parece ser eléctrico (0.0) o conductor (1.0) Se suele usar como un valor binario (0 o 1). |
grosería | Suavidad (1.0) o aspereza (0.0) de una superficie Las superficies suaves tienen reflejos nítidos |
reflejo | Reflejo del freno en la incidencia normal para superficies dieléctricos. Esto controla directamente la intensidad de los reflejos |
clearCoat | Intensidad de la capa transparente |
Aspereza de la capa transparente | Se perciben la suavidad o aspereza de la capa transparente de la capa. |
anisotropía | Cantidad de anisotropía en la dirección tangente o bitangente |
anisotropía | Dirección de la superficie local |
oclusión ambiente | Define qué porción de la luz ambiente puede acceder un punto de superficie. Es un factor de observación por píxel entre 0.0 y 1.0. |
normal | Es una normal detallada que se usa para perturbar la superficie mediante la asignación de aumento (asignación normal). |
clearCoatNormal | Es un detalle normal que se usa para perturbar la capa de recubrimiento transparente mediante la asignación de impulsos (asignación normal). |
emisivo | Albedo adicional y difuso para simular superficies emisivas (como neón, etcétera) Esta propiedad es útil principalmente en una canalización de HDR con un pase de floración. |
El tipo y el rango de cada propiedad se describen en la siguiente tabla.
Propiedad | Tipo | Range | Nota |
---|---|---|---|
color base | número de punto flotante4 | [0..1] | RGB lineal premultiplicado |
metálico | float | [0..1] | Debe ser 0 o 1 |
grosería | float | [0..1] | |
reflejo | float | [0..1] | Valores preferidos > 0.35 |
clearCoat | float | [0..1] | Debe ser 0 o 1 |
Aspereza de la capa transparente | float | [0..1] | Reasigna a [0.0.6] |
anisotropía | float | [-1.1] | La anisotropía es en la dirección tangente cuando este valor es positivo |
anisotropía | número de punto flotante3 | [0..1] | RGB lineal, codifica un vector de dirección en el espacio tangente |
oclusión ambiente | float | [0..1] | |
normal | número de punto flotante3 | [0..1] | RGB lineal, codifica un vector de dirección en el espacio tangente |
clearCoatNormal | número de punto flotante3 | [0..1] | RGB lineal, codifica un vector de dirección en el espacio tangente |
emisivo | número de punto flotante4 | rgb=[0.1], a=[-n..n] | Alfa es la compensación de exposición |
Color base
La propiedad baseColor
define el color percibido de un objeto (a veces llamado albedo). El efecto de baseColor
depende de la naturaleza de la superficie, controlada por la propiedad metallic
que se explica en la sección Metálica.
- No metales (dieléctricos)
Define el color difuso de la superficie. Por lo general, los valores reales se encuentran en el rango [10..240] si el valor está codificado entre 0 y 255, o en el rango [0.04.0.94] entre 0 y 1. En la siguiente tabla, se muestran varios ejemplos de colores base para superficies no metálicas.
Metal sRGB Hexadecimal Color Carbón 0,19, 0,19, 0,19 #323232 Goma 0,21, 0,21, 0,21 #353535 Barro 0,33, 0,24, 0,19 #553d31 Madera 0,53, 0,36, 0,24 #875c3c Vegetación 0,48, 0,51, 0,31 #7b824e Ladrillo 0,58, 0,49, 0,46 #947d75 Arena 0,69, 0,66, 0,52 #b1a884 Cemento 0,75, 0,75, 0,73 #c0bfbb - Metales (conductores)
Define el color especular de la superficie. Por lo general, los valores reales se encuentran en el rango [170..255] si el valor está codificado entre 0 y 255, o en el rango [0.66..1.0] entre 0 y 1. En la siguiente tabla, se muestran varios ejemplos de colores base para las superficies metálicas.
Metal sRGB Hexadecimal Color Plateado 0,98; 0,98; 0,96 #faf9f5 Aluminio 0,96; 0,96; 0,96 #f4f5f5 Titanio 0,81, 0,78, 0,76 #cec8c2 Hierro 0,76, 0,74, 0,73 #c0bdba Platino 0,84, 0,82, 0,79 #d6d1c8 Oro 1.00, 0.87, 0.62 #fedc9d Latón 0,96; 0,89; 0,68 #f4e4ad Copper 0,98, 0,85, 0,72 #fbd8b8
Metalizado
La propiedad metallic
define si la superficie es metálica (conductor) o no metálica (eléctrica). Esta propiedad se debe usar como un valor binario, establecido en 0 o 1. Los valores intermedios solo son realmente útiles para crear transiciones entre diferentes tipos de superficies cuando se usan texturas.
Esta propiedad puede cambiar drásticamente el aspecto de una superficie. Las superficies no metálicas tienen reflejo difuso cromático y reflejo acromático (la luz reflejada no cambia de color). Las superficies metálicas no tienen reflejos ni reflejos cromáticos (la luz reflejada adopta el color de la superficie según lo define baseColor
).
El efecto de metallic
se muestra a continuación (haz clic en la imagen para ver una versión más grande).
Aspereza
La propiedad roughness
controla la suavidad percibida de la superficie. Cuando roughness
se establece en 0, la superficie es perfectamente lisa y brillante. Cuanto más gruesa es la superficie, más borroso son los reflejos. Esta propiedad se suele denominar brillante en otros motores y herramientas, y es simplemente lo opuesto a la aspereza (roughness = 1 - glossiness
).
No metales
A continuación, se muestra el efecto de roughness
en superficies no metálicas (haz clic en la imagen para ver una versión más grande).
Metales
El efecto de roughness
en superficies metálicas se muestra a continuación (haz clic en la imagen para ver una versión más grande).
Reflexión
La propiedad reflectance
solo afecta a superficies no metálicas. Esta propiedad se puede usar para controlar la intensidad especular. Este valor se define entre 0 y 1, y representa una reasignación de un porcentaje de reflectancia. Por ejemplo, el valor predeterminado de 0.5 corresponde a una reflexión del 4%. Se deben evitar los valores inferiores a 0.35 (2% de reflexión), ya que ningún material del mundo real tiene una baja reflexión.
A continuación, se muestra el efecto de reflectance
en superficies no metálicas (haz clic en la imagen para ver una versión más grande).
En el siguiente gráfico, se muestran valores comunes y cómo se relacionan con la función de asignación.
En la siguiente tabla, se describen los valores de reflectancia aceptables para varios tipos de materiales (ningún material real tiene un valor inferior al 2%).
Material | Reflexión | Valor de la propiedad |
---|---|---|
Agua | 2% | 0.35 |
Tela | 4% a 5,6% | 0.5 a 0.59 |
Líquidos comunes | 2% a 4% | 0,35 a 0,5 |
Piedras preciosas comunes | 5% a 16% | 0.56 a 1.0 |
Plásticos, vidrio | 4% a 5% | 0.5 a 0.56 |
Otros materiales dieléctricos | 2% a 5% | 0,35 a 0,56 |
Ojos | 2.5% | 0,39 |
Máscara | 2.8% | 0,42 |
Cabello | 4,6% | 0.54 |
Los dientes | 5,8% | 0.6 |
Valor predeterminado | 4% | 0.5 |
Abrigo transparente
Los materiales de varias capas son bastante comunes, en especial los materiales con una capa delgada y translúcida sobre una capa base. Algunos ejemplos reales de este tipo de materiales incluyen pintura para autos, latas de soda, madera laqueada y acrílico.
La propiedad clearCoat
se puede usar para describir materiales con dos capas. La capa transparente del abrigo siempre será isotrópica y dieléctrica. En la siguiente imagen, se compara un material de fibra de carbono con el modelo de material estándar (izquierda) y el modelo de revestimiento transparente (derecha).
La propiedad clearCoat
controla la intensidad de la capa de abrigo transparente. Esto se debe tratar como un valor binario, establecido en 0 o 1. Los valores intermedios son útiles para controlar las transiciones entre las partes de la superficie que tienen capas transparentes y las que no.
A continuación, se muestra el efecto de clearCoat
en un metal duro (haz clic en la imagen para ver una versión más grande).
Aspereza de las capas transparente
La propiedad clearCoatRoughness
es similar a la propiedad roughness
, pero solo se aplica a la capa transparente. Además, debido a que las capas de capa transparentes nunca son completamente ásperas, el valor entre 0 y 1 se vuelve a asignar internamente a una aspereza real de 0 a 0.6.
A continuación, se muestra el efecto de clearCoatRoughness
en un metal duro (haz clic en la imagen para ver una versión más grande).
Anisotropía
Muchos materiales del mundo real, como el metal cepillado, solo se pueden replicar mediante un modelo de reflector anisotrópico. Un material se puede cambiar del modelo isotrópico predeterminado a uno anisotrópico mediante la propiedad anisotropy
. En la siguiente imagen, se compara un material isotrópico (izquierda) y un material anisotrópico (derecha).
A continuación, se muestra el efecto de la variación de anisotropy
de 0.0 (izquierda) a 1.0 (derecha) en un metal aproximado (haz clic en la imagen para ver una versión más grande).
En la siguiente imagen, se muestra cómo se puede controlar la dirección de las zonas anisotrópicas destacadas mediante el uso de valores positivos o negativos: los valores positivos (izquierda) definen la anisotropía en la dirección tangente y los valores negativos (derecha) en la dirección bitangente.
Dirección de la anisotropía
La propiedad anisotropyDirection
define la dirección de la superficie en un punto determinado y, por lo tanto, controla la forma de las zonas brillantes especulares. Se especifica como un vector de 3 valores que, por lo general, provienen de una textura y codifican las direcciones locales en la superficie.
A continuación, se muestra el efecto de renderizar anisotropyDirection
en un metal con un mapa de instrucciones sobre cómo llegar (haz clic en la imagen para ver una versión más grande).
A continuación, se muestra el mapa de indicaciones que se usa para procesar la imagen anterior.
Oclusión del ambiente
La propiedad ambientOcclusion
define qué porción de la luz ambiente puede acceder un punto de superficie. Es un factor de sombra por píxel entre 0.0 (completamente sombreado) y 1.0 (completamente iluminado). Esta propiedad solo afecta la iluminación difusa indirecta (iluminación basada en imágenes), no las luces directas, como las direccionales, de punto y puntuales, ni la iluminación especular. En la siguiente imagen, se comparan materiales sin oclusión del ambiente difuso (izquierda) y con él (derecha).
Normal
La propiedad normal
define la normal de la superficie en un punto determinado. Por lo general, proviene de una textura de mapa normal, que permite variar la propiedad por píxel. La normal se indica en el espacio tangente, lo que significa que +Z apunta fuera de la superficie.
Por ejemplo, imaginemos que queremos renderizar un mueble cubierto con cuero de capitoné. El modelado de la geometría para representar con precisión el patrón de capitonía requeriría demasiados triángulos, por lo que, en su lugar, generaríamos una malla de varios polígonos en un mapa normal. Luego, puedes aplicar el mapa base a una malla simplificada. En la siguiente imagen, se compara una malla simple sin asignación normal (izquierda) y con ella (derecha).
Ten en cuenta que la propiedad normal
afecta a la capa base y no a la capa transparente.
Abrigo normal
La propiedad clearCoatNormal
define la normalidad de la capa de recubrimiento transparente en un punto determinado. De lo contrario, se comporta como la propiedad normal
.
Emisor de luz
La propiedad emissive
se puede usar para simular la luz adicional emitida por la superficie. Se define como un valor float4
que contiene un color RGB (en el espacio lineal) y un valor de compensación de exposición (en el canal alfa).
Aunque un valor de exposición en realidad indica combinaciones de la configuración de la cámara, los fotógrafos suelen usarlos para describir la intensidad de la luz. Esta es la razón por la que las cámaras permiten que los fotógrafos apliquen una compensación de exposición para exponer una imagen o reemplazarla por más. Esta configuración se puede usar para el control artístico, pero también para lograr una exposición adecuada (por ejemplo, la nieve se expondrá como un gris del 18%).
El valor de compensación de exposición de la propiedad de emisión puede usarse para forzar el color de la emisión a mayor brillo (valores positivos) o un valor más oscuro (valores negativos) que la exposición actual. Si el efecto de flor está habilitado, usar una compensación de exposición positiva puede forzar la aparición de la superficie.
Modelo de tela
Todos los modelos de materiales descritos anteriormente están diseñados para simular superficies densas, tanto a nivel macro como micro. Sin embargo, la ropa y las telas suelen estar hechas de hilos sueltos que absorben y dispersan la luz en el incidente. En comparación con las superficies duras, la tela se caracteriza por un lóbulo especular más suave con una gran caída y la presencia de iluminación difusa, causada por las dispersiones hacia adelante y hacia atrás. Algunas telas también muestran colores especulares en dos tonos (por ejemplo, terciopelos).
En la siguiente imagen, se compara la tela del jean procesada con el modelo estándar (izquierda) y el modelo de tela (derecha). Observa cómo el modelo de material estándar no captura la apariencia de una muestra de tela de mezclilla (izquierda). La superficie se ve rígida (casi similar a un plástico), más similar a una lona que un trozo de ropa. Esto también muestra lo importante que es el lóbulo especular más suave, que causa la absorción y la dispersión, para la recreación fiel de la tela.
El terciopelo es un caso de uso interesante para un modelo de material de tela. Como se muestra en la siguiente imagen, este tipo de tela muestra una iluminación de borde fuerte debido a la dispersión hacia adelante y hacia atrás. Estos eventos de dispersión se producen por las fibras de pie en la superficie de la tela. Cuando la luz del incidente provenga de la dirección opuesta a la dirección de la vista, las fibras dispersarán la luz. De manera similar, cuando la luz del incidente proviene de la misma dirección que la vista, las fibras dispersan la luz hacia atrás.
Es importante tener en cuenta que hay tipos de telas que se modelan mejor a través de modelos de materiales de superficie dura. Por ejemplo, el cuero, la seda y el satén se pueden recrear con los modelos de materiales estándar o anisotrópicos.
El modelo de material de tela abarca todos los parámetros definidos anteriormente para el modo de material estándar, excepto los metálicos y los reflejos. También están disponibles dos parámetros adicionales que se describen en la siguiente tabla.
Parámetro | Definición |
---|---|
sheenColor | Tono especular para crear telas especulares en dos tonos (el valor predeterminado es \(\sqrt{baseColor}\)) |
subsurfaceColor | Teñir el color difuso después de la dispersión y la absorción a través del material |
El tipo y el rango de cada propiedad se describen en la siguiente tabla.
Propiedad | Tipo | Range | Nota |
---|---|---|---|
sheenColor | número de punto flotante3 | [0..1] | RGB lineal |
subsurfaceColor | número de punto flotante3 | [0..1] | RGB lineal |
Para crear un material tipo terciopelo, puedes configurar el color base como negro (o oscuro). En cambio, la información de cromaticidad debe establecerse en el color de brillo. Para crear telas más comunes, como vaquero, algodón, etc., usa el color base para la cromaticidad y usa el color de brillo predeterminado o establece el color de brillo en la luminosidad del color base.
Color de brillo
La propiedad sheenColor
se puede usar para modificar directamente la reflexión especular. Ofrece un mejor control sobre la apariencia de la tela y brinda la capacidad de crear materiales especulares en dos tonos.
En la siguiente imagen, se compara la tela azul con y sin (izquierda) y con (rechazo) (haz clic en la imagen para ver una versión más grande).
Color de la superficie
La propiedad subsurfaceColor
no se basa físicamente y se puede usar para simular la dispersión, la absorción parcial y la emisión de luz en ciertos tipos de telas. Esto es particularmente útil para crear telas más suaves.
En la siguiente imagen, se muestra el efecto de subsurfaceColor
. Muestra un paño blanco (columna izquierda) en comparación con un paño blanco con dispersión de la superficie marrón (columna derecha). Haz clic en la imagen para ver una versión más grande.
Modelo sin iluminación
El modelo de material sin iluminación se puede usar para apagar todos los cálculos de iluminación. Su propósito principal es renderizar elementos previamente iluminados, como un mapa de cubo, contenido externo (como un flujo de video o cámara), interfaces de usuario, visualización/depuración, etc. El modelo sin iluminación expone solo dos propiedades que se describen en la siguiente tabla.
Propiedad | Definición |
---|---|
color base | Color difuso de la superficie |
emisivo | Color difuso adicional para simular superficies emisivas. Esta propiedad es útil principalmente en una canalización de HDR con un pase de floración. |
El tipo y el rango de cada propiedad se describen en la siguiente tabla.
Propiedad | Tipo | Range | Nota |
---|---|---|---|
color base | número de punto flotante4 | [0..1] | RGB lineal premultiplicado |
emisivo | número de punto flotante4 | rgb=[0.1], a=N/C | RGB lineal lineal multiplicado |
El valor de emissive
simplemente se agrega a baseColor
cuando está presente. El uso principal de emissive
es forzar la aparición de una superficie sin iluminación si la canalización de HDR está configurada con un pase de floración.
En la siguiente imagen, se muestra un ejemplo del modelo de material sin iluminación que se usa para procesar información de depuración (haz clic en la imagen para ver una versión más grande).
Cómo administrar colores
Colores lineales
Si los datos de color provienen de una textura, asegúrate de usar una textura sRGB para aprovechar la conversión automática de hardware de sRGB a lineal. Si los datos de color se pasan como parámetro al material, puedes convertir el sRGB en lineal al ejecutar el siguiente algoritmo en cada canal de color:
float sRGB_to_linear(float color) {
return color <= 0.04045 ? color / 12.92 : pow((color + 0.055) / 1.055, 2.4);
}
Como alternativa, puedes usar una de las dos versiones más económicas, pero menos precisas, que se muestra a continuación:
// Cheaper
linearColor = pow(color, 2.2);
// Cheapest
linearColor = color * color;
Multiplicado alfa
Un color usa alfa multiplicado previamente si sus componentes RGB se multiplican por el canal alfa:
// Compute pre-multiplied color
color.rgb *= color.a;
Si se toma muestras del color de una textura, simplemente puedes asegurarte de que los datos de textura se multipliquen de antemano. En Android, cualquier textura que se suba desde un Bitmap se multiplicará de forma predeterminada.