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
eunlit
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
etype
, ambas do tipostring
. 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 umprecision
(o padrão édefault
). O formato pode serint
,float
. A precisão pode serdefault
(melhor precisão para a plataforma, normalmentehigh
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
.
- Tipos de samplers: use o nome do parâmetro com o prefixo
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
outangents
. - Descrição
- Lista os atributos de vértice exigidos pelo material. O atributo
position
é incluído automaticamente e não precisa ser especificado. O atributotangents
é obrigatório automaticamente ao selecionar qualquer modelo de sombreamento que não sejaunlit
. 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 chamadaeyeDirection
, vai poder acessá-la no sombreador de fragmentos usandovariable_eyeDirection
. No sombreador de vértice, o nome do interpolador é simplesmente um membro da estruturaMaterialVertexInputs
(material.eyeDirection
no exemplo). Cada interpolador é do tipofloat4
(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
emasked
. 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 modotransparent
, 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
edevice
. 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 comoflat
, 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
efrontAndBack
. 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
oufalse
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
oufalse
O padrão étrue
.- Descrição
- Ativa ou desativa gravações no buffer de profundidade.
material {
depthWrite : false
}
DepthCulling
- Tipo
boolean
- Valor
true
oufalse
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
oufalse
O padrão éfalse
.- Descrição
- Ativa ou desativa a renderização dupla. Quando definido como
true
,culling
é definido automaticamente comonone
. 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
outwoPassesTwoSides
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 modoculling
etc.twoPassesOneSide
: o objeto transparente é renderizado primeiro no buffer de profundidade e, em seguida, novamente no buffer de cores, em honra ao modocullling
. 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. OtwoPassesTwoSides
pode ser combinado com odoubleSided
para melhor efeito.
material {
transparency : twoPassesOneSide
}
Limite de máscaras
- Tipo
number
- Valor
- Um valor entre
0.0
e1.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 comomasked
. 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
oufalse
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
ouskinning
. - 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 daunlit
. 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.