Referencia de material personalizado

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 es lit.
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 y type, ambas del tipo string. 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 es float) y un precision (el valor predeterminado es default). El formato puede ser uno de int, float. La precisión puede ser una de las default (la mejor precisión para la plataforma, que suele ser high en computadoras de escritorio, medium en dispositivos móviles), low, medium y high.

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.
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 o tangents.
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 atributo tangents es obligatorio de forma automática cuando se selecciona cualquier modelo de sombreado que no sea unlit. 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 llamada eyeDirection, puedes acceder a ella en el sombreador de fragmentos mediante variable_eyeDirection. En el sombreador de vértices, el nombre del interpolador es simplemente un miembro de la estructura MaterialVertexInputs (material.eyeDirection en tu ejemplo). Cada interpolador es del tipo float4 (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 es opaque.
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 modo transparent, 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 es object.
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 es smooth.
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 en flat, 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 es back.
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 o false. La configuración predeterminada es true.
Descripción
Habilita o inhabilita las escrituras en el búfer de color.
material {
    colorWrite : false
}

depthWrite

Tipo
boolean
Valor
true o false. La configuración predeterminada es true.
Descripción
Habilita o inhabilita las escrituras en el búfer de profundidad.
material {
    depthWrite : false
}

pelolargo

Tipo
boolean
Valor
true o false. La configuración predeterminada es true.
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 o false. La configuración predeterminada es false.
Descripción
Habilita o inhabilita el procesamiento bilateral. Cuando se establece en true, culling se establece automáticamente en none; 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 o twoPassesTwoSides. La configuración predeterminada es default.
Descripción
Controla cómo se renderizan los objetos transparentes. Solo es válido cuando el modo blending no es opaque. 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 modo culling, 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 modo cullling. 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 con doubleSided para lograr un mejor efecto.

material {
    transparency : twoPassesOneSide
}

umbraldemáscara

Tipo
number
Valor
Un valor entre 0.0 y 1.0. La configuración predeterminada es 0.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 en masked. Cuando el modo de combinación no es masked, 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 o false. La configuración predeterminada es false.
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 o skinning.
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 de unlit. 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.