> How to convert 24bit texture to grayscale in realtime?
I don´t think it can be done without fragment programs.
You can make it pseudo-green by using glColorMask() but
not gray.
--
<\___/> For email, remove my socks.
/ O O \
\_____/ FTB. The Cheat is not dead!
> Michał "Wołek" wrote:
>
>> How to convert 24bit texture to grayscale in realtime?
>
> I don´t think it can be done without fragment programs.
>
i'm sure there are some functions that do it
> You can make it pseudo-green by using glColorMask() but
> not gray.
>
i want gray
How do you define "real time"?
> Michał "Wołek" wrote:
>>
>> i want gray
>
> How do you define "real time"?
>
i want to implement that in my game so it MUST be fast enought to
process many frames per second.
Here's a Cg PixelShader for the task.
struct vertex
{
float4 position : POSITION;
float2 texc : TEXCOORD0;
};
struct pixel
{
float4 color : COLOR0;
};
uniform sampler2D texmap;
pixel main(const vertex v)
{
pixel p;
float4 ntsc = float4(0.299,0.587,0.114,0.0);
float4 sample = tex2D(texmap,v.texc);
float gray = dot(sample,ntsc);
p.color = float4(gray,gray,gray,1);
return p;
}
--
-xXx-
Where do you get your texture from ? Is is read from disk or is it
rendered from a buffer ?
> It can be done very fast if you setup a DOT3 texture environment.
> For this to work, the graphics card/driver must support the
> ARB_texture_env_dot3 extension.
>
> Where do you get your texture from ? Is is read from disk or is it
> rendered from a buffer ?
>
both
> ok then I think you should stick to dot3. doesn't dot3 work ?
>
i didn't try it first i must find some manual on net
For the greyscale algorithm, it is something like :
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGB_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_CONSTANT_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
And you have to setup the constant color like this :
GLfloat black_n_white_mapping[4] = {0.33333f, 0.33333f, 0.33333f, 1.0f};
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, black_n_white_mapping);
You can map rgb->b&w with another constant, for instance with {0.1, 0.5,
0.4, 1.0} (note: the alpha is ignored) or whatever RGB triplet you like.
Also note that it looks better if R+G+B=1.
There is a good rgb->b&w mapping function at the www.opengl.org faq. I
don't remember it and I can't check it because my net is dead but I'm
sure you'll find it easily.
that dot3 is signed, so it expand the color values first ( (color-0.5)*2 )
.. in order to get correct grayscale conversion you need to tweak the
incomming values first ( color * 0.5 + 0.5) to keep them in th 0-1 span even
after the expand of the values. That can be done by using 2 more texture
units.. it means that a grayscale conversion costs 3 TMUs.. but if you have
gf3 or better hardware its not a problem.
you can also use nv_reg_combiners instead if you are using nvidias HW..
there you can make sure that the incoming values doesnt expand, and you can
preform it in 1 TMU only.
/Mikael Alfredsson
"Michał "Wołek"" <mail...@poczta.onet.pl> wrote in message
news:Xns937F1ECED7CA08...@213.180.128.20...
You're right about the color dynamic, even though unchanged dot3 would still
give decent results.
However, I think you can do a correct greyscale conversion with dot3 thanks to 2
TMUs, not 3.
Anyway, that's right that if you card supports register combiners, fragment
shaders or fragment programs, you can do it in a different way which *might* use
less instructions.