This translation is community contributed and may not be up to date. We only maintain the English version of the documentation. Read this manual in English
Materiais são usados para expressar como um componente gráfico (um sprite, tilemap, fonte, node GUI, modelo etc.) deve ser renderizado.
Um material contém tags, informações usadas no pipeline de renderização para selecionar objetos que serão renderizados. Ele também contém referências a programas de shader, que são compilados pelo driver gráfico disponível, enviados para o hardware gráfico e executados quando o componente é renderizado a cada frame.
Para criar um material, clique com o botão direito em uma pasta de destino no navegador Conteúdo e selecione Novo... ▸ Material. (Você também pode selecionar Arquivo ▸ Novo... no menu e então selecionar Material). Dê um nome ao novo arquivo de material e pressione Ok.

O novo material será aberto no Material Editor.

O arquivo de material contém as seguintes informações:
render.enable_material(). O nome deve ser único..vp) a usar ao renderizar com o material. O programa de vertex shader é executado na GPU para cada vértice primitivo de um componente. Ele calcula a posição de tela de cada vértice e também pode opcionalmente emitir variáveis “varying”, que são interpoladas e fornecidas como entrada para o fragment program..fp) a usar ao renderizar com o material. O programa é executado na GPU para cada fragmento (pixel) de uma primitiva, e seu objetivo é decidir a cor de cada fragmento. Isso geralmente é feito por consultas de textura e cálculos baseados em variáveis de entrada (variáveis varying ou constantes).render.predicate() para coletar componentes que devem ser desenhados juntos. Veja a documentação de Render para saber como fazer isso. O número máximo de tags que você pode usar em um projeto é 32.Atributos de shader (também chamados de vertex streams ou atributos de vértice) são um mecanismo que define como a GPU recupera vértices da memória para renderizar geometria. O vertex shader especifica um conjunto de streams usando a palavra-chave attribute e, na maioria dos casos, o Defold produz e vincula os dados automaticamente por baixo dos panos com base nos nomes dos streams. No entanto, em alguns casos, talvez você queira encaminhar mais dados por vértice para obter um efeito específico que a engine não produz. Um atributo de vértice pode ser configurado com os seguintes campos:
SEMANTIC_TYPE_COLOR mostrará um seletor de cor no editor, enquanto os dados ainda serão passados como estão da engine para o shader.
SEMANTIC_TYPE_NONE O tipo semântico padrão. Não tem nenhum outro efeito no atributo além de passar os dados do material para o atributo diretamente ao vertex buffer (padrão)SEMANTIC_TYPE_POSITION Produz dados de posição por vértice para o atributo. Pode ser usado junto com espaço de coordenadas para dizer à engine como as posições serão calculadasSEMANTIC_TYPE_TEXCOORD Produz coordenadas de textura por vértice para o atributoSEMANTIC_TYPE_PAGE_INDEX Produz índices de página por vértice para o atributoSEMANTIC_TYPE_COLOR Afeta como o editor interpreta o atributo. Se um atributo for configurado com semântica de cor, um widget seletor de cor será mostrado no inspetorSEMANTIC_TYPE_NORMAL Produz dados de normal por vértice para o atributoSEMANTIC_TYPE_TANGENT Produz dados de tangente por vértice para o atributoSEMANTIC_TYPE_WORLD_MATRIX Produz dados de matriz de mundo por vértice para o atributoSEMANTIC_TYPE_NORMAL_MATRIX Produz dados de matriz normal por vértice para o atributoSEMANTIC_TYPE_TEXTURE_TRANSFORM_2D Produz uma matriz de transformação de textura 3x3 por vértice para o atributo. Para componentes de partículas, a engine fornece uma matriz que transforma coordenadas para o espaço do atlas da propriedade de imagem no componente. Para componentes sprite, a engine fornece uma matriz para cada imagem que o componente está usando (ao usar multi-texturing). Para componentes model, uma matriz identidade é fornecida.TYPE_BYTE Valores byte com sinal de 8 bitsTYPE_UNSIGNED_BYTE Valores byte sem sinal de 8 bitsTYPE_SHORT Valores short com sinal de 16 bitsTYPE_UNSIGNED_SHORT Valores short sem sinal de 16 bitsTYPE_INT Valores inteiros com sinalTYPE_UNSIGNED_INT Valores inteiros sem sinalTYPE_FLOAT Valores de ponto flutuante (padrão)VECTOR_TYPE_SCALAR Valor escalar únicoVECTOR_TYPE_VEC2 Vetor 2DVECTOR_TYPE_VEC3 Vetor 3DVECTOR_TYPE_VEC4 Vetor 4D (padrão)VECTOR_TYPE_MAT2 Matriz 2DVECTOR_TYPE_MAT3 Matriz 3DVECTOR_TYPE_MAT4 Matriz 4DVertex Uma vez por vértice, por exemplo um atributo de posição normalmente será dado à função de vértice por vértice na malha (padrão)Instance Uma vez por instância, por exemplo um atributo de matriz de mundo normalmente será dado à função de vértice uma vez por instânciaAtributos personalizados também podem ser usados para reduzir a pegada de memória na CPU e GPU, reconfigurando os streams para usar um tipo de dado menor ou uma contagem diferente de elementos.
O sistema de materiais atribuirá automaticamente um tipo semântico padrão com base no nome do atributo em tempo de execução para um conjunto específico de nomes:
position - tipo semântico: SEMANTIC_TYPE_POSITIONtexcoord0 - tipo semântico: SEMANTIC_TYPE_TEXCOORDtexcoord1 - tipo semântico: SEMANTIC_TYPE_TEXCOORDpage_index - tipo semântico: SEMANTIC_TYPE_PAGE_INDEXcolor - tipo semântico: SEMANTIC_TYPE_COLORnormal - tipo semântico: SEMANTIC_TYPE_NORMALtangent - tipo semântico: SEMANTIC_TYPE_TANGENTmtx_world - tipo semântico: SEMANTIC_TYPE_WORLD_MATRIXmtx_normal - tipo semântico: SEMANTIC_TYPE_NORMAL_MATRIXmtx_texture_transform_2d - tipo semântico: SEMANTIC_TYPE_TEXTURE_TRANSFORM_2DSe você tiver entradas para esses atributos no material, o tipo semântico padrão será sobrescrito pelo que você tiver configurado no editor de material.
Semelhante às constantes de shader definidas pelo usuário, você também pode atualizar atributos de vértice em tempo de execução chamando go.get, go.set e go.animate:

