Creator描边Shader在WebGL模式下没有效果

如题,项目中需要用到shader对某些节点进行描边,在测试模拟器上,描边正常


但是到网页端的WebGL模式下,不光没有效果,而是整个节点都消失了

Creator版本1.6.1,附上测试代码ShaderTest.zip (212.6 KB)

@zilong @panda

@nantas @natural-law

你参考下这脚本。
ShaderOutline.js.zip (1.8 KB)

两端的gl接口不一样。你要做适配

我也是使用的这个shader,但是在WebGL模式下就没有效果了

是有做适配的,代码如下

setColor:function (_color) {
this.node.ClearShader();
this.color = _color;

this.color_red = this.color.getR();
this.color_green = this.color.getG();
this.color_blue = this.color.getB();

var glProgram = null;
if (cc.sys.isNative) {
    cc.log("use native GLProgram");
    glProgram = new cc.GLProgram();
    glProgram.initWithString(vertShader, fragShader);
    glProgram.link();
    glProgram.updateUniforms();
} else {
    cc.log("use webgl GLProgram");
    glProgram = new cc.GLProgram();
    glProgram.initWithVertexShaderByteArray(vertShader, fragShader);
    glProgram.addAttribute(cc.macro.ATTRIBUTE_NAME_POSITION, cc.macro.VERTEX_ATTRIB_POSITION);
    glProgram.addAttribute(cc.macro.ATTRIBUTE_NAME_COLOR, cc.macro.VERTEX_ATTRIB_COLOR);
    glProgram.addAttribute(cc.macro.ATTRIBUTE_NAME_TEX_COORD, cc.macro.VERTEX_ATTRIB_TEX_COORDS);
    glProgram.link();
    glProgram.updateUniforms();
    glProgram.use();
    glProgram.setUniformLocationWith2f(glProgram.getUniformLocationForName("outlineSize"), this.outlineWidth/this.node.width, this.outlineWidth/this.node.height);
    glProgram.setUniformLocationWith3f(glProgram.getUniformLocationForName("outlineColor"), this.color_red/255, this.color_green/255, this.color_blue/255);
}


this.setProgram(this.node._sgNode, glProgram);

},

setProgram:function (node, glProgram) {
if (cc.sys.isNative) {
var glProgram_state = cc.GLProgramState.getOrCreateWithGLProgram(glProgram);
glProgram_state.setUniformVec2(“outlineSize”, cc.p(this.outlineWidth/this.node.width, this.outlineWidth/this.node.height));
glProgram_state.setUniformVec3(“outlineColor”, {x: this.color_red/255, y: this.color_green/255, z: this.color_blue/255});

    node.setGLProgramState(glProgram_state);
} else {
    node.setShaderProgram(glProgram);
}
var children = node.children;
if (!children) return;

for (var i = 0; i < children.length; i++) {
    this.setProgram(children[i], glProgram);
}

},

附上我所使用的shader

const vertShader = `
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;

varying vec4 v_fragmentColor;
varying vec2 v_texCoord;

void main()
{
gl_Position = CC_PMatrix * a_position;
v_fragmentColor = a_color;
v_texCoord = a_texCoord;
}
const fragShader =
#ifdef GL_ES
precision mediump float;
#endif

varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
uniform vec2 outlineSize;
uniform vec3 outlineColor;

int getIsStrokeWithAngel(float cosangel, float sinangel)
{
int stroke = 0;
float a = texture2D(CC_Texture0, vec2(v_texCoord.x + outlineSize.x * cosangel, v_texCoord.y + outlineSize.y * sinangel)).a; // 这句比较难懂,outlineSize * cos(rad)可以理解为在x轴上投影,除以textureSize.x是因为texture2D接收的是一个0~1的纹理坐标,而不是像素坐标
float num = 1.0;
if (a >= num)
{
stroke = 1;
}
return stroke;
}

void main()
{
vec4 myC = texture2D(CC_Texture0, vec2(v_texCoord.x, v_texCoord.y));
float num = 1.0;
if (myC.a >= num)
{
gl_FragColor = v_fragmentColor * myC;
return;
}
int strokeCount = 0;
strokeCount += getIsStrokeWithAngel( 1.0, 0.0);
strokeCount += getIsStrokeWithAngel( 0.9659258262, 0.2588190451);
strokeCount += getIsStrokeWithAngel( 0.8660254037, 0.5);
strokeCount += getIsStrokeWithAngel( 0.7071067811, 0.7071067811);
strokeCount += getIsStrokeWithAngel( 0.5, 0.8660254037);
strokeCount += getIsStrokeWithAngel( 0.2588190451, 0.9659258262);
strokeCount += getIsStrokeWithAngel( 0.0, 1.0);
strokeCount += getIsStrokeWithAngel(-0.2588190451, 0.9659258262);
strokeCount += getIsStrokeWithAngel(-0.5, 0.8660254037);
strokeCount += getIsStrokeWithAngel(-0.7071067811, 0.7071067811);
strokeCount += getIsStrokeWithAngel(-0.8660254037, 0.5);
strokeCount += getIsStrokeWithAngel(-0.9659258262, 0.2588190451);
strokeCount += getIsStrokeWithAngel(-1.0, 0.0);
strokeCount += getIsStrokeWithAngel(-0.9659258262, -0.2588190451);
strokeCount += getIsStrokeWithAngel(-0.8660254037, -0.5);
strokeCount += getIsStrokeWithAngel(-0.7071067811, -0.7071067811);
strokeCount += getIsStrokeWithAngel(-0.5, -0.8660254037);
strokeCount += getIsStrokeWithAngel(-0.2588190451, -0.9659258262);
strokeCount += getIsStrokeWithAngel(0.0, -1.0);
strokeCount += getIsStrokeWithAngel(0.2588190451, -0.9659258262);
strokeCount += getIsStrokeWithAngel(0.5, -0.8660254037);
strokeCount += getIsStrokeWithAngel(0.7071067811, -0.7071067811);
strokeCount += getIsStrokeWithAngel(0.8660254037, -0.5);
strokeCount += getIsStrokeWithAngel(0.9659258262, -0.2588190451);

if (strokeCount > 0)
{
    myC.rgb = outlineColor;
    myC.a = 1.0;
}

gl_FragColor = v_fragmentColor * myC;

}
`