// 給節點設定自定義的Shader
cc.Node.prototype.setCustomShader = function (vsh, fsh, enable) {
var node = this;
var children;
var i;
// 現在寫的這些shader在web版中不相容,一下子沒找到相容方法,
// 暫時先把web版屏蔽一下,不然點選之後就不顯示了,不太爽
if (! cc.sys.isNative) {
return;
}
// 判斷是不是widget
if (this.getVirtualRenderer != null && this.getVirtualRenderer().getSprite != null) {
node = this.getVirtualRenderer().getSprite();
} else if (this.getVirtualRenderer != null) {
node = this.getVirtualRenderer();
}
_nodeSetCustomShader(node, vsh, fsh, enable);
children = this.getChildren();
for (i in children) {
if (children[i] instanceof ccui.TextAtlas) {
// todo 高亮效果會導緻數字标簽不顯示,是以暫時屏蔽掉,對效果也沒什麼影響
continue;
}
children[i].setCustomShader(vsh, fsh, enable);
}
//控件内部節點
if (this.getProtectedChildren != null) {
children = this.getProtectedChildren();
for (i in children) {
children[i].setCustomShader(vsh, fsh, enable);
}
}
};
// 給動畫設定Shaer, 動畫的置灰跟普通節點的置灰不太一樣,是以需要特殊設定
ccs.Armature.prototype.setCustomShader = function (vsh, fsh, enable) {
var bones; // 動畫的骨骼
var bone;
var key;
var list, display, i;
// 現在寫的這些shader在web版中不相容,一下子沒找到相容方法,
// 暫時先把web版屏蔽一下,不然點選之後就不顯示了,在太爽
if (! cc.sys.isNative) {
return;
}
bones = this.getBoneDic();
for (key in bones) {
bone = bones[key];
// 因為我們是序列動畫,如果隻取目前顯示的node進行處理的話,隻有當動畫
// 播放到目前幀時才會有效果,播放到其他幀時沒有效果,是以要取整個list進行處理
list = bone.getDisplayManager().getDecorativeDisplayList();
for (i in list) {
display = list[i].getDisplay();
_nodeSetCustomShader(display, vsh, fsh, enable);
}
}
};
// 一個基礎函數,用于實作下面的setCustomShader功能
var _nodeSetCustomShader = function (node, vsh, fsh, enable) {
var nodeProgram, program, _fsh;
if (node == null) {
return;
}
nodeProgram = node.getShaderProgram();
// 建立shader
if (enable === true) {
_fsh = fsh;
// 為ETCA特殊處理一下
if (nodeProgram === cc.shaderCache.getProgram("ShaderPositionTextureColorEtcAlpha_noMVP")) {
node.__alphaTexture = true;
if (_fsh === res.HighlightFsh)
_fsh = res.HighlightEtcaFsh;
}
program = cc.shaderCache.getProgram(vsh + _fsh);
if (program == null) {
program = new cc.GLProgram(vsh, _fsh);
program.link();
program.updateUniforms();
// shader建立後緩存起來,之後要用時每次從緩存中取,之前每次都建立一次,導緻記憶體洩漏
cc.shaderCache.addProgram(program, vsh + _fsh);
}
} else {
if (node.__alphaTexture) {
program = cc.shaderCache.getProgram("ShaderPositionTextureColorEtcAlpha_noMVP");
} else {
program = cc.shaderCache.getProgram("ShaderPositionTextureColor_noMVP");
}
}
if (program != null/* && nodeProgram != null*/)
node.setShaderProgram(program);
};
// 效果腳本
灰化:
gray.fsh
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
void main()
{
vec4 c = v_fragmentColor * texture2D(CC_Texture0, v_texCoord);
gl_FragColor.xyz = vec3(0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b);
gl_FragColor.w = c.w;
}
gray.vsh
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;
#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
#else
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
#endif
void main()
{
gl_Position = CC_PMatrix * a_position;
v_fragmentColor = a_color;
v_texCoord = a_texCoord;
}
// 将一個節點高亮
highlight.fsh
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
void main()
{
vec4 c = v_fragmentColor * texture2D(CC_Texture0, v_texCoord);
gl_FragColor.xyz = c.xyz * 2.0;
gl_FragColor.w = c.w;
}
highlight.vsh
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;
#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
#else
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
#endif
void main()
{
gl_Position = CC_PMatrix * a_position;
v_fragmentColor = a_color;
v_texCoord = a_texCoord;
}
highlightEtca.fsh
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
void main()
{
vec4 v4Colour = texture2D(CC_Texture0, v_texCoord);
v4Colour.a = texture2D(CC_Texture1, v_texCoord).r;
vec4 c = v_fragmentColor * v4Colour;
gl_FragColor.xyz = c.xyz * 2.0;
gl_FragColor.w = c.w;
}
// 将一個節點高亮, 主要是針對IU條件
uihighlight.fsh
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
void main()
{
vec4 c = v_fragmentColor * texture2D(CC_Texture0, v_texCoord);
gl_FragColor.xyz = c.xyz * 1.2;
gl_FragColor.w = c.w;
}
uihighlight.vsh
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;
#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
#else
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
#endif
void main()
{
gl_Position = CC_PMatrix * a_position;
v_fragmentColor = a_color;
v_texCoord = a_texCoord;
}
// 将一個節點按照sin曲線高亮
highlightSin.fsh
#ifdef GL_ES
precision mediump float;
#endif
#define speed 15
#define scale 1.5
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
void main()
{
vec4 c = v_fragmentColor * texture2D(CC_Texture0, v_texCoord);
gl_FragColor.rgb = c.rgb * (1 + abs(sin(CC_Time.x * speed)) * scale);
gl_FragColor.a = c.a;
}
highlightSin.vsh
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;
#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
#else
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
#endif
void main()
{
gl_Position = CC_PMatrix * a_position;
v_fragmentColor = a_color;
v_texCoord = a_texCoord;
}