使用shader必须关闭深度检测吗?

如题,因为使用了3D场景,因此需要开启深度检测。另外由于子弹的图片如图

为了把黑色部分变为透明,参考了网上一位朋友的Blog使用了shader,具体做法就是将当前像素的alpha值设置为RGB的最大值。 shader代码如下:


#ifdef GL_ES
precision lowp float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
uniform sampler2D u_texture;

void main()
{
    float ratio=0.0;
    vec4 texColor = texture2D(u_texture, v_texCoord);
    ratio = texColor > texColor?(texColor > texColor ? texColor : texColor) :(texColor > texColor? texColor : texColor);
    texColor = ratio;
    gl_FragColor = v_fragmentColor*texColor;
}

然后启用了深度检测后,shader没有作用,如图:

关闭深度检测后就好了,但是人物的Z轴位置不对了(本应该被山丘遮住的部分到了前面),如图:

子弹使用shader的代码为:


bool CCGSpell::initAdditional(void)
{
.......
    CCString* shaderCode = CCString::createWithContentsOfFile(std::string("Shaders/tansparent.fsh"));

    // 加载顶点着色器和片元着色器
    _pShaderProgram = new CCGLProgram();
    _pShaderProgram->initWithVertexShaderByteArray(ccPositionTextureA8Color_vert, shaderCode->getCString());

    // 启用顶点着色器的attribute变量,坐标、纹理坐标、颜色
    _pShaderProgram->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
    _pShaderProgram->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
    _pShaderProgram->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORD);

    // 自定义着色器链接
    _pShaderProgram->link();

    // 设置移动、缩放、旋转矩阵
    _pShaderProgram->updateUniforms();

    return true;
}

void CCGSpell::draw(Renderer *renderer, const Mat4& transform, uint32_t flags)
{
    _insideBounds = (flags & FLAGS_TRANSFORM_DIRTY) ? renderer->checkVisibility(transform, _contentSize) : _insideBounds;

    if (_insideBounds)
    {
        CCASSERT(!_batchNode, "If Sprite is being rendered by CCSpriteBatchNode, CCSprite::draw SHOULD NOT be called");

        _customCommand.init(1);
        _customCommand.func = CC_CALLBACK_0(CCGSpell::onDraw, this, transform, flags);
        _customCommand.setTransparent(true);              // 放入TransparentRenderQueue,相当于开启深度检测。
        renderer->addCommand(&_customCommand);
    }
}

void CCGSpell::onDraw(const Mat4 &transform, uint32_t flags)
{
    // 启用attributes变量输入,顶点坐标,纹理坐标,颜色
    ccGLEnableVertexAttribs(kCCVertexAttribFlag_PosColorTex);

    _pShaderProgram->use();
    _pShaderProgram->setUniformsForBuiltins(transform);

    // 绑定纹理到纹理槽0
    ccGLBindTexture2D(_texture->getName());
    long offset = (long)&_quad;

    // vertex
    int diff = offsetof(V3F_C4B_T2F, vertices);
    glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (void*)(offset + diff));

    // texCoods
    diff = offsetof(V3F_C4B_T2F, texCoords);
    glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (void*)(offset + diff));

    // color
    diff = offsetof(V3F_C4B_T2F, colors);
    glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V3F_C4B_T2F), (void*)(offset + diff));

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    CC_INCREMENT_GL_DRAWS(1);
}

另外试过在渲染子弹的onDraw函数中先关闭深度检测(或者将深度缓存设为只读),画完再开启。但是子弹就看不见了(跑到背景后面去了,因为我所有的sprite都是开启了深度检测)。
难道捕鱼达人3没有开启深度检测吗?求高人解救_(:зゝ∠)_

第一幅图的情况,可能是渲染顺序的问题,试着把子弹的globalzorder调大看看。

谢谢回复,子弹的GlobalZorder是最大的,否则子弹不会在最前面。
TransparentRenderQueue也是按GlobalZorder排序的_(:зゝ∠)_