Cocos2dx 更改sprite色相/饱和度/亮度(HSV)

首先先来了解一下概念

1.RGB模型 RGB是一种加色模式 将不同比例的RED/GREEN/BLUE混合在一起得到新的颜色


三原色混合

2.HSV(HSB)模型 通过色相/饱和度/亮度来得到颜色
H(hue):色相 表示颜色的类型 值域[0,360]
S(Saturation):饱和度 从灰度到纯色 值域[0,1]
V(Value or Brightness):亮度 从黑色到特定饱和度的颜色 值域[0,1]

色相环图


色相环

HSV模型图


这里写图片描述

RGB到HSV的转换公式


这里写图片描述

HSV到RGB的转换公式


这里写图片描述

公式可以参考
http://baike.baidu.com/subview/541362/8445478.htm?fr=aladdin

OK 有了基础知识的储备 下面上shader
colorHSL.fsh

#ifdef GL_ES
precision mediump float;
#endif

varying vec2 v_texCoord;
uniform sampler2D CC_Texture0;
uniform float u_dH;
uniform float u_dS;
uniform float u_dL;

void main() {
    
    vec4 texColor=texture2D(CC_Texture0, v_texCoord);
    float r=texColor.r;
    float g=texColor.g;
    float b=texColor.b;
    float a=texColor.a;
    //convert rgb to hsl
    float h;
    float s;
    float l;
    {
        float max=max(max(r,g),b);
        float min=min(min(r,g),b);
        //----h
        if(max==min){
            
            h=0.0;
        }else if(max==r&&g>=b){
            h=60.0*(g-b)/(max-min)+0.0;
        }else if(max==r&&g0.5){
            s=(max-min)/(2.0-2.0*l);
        }
    }
    //(h,s,l)+(dH,dS,dL) -> (h,s,l)
    h=h+u_dH;
    s=min(1.0,max(0.0,s+u_dS));
    l=l+u_dL;
    //convert (h,s,l) to rgb and got final color
    vec4 finalColor;
    {
        float q;
        if(l<0.5){
            q=l*(1.0+s);
        }else if(l>=0.5){
            q=l+s-l*s;
        }
        float p=2.0*l-q;
        float hk=h/360.0;
        float t[3];
        t[0]=hk+1.0/3.0;t[1]=hk;t[2]=hk-1.0/3.0;
        for(int i=0;i<3;i++){
            if(t[i]<0.0)t[i]+=1.0;
            if(t[i]>1.0)t[i]-=1.0;
        }//got t[I]
        float c[3];
        for(int i=0;i<3;i++){
            if(t[i]<1.0/6.0){
                c[i]=p+((q-p)*6.0*t[I]);
            }else if(1.0/6.0<=t[i]&&t[i]<0.5){
                c[i]=q;
            }else if(0.5<=t[i]&&t[i]<2.0/3.0){
                c[i]=p+((q-p)*6.0*(2.0/3.0-t[i]));
            }else{
                c[i]=p;
            }
        }
        finalColor=vec4(c[0],c[1],c[2],a);
    }

    finalColor+=vec4(u_dL,u_dL,u_dL,0.0);
    
    gl_FragColor=finalColor;
    
}

以下适用COCOS2.2版本

.H中增加以下代码

void setHSLMode();
void setHSL(float h , float s, float l);
void updateHSL();

float m_dH;
float m_dS;
float m_dL;

GLuint m_dHlocation;
GLuint m_dSlocation;
GLuint m_dLlocation;

具体实现

void GameColorSprite::setHSLMode(){

    ccBlendFunc blendFunc={GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA};
    this->setBlendFunc(blendFunc);

    GLchar * fragSource = (GLchar*) CCString::createWithContentsOfFile(CCFileUtils::sharedFileUtils()->fullPathForFilename("colorHSL.fsh").c_str())->getCString();
    
    CGLProgramWithUnifos* pProgram = new CGLProgramWithUnifos();
    pProgram->initWithVertexShaderByteArray(ccPositionTextureColor_vert, fragSource);
    this->setShaderProgram(pProgram);
    pProgram->release();
    
    CHECK_GL_ERROR_DEBUG();
    
    this->getShaderProgram()->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
    this->getShaderProgram()->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color);
    this->getShaderProgram()->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);
    CHECK_GL_ERROR_DEBUG();
    
    this->getShaderProgram()->link();
    CHECK_GL_ERROR_DEBUG();
    
    this->getShaderProgram()->updateUniforms();
    CHECK_GL_ERROR_DEBUG();
    
    m_dHlocation = glGetUniformLocation(getShaderProgram()->getProgram(), "u_dH");
    m_dSlocation = glGetUniformLocation(getShaderProgram()->getProgram(), "u_dS");
    m_dLlocation = glGetUniformLocation(getShaderProgram()->getProgram(), "u_dL");

    updateHSL();
}

void GameColorSprite::setHSL(float h , float s, float l){
    m_dH = h;
    m_dS = s;
    m_dL = l;
    updateHSL();
}
void GameColorSprite::updateHSL(){
    glUniform1f(m_dHlocation,m_dH);
    glUniform1f(m_dSlocation,m_dS);
    glUniform1f(m_dLlocation,m_dL);
}

————————
想要学习Cocos的同学,欢迎关注我的零基础Cocos教程
https://ke.qq.com/course/313749

你可能感兴趣的:(Cocos2dx 更改sprite色相/饱和度/亮度(HSV))