材质用以表达可视元素 (sprite, tilemap, font, GUI node, model 等等) 应该如何被渲染.
材质包含 tags, 用来在渲染过程中作为选择渲染对象的依据. 材质还具有 shader programs 这是通过显卡驱动编译好并上传至显卡每帧渲染时要使用的程序.
要创建材质, 在 Assets 浏览器里目标文件夹上 右键点击 然后选择 New... ▸ Material. (还可以从菜单选择 File ▸ New... , 再选择 Material). 给材质命名并点击 Ok.
新材质会在 材质编辑器 里打开.
材质文件包含以下信息:
render.enable_material()
也是使用这个名称. 此名称不能与其他名称重名.render.predicate()
来收集需要渲染的组件. 如何渲染请见 Render documentation. 每个项目最多可以使用32个标签.着色器常量, 或称 “uniforms” 是从引擎传输给顶点和片元着色器程序的数据. 要使用常量,您可以在材质文件中将其定义为一个 顶点常量 属性或 片元常量 属性.需要在着色器程序中定义相应的 uniform
变量.材质中可以设置以下常量:
sprite
, model
, spine
, particlefx
和 tilemap
) 的 .set_constant()
和 .reset_constant()
函数来改变其值. 改变单个组件实例的材质参数会 打破合批增加drawcall.举例:
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)
举例:
go.set("#sprite", "m", vmath.matrix4())
要使 CONSTANT_TYPE_USER
或 CONSTANT_TYPE_MATRIX4
类型的常量能使用 go.get()
和 go.set()
存取, 在着色器程序中必须使用到该常量. 如果常量在材质中定义了却没在着色器程序中使用, 它将被自动删除无法在运行时使用.
采样器用于从纹理 (瓷砖图源或者图集) 中取得颜色数据. 颜色数据用于在着色器程序中参与计算.
Sprite, tilemap, GUI 和 particle effect 组件自动获得 sampler2D
集. 着色程序里第一个声明的 sampler2D
与可视组件所引用的图片自动绑定. 也就是说这些组件不用特地指定材质文件. 而且目前这些组件只支持一个纹理. (如需在着色器中使用多纹理, 可以使用 render.enable_texture()
在渲染脚本中手动设置采样器.)
-- mysprite.fp
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D MY_SAMPLER;
void main()
{
gl_FragColor = texture2D(MY_SAMPLER, var_texcoord0.xy);
}
在材质文件中添加取样器名就指定了一个采样器. 要是材质文件里没有指定, 会使用项目全局设置里的 graphics 设置.
对于3D模型组件, 还要在材质文件里设置采样器属性. 之后编辑器会让你选择使用该材质的3D模型纹理:
-- 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
变量名相匹配.WRAP_MODE_REPEAT
[0,1] 范围之外重复纹理.WRAP_MODE_MIRRORED_REPEAT
[0,1] 范围之外重复纹理, 但是再次重复时使用镜像的纹理.WRAP_MODE_CLAMP_TO_EDGE
把大于 1.0 的值设置为 1.0, 小于 0.0 的值设置为 0.0—也就是说边缘的纹理会扩展开去.FILTER_MODE_NEAREST
使用位于像素中心最近的图素.FILTER_MODE_LINEAR
使用位于像素中心最近的的2x2图素矩阵的加权线性平均值.FILTER_MODE_NEAREST_MIPMAP_NEAREST
使用位于单个mipmap上最近的图素值.FILTER_MODE_NEAREST_MIPMAP_LINEAR
在最近的两个mipmap中选出最近的两个图素再进行线性插值.FILTER_MODE_LINEAR_MIPMAP_NEAREST
在单个mipmap里线性插值.FILTER_MODE_LINEAR_MIPMAP_LINEAR
使用线性插值分别计算两个mipmap再把两个结果进行线性插值.渲染管线工作时, 默认会从系统常量缓存中拉取数据. 也可以建立自定义缓存再把着色器参数在渲染脚本里填充进缓存里去:
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
常量为白色注意常量缓存就是一个普通的 Lua 表, 只是不能使用 pairs()
或 ipairs()
来进行迭代.
Did you spot an error or do you have a suggestion? Please let us know on GitHub!
GITHUB