go.set("#sprite", "tint", vmath.vector4(1,0,0,1))
go.animate("#sprite", "tint", go.PLAYBACK_LOOP_PINGPONG, vmath.vector4(1,0,0,1), go.EASING_LINEAR, 2)
Há algumas ressalvas ao atualizar atributos de vértice, no entanto: se um componente pode ou não usar o valor depende do tipo semântico do atributo. Por exemplo, um componente sprite oferece suporte a SEMANTIC_TYPE_POSITION, então se você atualizar um atributo que tem esse tipo semântico, o componente ignorará o valor sobrescrito, pois o tipo semântico dita que os dados devem sempre ser produzidos pela posição do sprite.
Nos casos em que um atributo de vértice é um escalar ou um tipo de vetor diferente de Vec4, você ainda pode definir os dados usando go.set:
-- Os dois últimos componentes no vec4 não serão usados!
go.set("#sprite", "sprite_position_2d", vmath.vector4(my_x,my_y,0,0))
go.animate("#sprite", "sprite_position_2d", go.PLAYBACK_LOOP_PINGPONG, vmath.vector4(1,2,0,0), go.EASING_LINEAR, 2)
O mesmo vale para atributos de matriz: se o atributo for um tipo de matriz diferente de Mat4, você ainda poderá definir os dados usando go.set.
Usando um atributo de transformação de textura para converter coordenadas UV para espaço de atlas:
#version 140
in vec3 position;
in vec4 texcoord0;
in mat3 texture_transform_2d;
out vec2 var_texcoord0;
void main()
{
// Extrai a posição da transformação
vec2 atlas_pos = texture_transform_2d[2].xy;
// Extrai a escala da transformação
vec2 atlas_size = vec2(
length(texture_transform_2d[0].xy),
length(texture_transform_2d[1].xy)
);
// converte para UV local (0..1)
vec2 localUV = (texcoord0 - atlas_pos) / atlas_size;
// Como alternativa, se as coordenadas UV já estiverem no intervalo 0..1,
// você pode transformar diretamente para espaço de atlas multiplicando a transformação:
vec2 transformedUv = texture_transform_2d * texcoord0;
// Passa o valor para o fragment shader
var_texcoord0 = localUV;
// ... restante do vertex shader
}
Instancing é uma técnica usada para desenhar com eficiência várias cópias do mesmo objeto em uma cena. Em vez de criar uma cópia separada do objeto cada vez que ele é usado, instancing permite que a engine gráfica crie um único objeto e depois o reutilize várias vezes. Por exemplo, em um jogo com uma floresta grande, em vez de criar um modelo de árvore separado para cada árvore, instancing permite criar um modelo de árvore e então posicioná-lo centenas ou milhares de vezes com posições e escalas diferentes. A floresta pode então ser renderizada com uma única draw call em vez de draw calls individuais para cada árvore.
Atualmente, instancing está disponível apenas para componentes Model.
Instancing é habilitado automaticamente quando possível. O Defold depende bastante de batching do estado de desenho tanto quanto possível; para instancing funcionar, alguns requisitos devem ser atendidos:
render.enable_material)Configurar um atributo de vértice para ser repetido por instância exige que Step function seja definido como Instance. Isso é feito automaticamente para certos tipos semânticos com base no nome (veja a tabela Default attribute semantics acima), mas também pode ser definido manualmente no editor de material definindo Step function como Instance.
Como exemplo simples, a cena a seguir tem quatro objetos de jogo, cada um com um componente model:

