Referência do material personalizado

O Sceneform fornece definições do Material Design padrão (.sfm) para facilitar que os desenvolvedores recebam resultados incríveis. Os desenvolvedores que querem personalizar profundamente a aparência dos recursos podem criar as próprias definições de material (arquivos *.mat) e aplicá-los aos recursos especificando o atributo source na definição do recurso.

Principais conceitos

Material
Um material define a aparência visual de uma superfície. Para descrever e renderizar completamente uma superfície, um material oferece as seguintes informações:
  • Modelo do Material Design
  • Conjunto de parâmetros nomeados controláveis por uso
  • Estado de varredura (modo de mesclagem, seleção de backface etc.)
  • Código do sombreador de vértices
  • Código do sombreador do fragmento
Modelo do Material Design
Também chamado de modelo de sombreamento ou modelo de iluminação, o modelo do Material Design define as propriedades intrínsecas de uma superfície. Essas propriedades têm influência direta na forma como a iluminação é calculada e, portanto, na aparência de uma superfície.
Definição do Material Design
Um arquivo de texto que descreve todas as informações exigidas por um material. Esta página descreve a estrutura e o formato dos arquivos de definição de material (*.mat) (link em inglês).

Definições dos materiais

Uma definição de material é um arquivo de texto que descreve todas as informações exigidas por um material:

  • Nome
  • Parâmetros do usuário
  • Modelo do Material Design
  • Atributos obrigatórios
  • Interpolantes (chamados de variáveis)
  • Estado de varredura (modo de mesclagem, etc.)
  • Código do sombreador (sombreador de fragmentos, opcionalmente no sombreador de vértices)

Formatar

O formato de definição do material é um formato vagamente baseado em JSON que chamamos de JSONish. No nível superior, uma definição do Material Design é composta por três blocos diferentes que usam a notação de objeto JSON:

material {
    // material properties
}

vertex {
    // vertex shader, optional
}

fragment {
    // fragment shader
}

Uma definição mínima de material viável precisa conter um bloco material e um fragment. O bloco vertex é opcional.

Diferenças com o JSON

No JSON, um objeto é composto por pares de chave-valor. Um par JSON tem a seguinte sintaxe:

"key" : value

Onde o valor pode ser uma string, um número, um objeto, uma matriz ou um literal (true, false ou null). Embora essa sintaxe seja perfeitamente válida em uma definição do material, uma variante sem aspas em torno das strings também é aceita em JSON:

key : value

As aspas continuam obrigatórias quando a string contém espaços.

Os blocos vertex e fragment contêm um código GLSL sem escape e sem aspas, que não é válido no JSON.

Comentários de estilo C++ de linha única são permitidos.

A chave de um par diferencia maiúsculas de minúsculas.

O valor de um par não diferencia maiúsculas de minúsculas.

Exemplo

A lista de código a seguir mostra um exemplo de definição válida do Material Design. Essa definição usa o modelo do Material Design iluminado, usa o modo de mesclagem padrão opaco padrão e requer que um conjunto de coordenadas UV seja apresentado na malha renderizada e define três parâmetros do usuário. As seções a seguir deste documento descrevem os blocos material e fragment em detalhes.

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;
    }
}

Bloco do Material Design

O bloco do Material Design é obrigatório e contém uma lista de pares de propriedades para descrever todos os dados não sombreadores.

name

Tipo
string
Valor
Qualquer string. As aspas duplas são obrigatórias se o nome contém espaços.
Descrição
Define o nome do material. O nome é mantido no momento da execução para fins de depuração.
material {
    name : stone
}

material {
    name : "Wet pavement"
}

shadingModel

Tipo
string
Valor
Qualquer um dos lit, cloth e unlit O padrão é lit.
Descrição
Seleciona o modelo do Material Design conforme descrito na seção Modelos do Material Design.
material {
    shadingModel : unlit
}

parâmetros

Tipo
matriz de objetos de parâmetro
Valor

Cada entrada é um objeto com as propriedades name e type, ambas do tipo string. O nome precisa ser um identificador GLSL válido. O tipo precisa ser um dos descritos na tabela abaixo.

Tipo Descrição
bool Booleano único
Booleano 2 Vetor de 2 booleanos
Booleano 3 Vetor de três booleanos
bool4 Vetor de 4 booleanos
float Variação única
ponto flutuante2 Vetor de dois flutuantes
ponto flutuante 3 Vetor de três flutuantes
ponto flutuante 4 Vetor de 4 flutuantes
int Número inteiro único
int2 Vetor de dois números inteiros
int3 Vetor de três números inteiros
int4 Vetor de quatro números inteiros
sampler2d Textura 2D
samplerExternal Textura externa. Para mais informações, consulte ExternalTexture e setExternalTexture()
Amostras

Os tipos de amostragem também podem especificar um format (o padrão é float) e um precision (o padrão é default). O formato pode ser int, float. A precisão pode ser default (melhor precisão para a plataforma, normalmente high em computadores, medium em dispositivos móveis), low, medium, high.

Descrição

