기본 OpenGL을 프레임 버퍼는 명시 적 포화를 저장하지 않는 RGB의 색 공간을 사용합니다. 채도를 추출하고 수정 한 다음 다시 변경하는 방법이 필요합니다.
이전에 RGB 벡터 길이를 사용하여 휘도를 0으로 표현한 나의 이전 제안은 올바르지 않았습니다. 스케일링을 고려하지 않았기 때문에 사과드립니다.
새로운 짧은 코드 조각은 FreeNode/IRC의 ## opengl 및 ## opengl3에서 일반 사용자 "RTFM_FTW"에게 전달되며 값 비싼 RGB-> HSV-> RGB를 계산하지 않고도 채도를 직접 수정할 수 있습니다 변환, 정확히 원하는 것입니다. HSV 코드가 귀하의 질문에 비해 열등하지만, 그대로 두겠습니다. 방금 채도보다 더 많은 제어를 원하는 경우
void main(void)
{
vec3 R0 = texture2DRect(S, gl_TexCoord[0].st).rgb;
gl_FragColor = vec4(mix(vec3(dot(R0, vec3(0.2125, 0.7154, 0.0721))),
R0, T), gl_Color.a);
}
, 당신은 HSL 또는 HSV 색 공간으로 변환해야합니다. 아래 그림과 같이 GLSL 조각 셰이더를 사용합니다.
GLSL v1.30 기능 사용법을 배우려면 http://www.opengl.org/registry에서 OpenGL 3.0 및 GLSL 1.30 사양을 읽어보십시오.
#version 130
#define RED 0
#define GREEN 1
#define BLUE 2
in vec4 vertexIn;
in vec4 colorIn;
in vec2 tcoordIn;
out vec4 pixel;
Sampler2D tex;
vec4 texel;
const float epsilon = 1e-6;
vec3 RGBtoHSV(vec3 color)
{
/* hue, saturation and value are all in the range [0,1> here, as opposed to their
normal ranges of: hue: [0,360>, sat: [0, 100] and value: [0, 256> */
int sortindex[3] = {RED,GREEN,BLUE};
float rgbArr[3] = float[3](color.r, color.g, color.b);
float hue, saturation, value, diff;
float minCol, maxCol;
int minIndex, maxIndex;
if(color.g < color.r)
swap(sortindex[0], sortindex[1]);
if(color.b < color.g)
swap(sortindex[1], sortindex[2]);
if(color.r < color.b)
swap(sortindex[2], sortindex[0]);
minIndex = sortindex[0];
maxIndex = sortindex[2];
minCol = rgbArr[minIndex];
maxCol = rgbArr[maxIndex];
diff = maxCol - minCol;
/* Hue */
if(diff < epsilon){
hue = 0.0;
}
else if(maxIndex == RED){
hue = ((1.0/6.0) * ((color.g - color.b)/diff)) + 1.0;
hue = fract(hue);
}
else if(maxIndex == GREEN){
hue = ((1.0/6.0) * ((color.b - color.r)/diff)) + (1.0/3.0);
}
else if(maxIndex == BLUE){
hue = ((1.0/6.0) * ((color.r - color.g)/diff)) + (2.0/3.0);
}
/* Saturation */
if(maxCol < epsilon)
saturation = 0;
else
saturation = (maxCol - minCol)/maxCol;
/* Value */
value = maxCol;
return vec3(hue, saturation, value);
}
vec3 HSVtoRGB(vec3 color)
{
float f,p,q,t, hueRound;
int hueIndex;
float hue, saturation, value;
vec3 result;
/* just for clarity */
hue = color.r;
saturation = color.g;
value = color.b;
hueRound = floor(hue * 6.0);
hueIndex = int(hueRound) % 6;
f = (hue * 6.0) - hueRound;
p = value * (1.0 - saturation);
q = value * (1.0 - f*saturation);
t = value * (1.0 - (1.0 - f)*saturation);
switch(hueIndex)
{
case 0:
result = vec3(value,t,p);
break;
case 1:
result = vec3(q,value,p);
break;
case 2:
result = vec3(p,value,t);
break;
case 3:
result = vec3(p,q,value);
break;
case 4:
result = vec3(t,p,value);
break;
default:
result = vec3(value,p,q);
break;
}
return result;
}
void main(void)
{
vec4 srcColor;
vec3 hsvColor;
vec3 rgbColor;
texel = Texture2D(tex, tcoordIn);
srcColor = texel*colorIn;
hsvColor = RGBtoHSV(srcColor.rgb);
/* You can do further changes here, if you want. */
hsvColor.g = 0; /* Set saturation to zero */
rgbColor = HSVtoRGB(hsvColor);
pixel = vec4(rgbColor.r, rgbColor.g, rgbColor.b, srcColor.a);
}
"v"가 정의되지 않았습니다. hsv2rgb에 대한 다른 알고리즘을 보면 이것이 실제로 "값"이어야합니다. 또한 마지막 사례 문 (사례 5)도 기본 사례 여야합니다. –