Sign in to follow this  
g0nzo

[HLSL] How to check if pixel color is equal to 0?

Recommended Posts

Hi, I've got problem with my app and I'm looking for possible error. In the pixel shader I need to check if value of a pixel is equal to 0 (I use device.ColorFill to reset surface color to black) and if it is, calculate something else, otherwise omit the calculations. Now I've got: if (luminanceSample.r = 0.0f) do something Will it work correctly or is it be better to do somehing like if (luminanceSample.r < 0.00001f) ? BTW. If I got a texture with i.e. 2 channels (G16R16F), but I need to get value of only first channel (R16F is not supported by my card) in the pixel shader - can I do float x = tex2D(...); or do I have to do float2 x = tex2D(...); float y = x.r; ?

Share this post


Link to post
Share on other sites
Hi g0nzo.
if (luminanceSample.r = 0.0f)
won't do what you want, but I presume that was a typo. It should read:
if (luminanceSample.r == 0.0f)

Anyway, the inequality is probably more reliable, and won't cost you any more operations. Rather than comparing with 0.00001f, you should compare with 1.0f / 256, as that is the resolution of 32 bit colour channels.

For your second question, the first snippet won't save you any performance over the second, as texture lookups sample all channels regardless of how many you use. The first piece of code is valid but slightly confusing in my opinion. Personally, I would use
float x = tex2D(...).r

Regards
Admiral

Share this post


Link to post
Share on other sites
Thank you!

Why resolution of 32 bit color is 1/2^8? Does it matter if I have 4x8 bits or 2x16 bits? What about resolution of 64 bit color - is it 1/2^16?

I didn't know that you can do

float x = tex2D(...).r

It surely makes it less confusing. Can I get more values, i.e. tex2D().rb etc.?

BTW. If I have G16R16F texture format, then the first value of float2 is still .r, not .g, right?

Thanks again!

Share this post


Link to post
Share on other sites
Sorry - I assumed you were using A8R8G8B8/R8G8B8A8. Under different channel-packings the resolution varies as you'd expect: the number that follows the R/G/B/A/X is the power to which 2 should be raised. In particular, the 64 bit A16R16G16B16 format does indeed have a resolution of 2^16 per channel.

As for the masking, sure you can turn a float4 into a float2 by appending .rb. You could equivalently use .xz for non-colour vector values (in fact, the two are equivalent, but you should use the appropriate notation for clarity). And no, the channel packing doesn't affect the masking notation, which can make it rather confusing.
On a similar vein, you can switch the channels/components as they are extracted in a single instruction using swizzling. For example, I could write
float2 transposed_projected_position = IN.position.yx
There are certain rules you must obey when swizzling (for instance, you couldn't use .wxzy) but on the whole, anything that's useful is legal.

Regards
Admiral

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this