Lista os parâmetros exigidos pelo material. Esses parâmetros podem ser definidos no ambiente de execução usando a API Material do Sceneform' O acesso aos parâmetros dos sombreadores varia de acordo com o tipo de parâmetro:

  • Tipos de samplers: use o nome do parâmetro com o prefixo materialParams_. Por exemplo, materialParams_myTexture.
  • Outros tipos: use o nome do parâmetro como o campo de uma estrutura chamada materialParams. Por exemplo, 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;
    }
}

exige

Tipo
matriz de string
Valor
Cada entrada precisa ser uma destas opções: uv0, uv1, color ou tangents.
Descrição
Lista os atributos de vértice exigidos pelo material. O atributo position é incluído automaticamente e não precisa ser especificado. O atributo tangents é obrigatório automaticamente ao selecionar qualquer modelo de sombreamento que não seja unlit. Consulte as seções de sombreadores deste documento para mais informações sobre como acessar esses atributos dos 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
matriz de string
Valor
Até quatro strings, cada uma precisa ser um identificador GLSL válido.
Descrição
Define interpoladores personalizados (ou variáveis) que são gerados pelo sombreador de vértices do material. Cada entrada da matriz define o nome de um interpolador. O nome completo no sombreador de fragmentos é o nome do interpolador com o prefixo variable_. Por exemplo, se você declarar uma variável chamada eyeDirection, vai poder acessá-la no sombreador de fragmentos usando variable_eyeDirection. No sombreador de vértice, o nome do interpolador é simplesmente um membro da estrutura MaterialVertexInputs (material.eyeDirection no exemplo). Cada interpolador é do tipo float4 (vec4) nos 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);
    }
}

misturando

Tipo
string
Valor
Qualquer um dos valores opaque, transparent, fade, add e masked. O valor padrão é opaque.
Descrição

Define como/se o objeto renderizado é combinado com o conteúdo do destino de renderização. Os possíveis modos de combinação são:

  • Opaco: a combinação é desativada, o canal alfa da saída do material é ignorado.
  • Transparente: a combinação está ativada. A saída do Material Design é composta pelo alfa com o destino de renderização, usando a regra de origem sobre de Porter-Duff. Esse modo de combinação pressupõe o Alfa pré-multiplicado.
  • Esmaecer (link em inglês): funciona como transparent, mas a transparência também é aplicada à luz especular. No modo transparent, os valores Alfa do Material Design só se aplicam à iluminação difusa. Esse modo de combinação é útil para esmaecer objetos com iluminação.
  • Adicionar: a combinação está ativada. A saída do Material Design é adicionada ao conteúdo do destino de renderização.
  • Masked: a combinação é desativada. Esse modo de combinação permite o mascaramento alfa. O canal Alfa da saída do material define se um fragmento é descartado ou não. Consulte a seção maskThreshold para mais informações.
material {
    blending : transparent
}

domínio vértice

Tipo
string
Valor
Qualquer um dos valores object, world, view e device. O padrão é object.
Descrição

Define o domínio (ou espaço de coordenadas) da malha renderizada. O domínio influencia como os vértices são transformados no sombreador de vértice. Os domínios possíveis são:

  • Objeto: os vértices são definidos no espaço de coordenadas do objeto (ou modelo). Os vértices são transformados usando a matriz de transformação do objeto renderizado
  • Mundo: os vértices são definidos no espaço de coordenadas mundial. Os vértices não são transformados usando a transformação do objeto renderizado.
  • Visualização: os vértices são definidos no espaço de coordenadas de visualização (ou olho ou da câmera). Os vértices não são transformados usando a transformação do objeto renderizado.
  • Dispositivo: os vértices são definidos no espaço de coordenadas normalizado do dispositivo (ou clipe). Os vértices não são transformados usando a transformação do objeto renderizado.
material {
    vertexDomain : device
}

interpolação

Tipo
string
Valor
Qualquer um dos smooth, flat O padrão é smooth.
Descrição
Define como os interpoladores (ou variáveis) são interpolados entre os vértices. Quando essa propriedade é definida como smooth, uma interpolação correta de perspectiva é realizada em cada interpolador. Quando definido como flat, nenhuma interpolação é executada e todos os fragmentos dentro de um determinado triângulo ficarão sombreados da mesma forma.
material {
    interpolation : flat
}

seleção

Tipo
string
Valor
Qualquer um dos valores none, front, back e frontAndBack. O padrão é back.
Descrição
Define quais triângulos precisam ser escolhidos: nenhum, triângulos voltados para a frente, triângulos para trás ou todos.
material {
    culling : none
}

ColorWrite

Tipo
boolean
Valor
true ou false O padrão é true.
Descrição
Ativa ou desativa gravações no buffer de cores.
material {
    colorWrite : false
}

profundidade da gravação

Tipo
boolean
Valor
true ou false O padrão é true.
Descrição
Ativa ou desativa gravações no buffer de profundidade.
material {
    depthWrite : false
}

DepthCulling

Tipo
boolean
Valor
true ou false O padrão é true.
Descrição
Ativa ou desativa os testes de profundidade. Quando o teste de profundidade estiver desativado, um objeto renderizado com esse material sempre vai aparecer sobre outros objetos opacos.
material {
    depthCulling : false
}

