Assembler学习记录,以及实现一个简单的颜色渐变效果

Cocos Creator v2.4.10

本来是在尝试 Shader 的学习过程中,接触到了 Assembler 的一些内容:

相比于 Shader 控制每一个像素, Assembler 仅能控制顶点,使其改变形状。

Assembler 优点:效率更高、不会像 Shader 那样在操作 uv 时无法合批。

RenderComponent

cc.Spritecc.Label 都继承自 cc.RenderComponent

const renderComponent = this.node.getComponent(cc.RenderComponent);
console.log(renderComponent);

输出 renderComponent 可以看到他的 _assembler 属性:

1721099997153

_assembler_renderData 存储顶点信息的有:vDatasuintVDatas

iDatas

iDatas 存储的是顶点索引顺序

1721100358775

cc.Spritecc.Label 默认由4个顶点构成,四个顶点的索引顺序如下:

2 3
0 1

左下 => 右下 => 左上 => 右上

GPU渲染的基础单元是三角形,一个正方形由2个三角形组成,iDatas记录的就是三角形的索引顺序。比如图中的就是由 (0, 1, 2)、(1, 3, 2) 两个三角形组成的。

vDatas

vDatas 记录的是顶点信息

1721100999264

每四个为一组,分别为顶点的 x、y、u、v、color。顶点顺序和上面一样也是 左下 => 右下 => 左上 => 右上。

  • x、y:顶点的坐标。.
  • u、v:顶点所对应的图片位置。
  • color:顶点的颜色。

SpritevDatas 信息中 uv 好像并不总是 0-1,暂时不知道是什么问题,具体修改时需要注意。

微信图片_20240716113740

uintVDatas

顶点颜色的需要在 uintVDatas 中的对应位置修改

1721101659470

Assembler 实现 颜色渐变

const {ccclass, property} = cc._decorator;

@ccclass
export default class CornerColorCtrl extends cc.Component {

    @property(cc.Color)
    leftBottom: cc.Color = cc.Color.WHITE;
    @property(cc.Color)
    rightBottom: cc.Color = cc.Color.WHITE;
    @property(cc.Color)
    leftTop: cc.Color = cc.Color.WHITE;
    @property(cc.Color)
    rightTop: cc.Color = cc.Color.WHITE;

    start () {
        cc.director.once(cc.Director.EVENT_AFTER_DRAW, ()=>{
            this.renderColor();
        }, this);
    }

    renderColor() {
        const assembler = renderComponent['_assembler'];
        const renderData = assembler['_renderData'];
        const uintVDatas = renderData['uintVDatas'][0];

        uintVDatas[4] = this.leftBottom['_val'];
        uintVDatas[9] = this.rightBottom['_val'];
        uintVDatas[14] = this.leftTop['_val'];
        uintVDatas[19] = this.rightTop['_val'];
    }
}

修改 assembler 数据的代码需要在引擎首次渲染之后再执行:

cc.director.once(cc.Director.EVENT_AFTER_DRAW, ()=>{
     this.renderColor();
}, this);

效果

1721102185076

1721102210528

参考
CocosCreator Assembler保姆级教程

10赞

mark一下 :grimacing:

mark,大佬就是牛逼

漏了一句 renderComponent 的获取,才发现

renderColor() {
        // 获取 renderComponent 
        const renderComponent = this.node.getComponent(cc.RenderComponent);

        const assembler = renderComponent['_assembler'];
        const renderData = assembler['_renderData'];
        const uintVDatas = renderData['uintVDatas'][0];

        uintVDatas[4] = this.leftBottom['_val'];
        uintVDatas[9] = this.rightBottom['_val'];
        uintVDatas[14] = this.leftTop['_val'];
        uintVDatas[19] = this.rightTop['_val'];
    }

mark assembler

技术插眼
技术插眼