Archived

This topic is now archived and is closed to further replies.

Greyscale conversion?

This topic is 5074 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am working on a simulator project where we would like to create a moonlit look by converting a scene to grayscale. The textures and materials are all color for daytime views, but we want to wash the color out for night views. What is the best way to do this? Is there a simple way to do this with gamma adjust or render properties?

Share this post


Link to post
Share on other sites
You could always use a pixel shader:

PROS:
Fast on supported HW
Flexible so you could make greyscale or whtever you want.
PS is the future - embrace it now.

CONS:
No SW emulation - you immediatly reduce the number of users who can run it.
Requires low-level programming of HW (complex)
PS is the future - various standards to choose from (1.1,1.4,2.0)

Neil

WHATCHA GONNA DO WHEN THE LARGEST ARMS IN THE WORLD RUN WILD ON YOU?!?!

Share this post


Link to post
Share on other sites
That''ll just make everything darker, nor really washed-out looking.
The only way i can think of is with a Pixel Shader.

Steve
DirectX Programmer
Soon to be the new Bill Gates

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Two sets of textures? To make a greyscal texture you could go through each texture, check the RGB value of the pixel, find an average and then assgin the avg to the RGB, kinda like:

grey = (Red + Green + Blue)/3
pixel = RGB(grey, grey, grey)

This may work, although to do it at realtime would be a pain, maybe write a bitmap converter that does the above, or make make double surfaces for the textures while loading the game, this may work, or I may be off, its been a long day...

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Thisis the AP again, I just tryed making a quick example in Visual Basic, it works very well, but it would be far to slow to use uring runtime, so as I said above it would make sense to make two versions of the bitmap using a converter, or creating while the game is loading. Although if I had a choice I would go with pixel shader.

Share this post


Link to post
Share on other sites

Use the D3DTOP_DOTPRODUCT3 texture stage state. That works fine on any chip which supports it (Permedia3, all GeForces, all Radeons, all Kyros).

You set one source to be the colour as usual, and the other to be TFACTOR. Then you fill TFACTOR with R=G=B=1/3:

// imagine you''ve done your usual colour stuff in stage 0
SetTSS( 1, D3DTSS_COLORARG1, D3DTA_CURRENT );
SetTSS( 1, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3 );
SetTSS( 1, D3DTSS_COLORARG2, D3DTA_TFACTOR );
// mark end of pipe
SetTSS( 2, D3DTSS_COLOROP, D3DTOP_DISABLE );

//
// set the constant to a=0, r=1/3, g=1/3, b=1/3
SetRS( D3DRS_TEXTUREFACTOR, 0x00555555 );


If you want more physically correct luminance (the eye is more receptive to some colour components than others), the REC709 coefficients (for average PC monitor) are r=0.2125, g=0.7154, b=0.0721. Converted to the TEXTUREFACTOR constant (multiply by 255 and convert to hex) it''s: 0x0036B612 [since you have to round some of the coefficients, you lose some precision - really the r,g,b parts of the constant should add up to 255 so I''d an extra 1 to the blue.


I''ll leave working out how the above turns colours into "black and white" as an excercise for the reader. Its good practice for learning how to get the most out of texture blending .



--
Simon O''Connor
Creative Asylum Ltd
www.creative-asylum.com

Share this post


Link to post
Share on other sites
Thank you for your help S1CA. Your approach works well but I am experiencing an effect where the new grayscale textures are blended through as an alpha value. That is, a texture that was previously green is now gray, and thus about 50% transparent. How do I convert to grayscale without changing the alpha value in the original texture?

Share this post


Link to post
Share on other sites
Vertex Shaders:

PROS:
Fast on HW. Fast in SW (just not as fast as HW)
Use to change output colour of vertices for nighttime

CONS:
Probably not as good as S1CA''s method graphically.

Neil


WHATCHA GONNA DO WHEN THE LARGEST ARMS IN THE WORLD RUN WILD ON YOU?!?!

Share this post


Link to post
Share on other sites
quote:
Original post by dragon9
Thank you for your help S1CA. Your approach works well but I am experiencing an effect where the new grayscale textures are blended through as an alpha value. That is, a texture that was previously green is now gray, and thus about 50% transparent. How do I convert to grayscale without changing the alpha value in the original texture?


Ah yes!, I probably should have mentioned that the DOTPRODUCT3 operation copies the result into R, G, B **AND** A.

I assume this is only on polygons which are already translucent anyway - for opaque polygons, the contents of the alpha channel shouldn''t be an issue since you should have D3DRS_ALPHABLENDENABLE=FALSE

Although not always recommended, try closing off the alpha blending pipe a stage earlier than the colour pipe is closed.

i.e.
SetTSS( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
SetTSS( 2, D3DTSS_COLOROP, D3DTOP_DISABLE );


Alternatives if that gives you problems:

1) use an extra stage to restore the alpha to just the texture alpha (assuming you never need to do anything like an ADD with it and the hardware supports it.)

2) if you only need one colour input for whatever you''re doing in stage 0, then you could put the DOTPRODUCT in that stage and use the alpha in stage 1 to restore the alpha. [same idea as #1, but supported on many more chips]




*sigh* if only everyone in the world had pixel shader capable hardware - we could simply apply a write mask to the dp operation. One day...


--
Simon O''Connor
Creative Asylum Ltd
www.creative-asylum.com

Share this post


Link to post
Share on other sites