dupla face

Tipo
boolean
Valor
true ou false O padrão é false.
Descrição
Ativa ou desativa a renderização dupla. Quando definido como true, culling é definido automaticamente como none. Se o triângulo for "voltado", o triângulo será revertido para ficar frontal.
material {
    doubleSided : true
}

transparência

Tipo
string
Valor
Qualquer um dos default, twoPassesOneSide ou twoPassesTwoSides O valor padrão é default.
Descrição
Controla como os objetos transparentes são renderizados. Ela só é válida quando o modo blending não é opaque. Nenhum desses métodos pode renderizar com precisão a geometria cativante, mas, na prática, eles costumam ser bons o suficiente.

Os três modos de transparência possíveis são:

  • default: o objeto transparente é renderizado normalmente, seguindo o modo culling etc.

  • twoPassesOneSide: o objeto transparente é renderizado primeiro no buffer de profundidade e, em seguida, novamente no buffer de cores, em honra ao modo cullling. Isso renderiza efetivamente apenas metade do objeto transparente, como mostrado abaixo.

  • twoPassesTwoSides: o objeto transparente é renderizado duas vezes no buffer de cores: primeiro com os rostos da parte de trás e, em seguida, com os rostos da frente. Esse modo permite renderizar o conjunto de rostos ao reduzir ou eliminar problemas de classificação, como mostrado abaixo. O twoPassesTwoSides pode ser combinado com o doubleSided para melhor efeito.

material {
    transparency : twoPassesOneSide
}

Limite de máscaras

Tipo
number
Valor
Um valor entre 0.0 e 1.0. O padrão é 0.4.
Descrição
Define o valor alfa mínimo que um fragmento precisa ter para não ser descartado quando o modo blending é definido como masked. Quando o modo de combinação não é masked, esse valor é ignorado. Esse valor pode ser usado para controlar a aparência de objetos mascarados por Alfa.
material {
    blending : masked,
    maskThreshold : 0.5
}

Multiplicador de sombra

Tipo
boolean
Valor
true ou false O padrão é false.
Descrição
Disponível apenas no modelo de sombreamento unlit. Se a propriedade estiver ativada, a cor final calculada pelo material será multiplicada pelo fator de sombreamento (ou visibilidade). Isso permite criar objetos transparentes de recebimento de sombra (por exemplo, um plano terrestre invisível em 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 da variante

Tipo
matriz de string
Valor
Cada entrada precisa ser uma destas opções: dynamicLighting, directionalLighting, shadowReceiver ou skinning.
Descrição
Usado para especificar uma lista de variantes do sombreador que as garantias do aplicativo nunca serão necessárias. Essas variantes de sombreador são ignoradas durante a fase de geração de código, reduzindo o tamanho geral do material. Algumas variantes poderão ser filtradas automaticamente. Por exemplo, todas as variantes relacionadas à iluminação (directionalLighting etc.) são filtradas ao compilar um material da unlit. Use o filtro de variantes com cuidado. Filtrar uma variante necessária no momento da execução pode causar falhas.

Descrição das variantes: directionalLighting, usado quando uma luz direcional está presente na cena, dynamicLighting, usada quando uma luz não direcional (ponto, espaço etc.) está presente na cena, shadowReceiver, usada quando um objeto pode receber sombras, skinning, usado quando um objeto é animado usando a skin da GPU

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

Bloco de vértices

O bloco de vértice é opcional e pode ser usado para controlar o estágio de sombreamento de vértice do material. O bloco de vértice precisa conter um código ESSL 3.0 válido (a versão do GLSL compatível com OpenGL ES 3.0). É possível criar várias funções dentro do bloco de vértice, mas é necessário declarar a função materialVertex:

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

Essa função será invocada automaticamente no momento da execução pelo sistema de sombreamento e oferece a capacidade de ler e modificar propriedades do material usando a estrutura MaterialVertexInputs. Essa definição completa da estrutura pode ser encontrada na seção Entradas do vértice do Material Design (link em inglês).

É possível usar essa estrutura para calcular variáveis/interpolantes personalizados ou para modificar o valor dos atributos. Por exemplo, os blocos de vértices a seguir modificam as cores e as coordenadas UV do vértice ao longo do tempo:

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

Além da estrutura MaterialVertexInputs, seu código de sombreamento de vértices pode usar todas as APIs públicas listadas na seção APIs públicas do sombreador.

Entradas de vértice do Material Design

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
};

Bloco de fragmentos

O bloco de fragmentos precisa ser usado para controlar o estágio de sombreamento do fragmento do material. O bloco de fragmentos precisa conter um código ESSL 3.0 válido (a versão do GLSL compatível com OpenGL ES 3.0). É possível criar várias funções dentro do bloco de vértice, mas é necessário declarar a função material:

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

Essa função será invocada automaticamente no momento da execução pelo sistema de sombreamento e oferece a capacidade de ler e modificar propriedades do material usando a estrutura MaterialInputs. Essa definição completa da estrutura pode ser encontrada na seção de entradas do fragmento do Material Design. A definição completa dos vários membros da estrutura pode ser encontrada na seção "Modelos do Material Design" deste documento.