O material é configurado assim, com um único atributo de vértice personalizado repetido por instância:

O vertex shader tem vários atributos por instância especificados:
// Atributos por vértice
attribute highp vec4 position;
attribute mediump vec2 texcoord0;
attribute mediump vec3 normal;
// Atributos por instância
attribute mediump mat4 mtx_world;
attribute mediump mat4 mtx_normal;
attribute mediump vec4 instance_color;
Observe que mtx_world e mtx_normal serão configurados para usar a step function Instance por padrão. Isso pode ser alterado no editor de material adicionando uma entrada para eles e definindo Step function como Vertex, o que fará o atributo ser repetido por vértice em vez de por instância.
Para verificar que o instancing funciona neste caso, você pode olhar o perfilador web. Neste caso, como a única coisa que muda entre as instâncias da caixa são os atributos por instância, ela pode ser renderizada com uma única draw call:

Em adaptadores gráficos baseados em OpenGL, instancing exige pelo menos OpenGL 3.1 para desktop e OpenGL ES 3.0 para mobile. Isso significa que dispositivos muito antigos usando OpenGL ES2 ou versões mais antigas de OpenGL podem não oferecer suporte a instancing. Nesse caso, a renderização ainda funcionará por padrão sem nenhum cuidado especial do desenvolvedor, mas talvez não tenha o mesmo desempenho que teria se instancing real fosse usado. Atualmente, não há como detectar se instancing é suportado ou não, mas essa funcionalidade será adicionada no futuro para que um material mais barato possa ser usado, ou para que coisas como folhagem ou clutter, que normalmente seriam boas candidatas a instancing, possam ser puladas completamente.
Constantes de shader, ou “uniforms”, são valores passados da engine para programas de vertex e fragment shader. Para usar uma constante, você a define no arquivo de material como uma propriedade Vertex Constant ou Fragment Constant. Variáveis uniform correspondentes precisam ser definidas no programa de shader. As seguintes constantes podem ser definidas em um material:
CONSTANT_TYPE_WORLDCONSTANT_TYPE_VIEWCONSTANT_TYPE_PROJECTIONCONSTANT_TYPE_VIEWPROJCONSTANT_TYPE_WORLDVIEWCONSTANT_TYPE_WORLDVIEWPROJCONSTANT_TYPE_NORMALCONSTANT_TYPE_USERExemplo:
go.set("#sprite", "tint", vmath.vector4(1,0,0,1))
go.animate("#sprite", "tint", go.PLAYBACK_LOOP_PINGPONG, vmath.vector4(1,0,0,1), go.EASING_LINEAR, 2)
CONSTANT_TYPE_USER_MATRIX4Exemplo:
go.set("#sprite", "m", vmath.matrix4())
Para que uma constante de material do tipo CONSTANT_TYPE_USER ou CONSTANT_TYPE_MATRIX4 esteja disponível usando go.get() e go.set(), ela precisa ser usada no programa de shader. Se a constante for definida no material, mas não usada no programa, ela será removida do material e não ficará disponível em tempo de execução.
Samplers são usados para amostrar as informações de cor de uma textura (um tile source ou atlas). As informações de cor podem então ser usadas para cálculos no programa de shader.
Componentes Sprite, tilemap, GUI e efeito de partículas recebem automaticamente um sampler2D definido. O primeiro sampler2D declarado no programa de shader é vinculado automaticamente à imagem referenciada no componente gráfico. Portanto, atualmente não há necessidade de especificar samplers no arquivo de materiais para esses componentes. Além disso, esses tipos de componente atualmente oferecem suporte a apenas uma textura. (Se você precisar de várias texturas em um shader, pode usar render.enable_texture() e definir samplers de textura manualmente a partir do seu script de renderização.)
![]()
-- mysprite.fp
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D MY_SAMPLER;
void main()
{
gl_FragColor = texture2D(MY_SAMPLER, var_texcoord0.xy);
}
Você pode especificar as configurações de sampler de um componente adicionando o sampler pelo nome no arquivo de materiais. Se você não configurar seu sampler no arquivo de materiais, as configurações globais de projeto graphics serão usadas.

