找半天没找到能用的,自己写了个用 shader 实现的渐变效果,仅支持 webgl
// component
cc.Class({
extends: cc.Component,
properties: {
fragmentName: 'Gradient',
from: cc.Color,
to: cc.Color,
},
start() {
this.vertStr = `
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;
varying vec2 v_texCoord;
varying vec4 v_fragmentColor;
void main()
{
gl_Position = CC_PMatrix * a_position;
v_fragmentColor = a_color;
v_texCoord = a_texCoord;
}
`;
// this.colors = [cc.Color.BLUE, cc.Color.YELLOW, cc.Color.ORANGE];
this.program = new cc.GLProgram();
this.loadShader(this.fragmentName, this.setProgram);
},
loadShader (shaderName, callback) {
cc.loader.loadRes('/Shaders/' + shaderName, null, function (err, res) {
if (err) {
console.error('load fail.');
return;
}
var sgNode = this.node.getComponent(cc.Sprite)._sgNode;
callback(sgNode, this.program, this.vertStr, res);
this.setBGGradient();
}.bind(this));
},
setBGGradient () {
// var randomNumber = Math.floor(Math.random() * 3);
// this.from = this.colors[randomNumber];
this.updateUniform();
},
updateUniform() {
this.program.use();
if (cc.sys.isNative) {
var state = cc.GLProgramState.getOrCreateWithGLProgram(this.program);
state.setUniformVec3('from', this.from);
state.setUniformVec3('to', this.to);
}
else {
var from = this.program.getUniformLocationForName('from');
var to = this.program.getUniformLocationForName('to');
var fromNormalized = this.colorNormalized(this.from);
var toNormalized = this.colorNormalized(this.to);
this.program.setUniformLocationWith3f(from, fromNormalized.r, fromNormalized.g, fromNormalized.b);
this.program.setUniformLocationWith3f(to, toNormalized.r, toNormalized.g, toNormalized.b);
}
},
colorNormalized (color) {
var normalized = {r: 0.0, g: 0.0, b: 0.0};
normalized.r = color.r / 255;
normalized.g = color.g / 255;
normalized.b = color.b / 255;
return normalized;
},
setProgram(sgNode, program, vert, frag) {
if (cc.sys.isNative) {
program.initWithString(vert, frag);
}
else {
program.initWithVertexShaderByteArray(vert, frag);
program.addAttribute(cc.macro.ATTRIBUTE_NAME_POSITION, cc.macro.VERTEX_ATTRIB_POSITION);
program.addAttribute(cc.macro.ATTRIBUTE_NAME_COLOR, cc.macro.VERTEX_ATTRIB_COLOR);
program.addAttribute(cc.macro.ATTRIBUTE_NAME_TEX_COORD, cc.macro.VERTEX_ATTRIB_TEX_COORDS);
}
program.link();
program.updateUniforms();
if (cc.sys.isNative) {
var state = cc.GLProgramState.getOrCreateWithGLProgram(program);
sgNode.setGLProgramState(state);
}
else {
sgNode.setShaderProgram(program);
}
},
});
// glsl
#ifdef GL_ES
precision mediump float;
#endif
uniform vec3 from;
uniform vec3 to;
varying vec2 v_texCoord;
void main(void) {
vec2 uv = v_texCoord.xy;
vec3 color = uv.y * to + (1.0 - uv.y) * from;
gl_FragColor = vec4(color, 1.0);
}
3赞
666膜拜大佬
发个效果图see see呗

公司没代码,找了张参考。就是PS里这种渐变,纵向的
好像这种效果我们都是直接用图片资源完成的。。 这两种哪种性能高?我们一直不敢用shader 就怕有性能问题
这能有啥性能问题,只要是webgl都有个默认shader,你看源码就知道了
我指的是帧率 drawcall方面以及在低端机子上的发热上 上次测试了一个shader效果 在低端机子上惨不忍睹 虽然这个比较简单 但是如果量大的话应该也存在这种隐患吧
而且好像2.0没有_sgNode了
哦

这个改顶点色就可以了,不是有这个组件的么
膜拜下大佬~
那组件叫啥
我擦,shader写渐变啊
额,我怎么没找到有修改顶点色的组件
ccc确实没实现 
嗯哼,你的意思是shader重新分配顶点改顶点色么,opengl确实会自动插值颜色
不改shader,设置下4个顶点色就可以了,还可以改变渐变的方向和渐变的位置。
这样就不需要切换shader,贴图用同一张小的纯色贴图的话还可以合批。
cocos2dx原来有个GradientLayer实现渐变的,ccc暂时没实现,可能用的少