O objetivo da função material() é calcular as propriedades do Material Design específicas do modelo de sombreamento selecionado. Por exemplo, aqui está um bloco de fragmento que cria um metal vermelho brilhante usando o modelo de sombreamento padrão da iluminação:

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;
    }
}

Função prepareMaterial

É necessário chamar prepareMaterial(material) antes de sair da função material(). Essa função prepareMaterial configura o estado interno do modelo do Material Design. Algumas das APIs descritas na seção APIs de fragmentos, como shading_normal, por exemplo, só podem ser acessadas após invocar prepareMaterial().

Também é importante lembrar que a propriedade normal, conforme descrito na seção Entradas de fragmento do Material, tem um efeito somente quando modificada antes de chamar prepareMaterial(). Veja um exemplo de um sombreador de fragmento que modifica corretamente a propriedade normal para implementar um plástico vermelho vermelho com mapeamento de falhas:

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 do Material Design

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)
}

APIs públicas de sombreador

Tipos

Embora os tipos de GLSL possam ser usados diretamente (vec4 ou mat4), recomendamos o uso dos seguintes aliases de tipo:

Nome Tipo de GLSL Descrição
bool2 (link em inglês) bvec2 Um vetor de dois booleanos
bool3 (link em inglês) bvec3 Um vetor de três booleanos
bool 4 bvec4 Um vetor de quatro booleanos
int2 ivec2 Um vetor de dois números inteiros
int3 ivec3 Um vetor de três números inteiros
int4 ivec4 Um vetor de quatro números inteiros
uint2 (link em inglês) uvec2 Um vetor de dois números inteiros sem assinatura
uint3 (link em inglês) Uvec3 Um vetor de três números inteiros sem assinatura
uint4 (link em inglês) Uvc4 Um vetor de quatro números inteiros sem assinatura
float2 (link em inglês) ponto flutuante2 Um vetor de dois flutuantes
float3 (link em inglês) ponto flutuante 3 Um vetor de três flutuantes
float4 (link em inglês) ponto flutuante 4 Um vetor de quatro pontos flutuantes
float4x4 (em inglês) tapete Uma matriz flutuante de 4 x 4
float3x3 (em inglês) tapete Uma matriz flutuante de 3 x 3

Matemática

Nome Tipo Descrição
PI float Uma constante que representa \(\pi\)
HALF_PI (em inglês) float Uma constante que representa \(\frac{\pi}{2}\)
saturate(float x) float Fixa o valor especificado entre 0,0 e 1,0
pow5(float x) float Computação \(x^5\)
sq(float x) float Computação \(x^2\)
max3(float3 v) float Retorna o valor máximo da float3 especificada.
mulMat4x4Float3(float4x4 m, float3 v) ponto flutuante 4 Retorna \(m * v\)
mulMat3x3Float3(float4x4 m, float3 v) ponto flutuante 4 Retorna \(m * v\)

Matrizes

Nome Tipo Descrição
getViewFromWorldMatrix() float4x4 Matriz que converte do espaço mundo para o espaço de visualização/olhos
getWorldFromViewMatrix() float4x4 Matriz que converte do espaço de visualização/olho para o espaço mundial
getClipFromViewMatrix() (link em inglês) float4x4 Matriz que converte o espaço de visualização/olho em um espaço do clipe (NDC, na sigla em inglês).
getViewFromClipMatrix() float4x4 Matriz que faz a conversão do espaço de clipe (NDC, na sigla em inglês) para o espaço de visualização/olho
getClipFromWorldMatrix() float4x4 Matriz que converte o mundo em espaço do clipe (NDC, na sigla em inglês)

Constantes de frame

Nome Tipo Descrição
getResolution(). ponto flutuante 4 Resolução da visualização em pixels: width, height, 1 / width, 1 / height
getWorldCameraPosition(). ponto flutuante 3 Posição da câmera/olho no espaço mundial
getTime() (em inglês) float Tempo em segundos desde que o mecanismo Sceneform foi inicializado, pode ser redefinido regularmente para evitar a perda de precisão
getExposição(). float Exposição fotométrica da câmera
getEV100() (link em inglês) float Valor de exposição em ISO 100 da câmera

Somente vértice

As APIs a seguir estão disponíveis apenas no bloco de vértice:

Nome Tipo Descrição
getPosition(). ponto flutuante 4 Posição do vértice no domínio definido pelo material (padrão: espaço do objeto/modelo)
getWorldFromModelMatrix() float4x4 Matriz que faz a conversão do espaço do modelo (objeto) para o espaço mundial
getWorldFromModelNormalMatrix() flutuante3 x 3 Matriz que converte normais do espaço do modelo (objeto) para o espaço mundial.

Somente fragmento

As APIs a seguir estão disponíveis apenas no bloco de fragmentos:

