cocos2dx 更改sprite色相 饱和度 亮度

首先先来了解一下概念

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&&g<b){
            h=60.0*(g-b)/(max-min)+360.0;
        }else if(max==g){
            h=60.0*(b-r)/(max-min)+120.0;
        }else if(max==b){
            h=60.0*(r-g)/(max-min)+240.0;
        }
        //----l
        l=0.5*(max+min);
        //----s
        if(l==0.0||max==min){
            s=0.0;
        }else if(0.0<=l&&l<=0.5){
            s=(max-min)/(2.0*l);
        }else if(l>0.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);
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值