当渲染纹理多边形的场景,我想是能够以原始的色彩和“灰度级”模式渲染之间切换。我一直在努力实现这一目标用融合和色彩矩阵运算;没有它的工作(与融合我找不到glBlendFunc()是取得了一些类似远程到我想要的东西,和彩色矩阵运算的 ...在这里讨论)。

想到的(而且是相当昂贵的)一个解决办法是捕捉画面的每一帧,并将所得纹理转化为灰度一个和显示,而不是...(如果我说我灰阶实际上意味着有什么低饱和度,但我猜大多数可能的解决方案也不会不同于灰阶所有的东西)。

其他什么可以怎么做?

有帮助吗?

解决方案

默认的OpenGL帧缓冲器使用RGB颜色空间,其中不存储一个明确的饱和度。你需要提取的饱和度,修改它的方法,然后再改回来。

我以前的它简单地使用的RGB矢量长度的建议来表示亮度0是不正确的,因为它没有考虑缩放考虑,我道歉。

信贷新一小段转到普通用户“RTFM_FTW”从FreeNode的/ IRC ## OpenGL和## opengl3,它可以让你直接修改不饱和计算昂贵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片段着色器如下所示。

读取的可用的OpenGL 3.0和GLSL 1.30规范上 http://www.opengl.org/registry学习如何使用GLSL V1.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);
}

其他提示

如果你对一个现代的OpenGL足够的工作,我会说像素着色器这里是一个非常合适的解决方案。无论挂接到每个多边形的阴影,因为他们渲染,或在第二遍,只是读取每个像素,转换为灰度,并将其写回做一个全屏幕四。除非你的分辨率,图形硬件,和目标帧率是有点“极值”,这应该是在大多数情况下是可行的这些日子。

有关大多数桌面渲染到纹理是不贵了,所有的compiz,航空等和类似开花或在最近的标题可见景深效果依赖于它。

其实你不转换屏幕材质本身为灰度,你想绘制纹理和片段着色器转化valures到灰度的卵石大小的方形。

另一种选择是有两套片段着色的为你的三角形,一个仅仅复制gl_FrontColor属性作为固定功能pieline会和另一写入的灰度值到屏幕缓冲器。

一个第三选项可能被索引颜色模式,如果设置UUP灰度调色板,但是模式可能过时,由现在很差支撑;再加上你失去了很多的功能,例如混合,如果我没有记错。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top