Nome Tipo Descrição
getWorldTangentFrame() (link em inglês) flutuante3 x 3 Matriz contendo em cada coluna o tangent (frame[0]), bi-tangent (frame[1]) e normal (frame[2]) do vértice no espaço mundial. Se o material não calcular um espaço tangente normal para mapeamento de batidas ou se o sombreamento não for anisotrópico, apenas o normal será válido nessa matriz.
getWorldPosition(). ponto flutuante 3 Posição do fragmento no espaço mundial
getWorldViewVector(). ponto flutuante 3 Vetor normalizado no espaço mundial, da posição do fragmento até o olho
getWorldNormalVector() ponto flutuante 3 normalização normal no espaço do mundo, após o mapeamento de falhas (precisa ser usado após prepareMaterial())
getWorldReflectedVector() ponto flutuante 3 Reflexão do vetor de visualização sobre o normal (precisa ser usado após prepareMaterial())
getNdotV() (link em inglês) float O resultado de dot(normal, view), sempre estritamente maior que 0 (precisa ser usado após prepareMaterial())
getColor(). ponto flutuante 4 Cor intercalada do fragmento se o atributo de cor for obrigatório
getUV0(). ponto flutuante2 Primeiro conjunto interpolado de coordenadas UV, se o atributo uv0 for obrigatório
getUV1(). ponto flutuante2 Primeiro conjunto interpolado de coordenadas UV, se o atributo uv1 for obrigatório
inverseTonemap(float3) ponto flutuante 3 Aplica o operador de mapeamento de tom inverso à cor sRGB linear especificada. Esta operação pode ser uma aproximação
inverseTonemapSRGB(float3) ponto flutuante 3 Aplica o operador de mapeamento de tom inverso à cor sRGB não linear especificada. Esta operação pode ser uma aproximação
luminância(float3) float Calcula a luminância da cor sRGB linear especificada.

Modelos do Material Design

Os materiais de cena podem usar um dos seguintes modelos de material:

  • Lit (ou padrão)
  • Tecido
  • Não iluminada

Modelo do Lit

O modelo iluminado é o modelo de material padrão do Sceneform. Esse modelo de sombreamento físico foi projetado para oferecer boa interoperabilidade com outras ferramentas e mecanismos comuns, como Unity 5, Unreal Engine 4, Substr Designer ou Marmoset Toolbag.

Esse modelo do Material Design pode ser usado para descrever um grande número de superfícies não metálicas (dielétricas) ou superfícies metálicas (condutores).

A aparência de um material usando o modelo padrão é controlada usando as propriedades descritas na tabela abaixo.

Propriedades do modelo padrão

Propriedade Definição
baseColor. Difusão do albedo para superfícies não metálicas e cor especular para superfícies metálicas
metal Se uma superfície parece ser dielétrica (0.0) ou condutor (1.0). Muitas vezes usado como um valor binário (0 ou 1)
aspereza Suavidade percebida (1.0) ou aspereza (0.0) de uma superfície. Superfícies lisas têm reflexos nítidos
refletência Refletão de fresnel na incidência normal de superfícies dielétricas. Isso controla diretamente a força das reflexões
clearCoat (em inglês) Nível de segurança da camada de camada transparente
clearCoatRoughness (link em inglês) Suavidade ou aspereza percebida da camada de brilho transparente
anisotropia Quantidade de anisotrópicas na direção tangente ou bitangente
anisotropyDirection (link em inglês) Direção da superfície local
ambientOcclusion (link em inglês) Define quanto da luz ambiente é acessível a um ponto de superfície. É um fator de sombreamento por pixel entre 0,0 e 1,0
normal Um detalhe normal usado para perturbar a superfície usando o mapeamento de picos (mapeamento normal).
clearCoatNormal Um detalhe normal usado para perturbar a camada de casaco claro usando o mapeamento de saltos (mapeamento normal)
emissivo Albedo difusa adicional para simular superfícies emissivas (como neônios etc.) Esta propriedade é muito útil em um pipeline HDR com um passe de flor

O tipo e o intervalo de cada propriedade estão descritos na tabela abaixo.

Propriedade Tipo Intervalo Observação
baseColor. ponto flutuante 4 [0...1] RGB linear pré-multiplicado
metal float [0...1] Deve ser 0 ou 1
aspereza float [0...1]
refletência float [0...1] Prefira valores > 0,35
clearCoat (em inglês) float [0...1] Deve ser 0 ou 1
clearCoatRoughness (link em inglês) float [0...1] Remapea para [0..0.6]
anisotropia float [-1,1] A anisotropia está na direção tangente quando esse valor é positivo
anisotropyDirection (link em inglês) ponto flutuante 3 [0...1] RGB linear, codifica um vetor de direção no espaço tangente
ambientOcclusion (link em inglês) float [0...1]
normal ponto flutuante 3 [0...1] RGB linear, codifica um vetor de direção no espaço tangente
clearCoatNormal ponto flutuante 3 [0...1] RGB linear, codifica um vetor de direção no espaço tangente
emissivo ponto flutuante 4 rgb=[0..1], a=[-n..n] Alfa é a compensação de exposição

Cor de base

