谁知道有什么办法让sprite能做渐变色

mark…

多谢指点!

也可以试试直接修改顶点属性

你的解决方案更屌啊,不止Sprite,连文本都能做渐变,希望让官方把你的功能集成到编辑器里随时能用

shader也可以作用文本.
使用顶点属性的优势是不影响合批.

都已经没有ColorAssembler2D了

效果如下:修改顶点颜色实现,不会打断合批,只要是从cc.RenderComponent派生的都可以绑定;

基于2.4.9实现,如果需要3.x的则前往这里https://forum.cocos.org/t/topic/146839?u=1015130701

源码:

const {ccclass, property, executeInEditMode} = cc._decorator;

/**

  • 渐变顶点;

  • 仅适用于简单(非九切)的非透明渐变;
    */
    @ccclass
    @executeInEditMode
    export default class VertexGradient extends cc.Component
    {
    @property({tooltip:“是否反向”})
    set invert(v)
    {
    if(this._bInvert != v)
    {
    this._bInvert = v;
    this.markColorDirty();
    }
    }

    get invert()
    {
    return this._bInvert;
    }

    @property
    _bInvert:boolean = false;

    @property({type:cc.Enum(GRID_TYPE)})
    set dir(v)
    {
    if(this._dir != v)
    {
    this._dir = v;
    this.markColorDirty();
    }
    }

    get dir()
    {
    return this._dir;
    }

    @property({type:cc.Enum(GRID_TYPE)})
    _dir:GRID_TYPE = GRID_TYPE.GRID_VERTICAL;

    @property(cc.Color)
    set downColor(value)
    {
    if(!this._downColor.equals(value))
    {
    this._downColor.set(value);
    this.markColorDirty();
    }
    }
    get downColor()
    {
    return this._downColor.clone();
    }
    @property(cc.Color)
    private _downColor:cc.Color = cc.Color.WHITE;

    @property(cc.Color)
    set upColor(value)
    {
    if(!this._upColor.equals(value))
    {
    this._upColor.set(value);
    this.markColorDirty();
    }
    }
    get upColor()
    {
    return this._upColor.clone();
    }
    @property(cc.Color)
    private _upColor:cc.Color = cc.Color.WHITE;

    onLoad()
    {
    let render = this.getComponent(cc.RenderComponent);
    render["_updateColor"] = this._updateColor.bind(this);
    this.markColorDirty();
    }

    markColorDirty()
    {
    let render = this.getComponent(cc.RenderComponent);
    render.node["_renderFlag"] |= (cc as any).RenderFlow.FLAG_COLOR | (cc as any).RenderFlow.FLAG_OPACITY;
    }

    _updateColor() {
    let colors = [];
    switch(this.dir)
    {
    case GRID_TYPE.GRID_VERTICAL:
    {
    colors = [this.upColor, this.upColor, this.downColor, this.downColor];
    }
    break;

         case GRID_TYPE.GRID_HORIZONTAL:
             {
                 colors = [this.downColor, this.upColor, this.downColor, this.upColor];
             }
             break;
     }
    
     if(this.invert)
     {
         colors = colors.reverse();
     }
    
     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] = (colors[count++] || color)['_val'];
     }
     cmp.setVertsDirty();
    

    }
    }

因为GRID_TYPE在其他脚本中,这里为了保证脚本独立性,单独分离出来;
export enum GRID_TYPE

{

GRID_HORIZONTAL,

GRID_VERTICAL

}

6赞

非常感谢!,我需要的功能是上部分保持图片原色,下部分渐变透明,就稍微修改了一下
vec4 c =vec4(v_color.r,v_color.g,v_color.b,v_color.a);
c.a = 1.0 - v_uv0.y;
o *= c;

mark,渐变

mark, 渐变色

mark!

渐变色,好用!!!

image
image

官方Shader的HELLO WORLD 就是教你做渐变色:https://docs.cocos.com/creator/3.8/manual/zh/shader/write-effect-2d-sprite-gradient.html

1赞

给4个顶点不一样的颜色,也是一种思路。

最近新加的吧,以前没看到过这种文档

好早就有这个文档了

感谢分享
不过我在编辑器中有成功渐变
但是测试时在浏览器上没有变化

用 shader 的方式,在遇到使用图集时应该会有问题,sprite 在图集里面的 uv 并不是从 0 到 1,修改顶点色应该更通用一点

解决了 ,有遇到的朋友可以参考这篇

https://forum.cocos.org/t/shader/96035/6