Tutorial: Gradients and colors in Cocos Creator

Gradients and colors in Cocos Creator

This tutorial will demonstrate how to create grandients and change colors of Sprite and `Label objects.

Previewing

Here is a preview of what creating these effects can look like:

97c722babdc7b9b063f76cccf2ba197d9168a61c

How do we do this?

First, add the script ColorAssembler2D to a cc.Sprite or a cc.Label.

Second, adjust the color of the colors parameter. The corresponding position of each point is as follows:

f3409e720057a3174d48ab80eba750c9400bafa5

Third, every cc.RenderComponent has an _assembler parameter.

a1f2e81da27326a6d6450e7242b8da9f830c37ee

As long as this _assembler inherits cc.Assembler2D, there is a method for updateColor.

adf10b14d5b4820f16826099b24b857668ce41ba

Fourth, draw the scoop according to the gourd and modify the color value of the vertex. Example code:


// private _updateColors() {

const cmp = this.getComponent(cc.RenderComponent);

if (!cmp) return;

const _assembler = cmp['_assembler'];

if (!(_assembler instanceof cc['Assembler2D'])) return;

const uintVerts = _assembler._renderData.uintVDatas[0];

if (!uintVerts) return;

const color = this.node.color;

const floatsPerVert = _assembler.floatsPerVert;

const colorOffset = _assembler.colorOffset;

let count = 0;

for (let i = colorOffset, l = uintVerts.length; i < l; i += floatsPerVert) {

uintVerts[i] = (this.colors[count++] || color)['_val'];

}

Fifth, this method needs to be modified after the engine is rendered to be effective. Example:


onEnable() {

cc.director.once(cc.Director.EVENT_AFTER_DRAW, this._updateColors, this);

}

Sixth, ff you remove this component, you must tell the engine to re-render this color. Example:


onDisable() {

cc.director.off(cc.Director.EVENT_AFTER_DRAW, this._updateColors, this);

this.node['_renderFlag'] |= cc['RenderFlow'].FLAG_COLOR;

}

References

Video demonstration

Complete code (see readme)

Original article in Chinese by Bai Yuwubing

6 Likes

@slackmoehrle, Thanks a lot

1 Like

@slackmoehrle Thanks, Iā€™ve been looking at how to create a custom render component for a tiled map to avoid processing tons of nodes. I found some articles but Iā€™m getting lost in the Cocos changes and unsure what is relevant anymore.

For example here https://www.cocos.com/5821?language=en it mentions ā€œcc.Assemblerā€, but it doesnā€™t look like that class is exposed in typescript? Seems the only way to access that is via _assembler on each render component etc. So Iā€™m not really sure how I would recreate something like Cocos TiledMap render component.

Another way which might help with my issue and might be even better was using rendertexture and render all of the tiles in there at the expense of some video memory, but that also doesnā€™t seem to be possible easily. In the C++ Cocos it seems you could just render particular nodes inside the texture.

But in Creator it seems you need to use camera to do anything with render texture, which doesnā€™t fit my case :confused: So Iā€™m a bit stuck how I can output lots of quads/static tiles to form a map layer in efficient manner. I could create a new topic for that I suppose, just thought it was relevant to the cc.Assembler.

Awesome work!

I will be playing around with this later. Without having any exprience with this yet, it looks like from a surface level we will need/want more control about the direction and offset of the gradient, but looks like maybe it can be ā€˜fakedā€™ by using the correct number and arrangement of colors.

However it does seem pretty straight forward that RADIAL gradient is not supported yet?