A propriedade baseColor define a cor percebida de um objeto (às vezes chamada de albedo). O efeito da baseColor depende da natureza da superfície, controlada pela propriedade metallic explicada na seção Metalítica.

Não metais (dielétricas)

Define a cor difusa da superfície. Os valores reais normalmente são encontrados no intervalo [10..240] se o valor é codificado entre 0 e 255 ou no intervalo [0.04..0.94] entre 0 e 1. Veja vários exemplos de cores base para superfícies não metálicas na tabela abaixo.

Metal sRGB Codificação Cor
Carvão 0,19, 0,19, 0,19 #323232
 
Borracha 0,21, 0,21, 0,21 #353535
 
Lama 0,33, 0,24, 0,19 #553d31
 
Madeira 0,53, 0,36, 0,24 #875c3c
 
Vegetação 0,48, 0,51, 0,31 #7b824e
 
Brick 0,58, 0,49, 0,46 #947d75
 
Areia 0,69, 0,66, 0,52 #b1a884
 
Concrete 0,75, 0,75, 0,73 #c0bfbb
 
Metais (condutores)

Define a cor especular da superfície. Os valores reais normalmente são encontrados no intervalo [170..255] se o valor é codificado entre 0 e 255 ou no intervalo [0,66..1,0] entre 0 e 1. Veja vários exemplos de cores base para superfícies metálicas na tabela abaixo.

Metal sRGB Codificação Cor
Silver 0,98, 0,98, 0,96 #faf9f5
 
Alumínio 0,96, 0,96, 0,96 #f4f5f5
 
Titânio 0,81, 0,78, 0,76 #cec8c2
 
Ferro 0,76, 0,74, 0,73 #c0bdba
 
Platina 0,84, 0,82, 0,79 #d6d1c8
 
Gold 1,00, 0,87, 0,62 #fedc9d
 
Latão 0,96, 0,89, 0,68 #f4e4ad
 
Copper 0,98, 0,85, 0,72 #fbd8b8
 

Metálico

A propriedade metallic define se a superfície é metálica (condutor) ou não metálica (dielétrica). Essa propriedade precisa ser usada como um valor binário, definido como 0 ou 1. Os valores intermediários só são realmente úteis para criar transições entre diferentes tipos de superfícies ao usar texturas.

Essa propriedade pode mudar drasticamente a aparência de uma superfície. As superfícies não metálicas têm reflexão difusa cromática e reflexo especular acromático. A luz refletida não muda de cor. As superfícies metálicas não têm nenhuma reflexão difusa e reflexo especular cromático. A luz refletida assume a cor da superfície, conforme definido por baseColor.

O efeito de metallic é mostrado abaixo (clique na imagem para ver uma versão maior).

Rugosidade

A propriedade roughness controla a suavidade percebida da superfície. Quando roughness é definido como 0, a superfície é perfeitamente lisa e altamente brilhante. Quanto mais alto for a superfície, mais reflexos eles serão. Essa propriedade costuma ser chamada de brilho em outros mecanismos e ferramentas e é simplesmente o oposto da aspereza (roughness = 1 - glossiness).

Não metais

O efeito de roughness em superfícies não metálicas é mostrado abaixo (clique na imagem para ver uma versão maior dele).

Metais

O efeito de roughness em superfícies metálicas é mostrado abaixo (clique na imagem para ver uma versão maior dele).

Reflita

A propriedade reflectance afeta apenas superfícies não metálicas. Esta propriedade pode ser usada para controlar a intensidade especular. Esse valor é definido entre 0 e 1 e representa um remapeamento de uma porcentagem de refletância. Por exemplo, o valor padrão de 0,5 corresponde a uma reflexão de 4%. Evite valores abaixo de 0,35 (refletência de 2%), já que nenhum material real tem uma reflexão tão baixa.

O efeito de reflectance em superfícies não metálicas é mostrado abaixo (clique na imagem para ver uma versão maior).

O gráfico abaixo mostra valores comuns e como eles se relacionam com a função de mapeamento.

A tabela abaixo descreve valores de refletância aceitáveis para vários tipos de materiais (nenhum material real tem um valor abaixo de 2%).

Material Reflita Valor da propriedade
Água 2% 0,35
Tecido 4% a 5,6% 0,5 a 0,59
Líquidos comuns 2% a 4% 0,35 a 0,5
Pedras preciosas comuns 5% a 16% 0,56 a 1,0
Plásticos, vidros 4% a 5% 0,5 a 0,56
Outros materiais dielétricos 2% a 5% 0,35 a 0,56
Olhos 2,5% 0,39
Aparência 2,8% 0,42
Cabelos 4,6% 0,54
Com dentes 5,8% 0,6
Valor padrão 4% 0,5

Limpar casaco

Materiais de várias camadas são bastante comuns, especialmente materiais com uma camada translúcida fina sobre uma camada de base. Exemplos reais desses materiais incluem tintas para carro, latas de refrigerante, madeira laqueada e acrílico.

A propriedade clearCoat pode ser usada para descrever materiais com duas camadas. A camada de revestimento transparente sempre será isotrópica e dielétrica. A imagem a seguir compara um material de fibra de carbono sob o modelo de material padrão (à esquerda) e com o modelo de casaco claro (à direita).