Para componentes model, você precisa especificar seus samplers no arquivo de material com as configurações desejadas. O editor então permitirá definir texturas para qualquer componente model que use o material:

-- mymodel.fp
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D TEXTURE_1;
uniform lowp sampler2D TEXTURE_2;
void main()
{
lowp vec4 color1 = texture2D(TEXTURE_1, var_texcoord0.xy);
lowp vec4 color2 = texture2D(TEXTURE_2, var_texcoord0.xy);
gl_FragColor = color1 * color2;
}

sampler2D declarado no fragment shader.WRAP_MODE_REPEAT repetirá dados de textura fora do intervalo [0,1].WRAP_MODE_MIRRORED_REPEAT repetirá dados de textura fora do intervalo [0,1], mas cada segunda repetição será espelhada.WRAP_MODE_CLAMP_TO_EDGE definirá dados de textura para valores maiores que 1.0 como 1.0, e quaisquer valores menores que 0.0 serão definidos como 0.0; ou seja, os pixels da borda serão repetidos até a borda.Default usa a opção de filtro padrão especificada no arquivo game.project em Graphics como Default Texture Min Filter e Default Texture Mag Filter.FILTER_MODE_NEAREST usa o texel com coordenadas mais próximas do centro do pixel.FILTER_MODE_LINEAR define uma média linear ponderada do array 2x2 de texels que ficam mais próximos do centro do pixel.FILTER_MODE_NEAREST_MIPMAP_NEAREST escolhe o valor de texel mais próximo dentro de um mipmap individual.FILTER_MODE_NEAREST_MIPMAP_LINEAR seleciona o texel mais próximo nas duas melhores escolhas de mipmaps mais próximas e então interpola linearmente entre esses dois valores.FILTER_MODE_LINEAR_MIPMAP_NEAREST interpola linearmente dentro de um mipmap individual.FILTER_MODE_LINEAR_MIPMAP_LINEAR usa interpolação linear para calcular o valor em cada um de dois mapas e então interpola linearmente entre esses dois valores.Quando o pipeline de renderização desenha, ele obtém valores de constantes de um buffer padrão de constantes do sistema. Você pode criar um buffer de constantes personalizado para sobrescrever as constantes padrão e, em vez disso, definir programaticamente uniforms do programa de shader no script de renderização:
self.constants = render.constant_buffer() -- <1>
self.constants.tint = vmath.vector4(1, 0, 0, 1) -- <2>
...
render.draw(self.my_pred, {constants = self.constants}) -- <3>
tint para vermelho vivoObserve que os elementos constantes do buffer são referenciados como uma tabela Lua comum, mas você não pode iterar sobre o buffer com pairs() ou ipairs().