Materials are used to express how a graphical component (a sprite, tilemap, font, GUI node, model etc) should be rendered.
A material holds tags, information that is used in the rendering pipeline to select objects to be rendered. It also holds references to shader programs that are compiled through the available graphics driver and uploaded to the graphics hardware and run when the component is rendered each frame.
To create a material, right click a target folder in the Assets browser and select New... ▸ Material. (You can also select File ▸ New... from the menu, and then select Material). Name the new material file and press Ok.
The new material will open in the Material Editor.
The material file contains the following information:
render.enable_material()
. The name should be unique.render.predicate()
to collect components that should be drawn together. See the Render documentation on how to do that. The maximum number of tags you can use in a project is 32.Shader constants, or “uniforms” are values that are passed from the engine to vertex and fragment shader programs. To use a constant you define it in the material file as either a Vertex Constant property or a Fragment Constant property. Corresponding uniform
variables need to be defined in the shader program. The following constants can be set in a material:
Example:
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)
Example:
go.set("#sprite", "m", vmath.matrix4())
In order for a material constant of type CONSTANT_TYPE_USER
or CONSTANT_TYPE_MATRIX4
to be available using go.get()
and go.set()
it has to be used in the shader program. If the constant is defined in the material but not used in the program it will be removed from the material and it will not be available at run-time.
Samplers are used to sample the color information from a texture (a tile source or atlas). The color information can then be used for calculations in the shader program.
Sprite, tilemap, GUI and particle effect components automatically gets a sampler2D
set. The first declared sampler2D
in the shader program is automatically bound to the image referenced in the graphics component. Therefore there is currently no need to specify any samplers in the materials file for those components. Furthermore, those component types currently only support a single texture. (If you need multiple textures in a shader, you can use render.enable_texture()
and set texture samplers manually from your render script.)
-- mysprite.fp
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D MY_SAMPLER;
void main()
{
gl_FragColor = texture2D(MY_SAMPLER, var_texcoord0.xy);
}
You can specify a component’s sampler settings by adding the sampler by name in the materials file. If you don’t set up your sampler in the materials file, the global graphics project settings are used.
For model components, you need to specify your samplers in the material file with the settings you want. The editor will then allow you to set textures for any model component that use the 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
declared in the fragment shader.WRAP_MODE_REPEAT
will repeat texture data outside the range [0,1].WRAP_MODE_MIRRORED_REPEAT
will repeat texture data outside the range [0,1] but every second repetition is mirrored.WRAP_MODE_CLAMP_TO_EDGE
will set texture data for values greater than 1.0 to 1.0, and any values less than 0.0 is set to 0.0—i.e. the edge pixels will be repeated to the edge.FILTER_MODE_NEAREST
uses the texel with coordinates nearest the center of the pixel.FILTER_MODE_LINEAR
sets a weighted linear average of the 2x2 array of texels that lie nearest to the center of the pixel.FILTER_MODE_NEAREST_MIPMAP_NEAREST
chooses the nearest texel value within an individual mipmap.FILTER_MODE_NEAREST_MIPMAP_LINEAR
selects the nearest texel in the two nearest best choices of mipmaps and then interpolates linearly between these two values.FILTER_MODE_LINEAR_MIPMAP_NEAREST
interpolates linearly within an individual mipmap.FILTER_MODE_LINEAR_MIPMAP_LINEAR
uses linear interpolation to compute the value in each of two maps and then interpolates linearly between these two values.When the rendering pipeline draws, it pulls constant values from a default system constants buffer. You can create a custom constants buffer to override the default constants and instead set shader program uniforms programmatically in the render script:
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
constant to bright redNote that the buffer’s constant elements are referenced like an ordinary Lua table, but you can’t iterate over the buffer with pairs()
or ipairs()
.
Did you spot an error or do you have a suggestion? Please let us know on GitHub!
GITHUB