A propriedade clearCoat controla a intensidade da camada de casaco transparente. Isso deve ser tratado como um valor binário, definido como 0 ou 1. Os valores intermediários são úteis para controlar transições entre partes da superfície que têm camadas de camada claras e partes que não têm.

O efeito de clearCoat em um metal áspero é mostrado abaixo (clique na imagem para ver uma versão maior).

Remover aspereza do casaco

A propriedade clearCoatRoughness é semelhante à propriedade roughness, mas se aplica apenas à camada de casaco transparente. Além disso, como as camadas de camada clara nunca são completamente ágeis, o valor entre 0 e 1 é remapeado internamente para uma aspereza real de 0 a 0,6.

O efeito de clearCoatRoughness em um metal áspero é mostrado abaixo (clique na imagem para ver uma versão maior).

Anisotropy

Muitos materiais do mundo real, como o metal escovado, só podem ser replicados usando um modelo de refletividade anisotrópica. É possível mudar um material do modelo isotrópico padrão para um modelo anisotrópico usando a propriedade anisotropy. A imagem a seguir compara um material isotrópico (à esquerda) e um material antropológico (à direita).

O efeito de variar anisotropy de 0,0 (à esquerda) para 1,0 (à direita) em um metal áspero é mostrado abaixo (clique na imagem para ver uma versão maior).

A imagem abaixo mostra como a direção dos destaques anisotrópicos pode ser controlada usando valores positivos ou negativos: valores positivos (à esquerda) definem a anisotrópica na direção tangente e os valores negativos (à direita) na direção bitbitante.

Direção anisotrópica

A propriedade anisotropyDirection define a direção da superfície em um determinado ponto e, portanto, controla a forma dos destaques especulares. Ela é especificada como um vetor de três valores que geralmente vêm de uma textura, codificando as rotas locais para a superfície.

O efeito da renderização de anisotropyDirection em um metal com um mapa de rotas é mostrado abaixo (clique na imagem para ver uma versão maior).

O mapa de rotas usado para renderizar a imagem acima é mostrado abaixo.

Oclusão do ambiente

A propriedade ambientOcclusion define a quantidade de luz ambiente acessível a um ponto de superfície. É um fator de sombreamento por pixel entre 0,0 (totalmente sombreado) e 1,0 (totalmente iluminado). Essa propriedade afeta apenas a iluminação indireta difusa (com base em imagem), e não luzes diretas, como iluminação direcional, de ponto e ponto, nem iluminação especular. A imagem a seguir compara materiais sem oclusão de ambiente difusa (à esquerda) e com ela (à direita).

Normal

A propriedade normal define o normal da superfície em um determinado ponto. Ela geralmente vem de uma textura de mapa normal, que permite variar a propriedade por pixel. O normal é fornecido no espaço tangente, o que significa que +Z aponta para fora da superfície.

Por exemplo, imagine que vamos renderizar um móvel coberto por couro acolchoado. Modelar a geometria para representar com precisão o padrão acolchoado exigiria muitos triângulos. Em vez disso, colocamos uma malha de alta polígono em um mapa normal. Em seguida, aplique o mapa base a uma malha simplificada. A imagem a seguir compara uma malha simples sem mapeamento normal (à esquerda) e com ela (à direita).

Observe que a propriedade normal afeta a camada de base, e não a camada de bruto.

Limpar casaco normal

A propriedade clearCoatNormal define o normal da camada de casaco claro em um determinado ponto. Ele se comporta de outra forma, como a propriedade normal.

Emissivo

A propriedade emissive pode ser usada para simular outra luz emitida pela superfície. Ela é definida como um valor float4 que contém uma cor RGB (no espaço linear) e um valor de compensação de exposição (no canal Alfa).

Embora o valor de exposição indique combinações de configurações da câmera, ele é geralmente usado pelos fotógrafos para descrever a intensidade da luz. É por isso que as câmeras permitem que os fotógrafos apliquem uma compensação de exposição a uma imagem acima ou abaixo do esperado. Essa configuração pode ser usada para controle artístico, mas também para alcançar uma exposição adequada. Por exemplo, a neve será exposta como 18% cinza-escuro.

O valor de compensação de exposição da propriedade emissiva pode ser usado para forçar a cor emissiva para ser mais clara (valores positivos) ou mais escura (valores negativos) do que a exposição atual. Se o efeito de floração estiver ativado, usar uma compensação de exposição positiva poderá forçar a superfície a florescer.

Modelo de pano

Todos os modelos do Material Design descritos anteriormente foram projetados para simular superfícies densas, em Macro e micro. No entanto, roupas e tecidos são geralmente feitos de fios soltos que absorvem e espalham a luz do incidente. Em comparação com superfícies duras, o tecido é caracterizado por um lobo especular mais suave com uma grande queda e com a presença de iluminação de fuzz, causada pela dispersão para frente/para trás. Alguns tecidos também exibem cores especulares de dois tons, veludos, por exemplo.

