首先先来了解一下概念
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