Jump to content
  • Advertisement
Sign in to follow this  
konnichiwa

Rendering Grayscale, RenderState/TextureState

This topic is 4811 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'm trying to render a sprite (or anything really) to be a Grayscale when i want it to be, I REALLY dont want to edit the texture to make it gray, so I wondered If there was any RenderState / Texture State i can apply to make this work? Thank you very much :)

Share this post


Link to post
Share on other sites
Advertisement
If you're using pixel shaders, it's easy - you just average the red, green, and blue channels, and then set all 3 channels to the same (averaged) value. You could make things more complicated by using the proper luminance values (I don't rmember them, but green is multiplied by 0.3 I think. Red and blue are multipled by different values).

Without pixel shaders, I can't think of any way to do this without modifying the texture, but I'm fairly sure there must be a way. I'd be interested to know too...

Share this post


Link to post
Share on other sites
Hi there konnichiwa,
How are you doing buddy?

The Problem
Setting renderstate to make a texture grayscale

The Solution
I would say the logical and easiest step is just to modify the texture. Unforunately I don't know of any render states that you might be able to set to get this effect but it surely is possible in shaders and if you want more information on that you can check the Post Process sample in the SDK directory,
Source: (SDK root)\Samples\C++\Direct3D\PostProcess

You could probably also fake a kind of grayscale by rendering to texture and modifying the values of each of the vertices in the texture after rendering and then you have your "greyscale" texture.

I hope this helps buddy.
Take care.

Share this post


Link to post
Share on other sites
If you're using pixel shaders, you can convert an RGB color to grayscale by the following:

float fLuminance = 0.299f*color.r + 0.587f*color.g + 0.114f*color.b;
return float4( fLuminance, fLuminance, fLuminance, 1.0f );

Use this luminance value as the RGB colors output from the pixel shader and you get proper grayscale images.

As far as I know, there is no way to do this without using shaders.

neneboricua

Share this post


Link to post
Share on other sites
Quote:
Original post by neneboricua19
If you're using pixel shaders, you can convert an RGB color to grayscale by the following:

float fLuminance = 0.299f*color.r + 0.587f*color.g + 0.114f*color.b;
return float4( fLuminance, fLuminance, fLuminance, 1.0f );

Use this luminance value as the RGB colors output from the pixel shader and you get proper grayscale images.

As far as I know, there is no way to do this without using shaders.

neneboricua


Couldn't you just use SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DOTPRODUCT3) and set ARG1 to the texture and ARG2 to TFACTOR. Then before you render call SetRenderState( D3DRS_TEXTUREFACTOR, dwTFactor) where dwTFactor is the vector (0.299, 0.587, 0.114) packed into a DWORD. I havn't tried it but it may work.


-SirKnight

Share this post


Link to post
Share on other sites
I tried out the effect described by SirKnight and it works perfectly, but you have to use inverted weights for the TFactor (don't ask me why :). I initially used the following C# code, following the instructions:

[source lang=C#]
device.TextureState[0].ColorOperation = TextureOperation.DotProduct3;
device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor;
device.TextureState[0].ColorArgument2 = TextureArgument.TFactor;
device.RenderState.TextureFactor = ( 0xFF << 24 ) | (76 << 16) | (150 << 8) | 29;




This however produced an inverted, but grayscale image in my effect demo. It may be a problem with the renderstates already set by my effects, so I thought I'd post my original result as well. Anyway, here it is:



To fix this inverted color, I simply inverted the TFactor. This gave the correct effect and it also miraculously solved the problem with the articfacts in the shadow volume & billboards in the first picture. So, the code:

[source lang=c#]
device.TextureState[0].ColorOperation = TextureOperation.DotProduct3;
device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor;
device.TextureState[0].ColorArgument2 = TextureArgument.TFactor;
device.RenderState.TextureFactor = ( 0xFF << 24 ) | ( (255-76) << 16) | ( (255-150) << 8) |(255- 29);




and the final effect:

Share this post


Link to post
Share on other sites
Quote:
Original post by SirKnight
Couldn't you just use SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DOTPRODUCT3) and set ARG1 to the texture and ARG2 to TFACTOR. Then before you render call SetRenderState( D3DRS_TEXTUREFACTOR, dwTFactor) where dwTFactor is the vector (0.299, 0.587, 0.114) packed into a DWORD. I havn't tried it but it may work.


-SirKnight
Ooh, that's a sexy way to do it. I'd never think of that. [smile] Ratings++

Share this post


Link to post
Share on other sites
Quote:
Original post by SirKnight
Couldn't you just use SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DOTPRODUCT3) and set ARG1 to the texture and ARG2 to TFACTOR. Then before you render call SetRenderState( D3DRS_TEXTUREFACTOR, dwTFactor) where dwTFactor is the vector (0.299, 0.587, 0.114) packed into a DWORD. I havn't tried it but it may work.

Well done, SirKnight. I had forgotten about the TFACTOR thing. Been doing nothing but shaders for the past couple of years so I tend to forget parts of the fixed function pipeline.

neneboricua

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!