A imagem a seguir compara o tecido jeans renderizado usando o modelo padrão (à esquerda) e o modelo de tecido (à direita). Observe como o modelo do Material Design padrão falha para capturar a aparência de uma amostra de tecido jeans (esquerda). A superfície aparenta ser rígida (quase plástico como), o que é mais semelhante a uma lona do que uma peça de vestuário. Isso também mostra a importância do lóbulo especular mais suave causado pela absorção e a dispersão para a recriação fiel do tecido.

O veludo é um caso de uso interessante para um modelo de material de tecido. Como mostrado na imagem abaixo, esse tipo de tecido exibe uma iluminação forte nas bordas devido à dispersão para frente e para trás. Esses eventos de dispersão são causados por fibras retas na superfície do tecido. Quando a luz de incidente vem da direção oposta à direção da visualização, as fibras vão espalhar a luz. Da mesma forma, quando a luz de incidente da mesma direção que a visualização da visualização, as fibras vão espalhar a luz de volta.

É importante observar que há tipos de tecidos que ainda são modelados melhor por modelos de material de superfície rígida. Por exemplo, couro, seda e cetim podem ser recriados usando os modelos de material padrão ou anisotrópicos.

O modelo de material de tecido abrange todos os parâmetros definidos anteriormente para o modo de material padrão, exceto metal e refletor. Dois parâmetros extras descritos na tabela abaixo também estão disponíveis.

Parâmetro Definição
sheenColor Tonalidade especular para criar tecidos especulares com dois tons (o padrão é \(\sqrt{baseColor}\))
subsurfaceColor Tonalidade da cor difusa após a dispersão e a absorção pelo material

O tipo e o intervalo de cada propriedade estão descritos na tabela abaixo.

Propriedade Tipo Intervalo Observação
sheenColor ponto flutuante 3 [0...1] RGB linear
subsurfaceColor ponto flutuante 3 [0...1] RGB linear

Para criar um material semelhante a veludo, a cor base pode ser definida como preto (ou uma cor escura). As informações de cromatografia devem ser definidas na cor do tom. Para criar tecidos mais comuns, como jeans, algodão etc., use a cor de base para a cromática e use a cor padrão do reflexo ou defina a cor do reflexo para a luminância da cor de base.

Cor do tom

A propriedade sheenColor pode ser usada para modificar diretamente a reflexão especular. Ele oferece melhor controle sobre a aparência do tecido e permite a criação de materiais especulares com dois tons.

A imagem a seguir compara o tecido azul com e sem (à esquerda) e com o acúmulo (à direita) (clique na imagem para ver uma versão maior).

Cor do subsolo

A propriedade subsurfaceColor não é física e pode ser usada para simular a dispersão, absorção parcial e reemissão de luz em determinados tipos de tecido. Isso é particularmente útil para criar tecidos mais suaves.

A imagem a seguir demonstra o efeito da subsurfaceColor. Ele mostra um tecido branco (coluna à esquerda) x tecido branco com sabão de subsuperfície marrom (coluna direita). Clique na imagem para ver uma versão maior.

Modelo com iluminação

Esse modelo pode ser usado para desativar todos os cálculos de iluminação. A principal finalidade é renderizar elementos pré-iluminados, como um cubo, conteúdo externo (como um stream de vídeo ou câmera), interfaces do usuário, visualização/depuração etc. O modelo não iluminado expõe apenas duas propriedades descritas na tabela abaixo.

Propriedade Definição
baseColor. Cor da superfície difusa
emissivo É uma cor difusa adicional para simular superfícies emissivas. Esta propriedade é útil principalmente em um pipeline HDR com uma transmissão de flores

O tipo e o intervalo de cada propriedade estão descritos na tabela abaixo.

Propriedade Tipo Intervalo Observação
baseColor. ponto flutuante 4 [0...1] RGB linear pré-multiplicado
emissivo ponto flutuante 4 rgb=[0..1], a=N/A O RGB linear pré-multiplicado é ignorado

O valor de emissive é simplesmente adicionado a baseColor quando presente. O principal uso da emissive é forçar a exibição de uma superfície não iluminada se o pipeline HDR estiver configurado com uma passagem de bloom.

A imagem a seguir mostra um exemplo do modelo do Material Design não iluminado usado para renderizar informações de depuração. Clique na imagem para ver uma versão maior.

Como gerenciar cores

Cores lineares

Se os dados de cores vierem de uma textura, basta usar uma textura sRGB para se beneficiar da conversão automática de hardware de sRGB para linear. Se os dados de cor forem transmitidos como um parâmetro para o material, você poderá converter de sRGB para linear executando o seguinte algoritmo em cada canal de cores:

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

Como alternativa, você pode usar uma das duas versões mais baratas, mas menos precisas, mostradas abaixo:

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

Alfa pré-multiplicado

Uma cor usa a versão Alfa pré-multiplicada se os componentes RGB dela forem multiplicados pelo canal alfa:

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

Se a cor for amostrada de uma textura, basta garantir que os dados da textura sejam pré-multiplicados com antecedência. No Android, qualquer textura enviada de um Bitmap será pré-multiplicada por padrão.