Pages: [1]   Go Down
  Print  
Author Topic: Bitwise And (&) in HLSL  (Read 4208 times)
February 27, 2008, 06:01:32 pm
I packed some boolean true/false individual bit values into a variable supplied to a shader via the CHANNELVALUE# semantic and am trying to unpack the individual boolean values within the shader to enable filling some bools within the shader code with them and seem to be unable to use the Bitwise And (&) operator to extract them.

Having read the Microsoft documentation on HLSL operators, the & operator seems to be supported, but only for int operands.  There doesn't seem to be any way to read in an int as part of an Object Section slider; the shader ignores it if you try.  It doesn't particularly matter to me how it's necessary to pack the values in, but I know there has to be some means of reading them in within the shader.  If the & operator doesn't work, then I believe I can just figure out how large the float is and do a lot of bit shifting to isolate each bit I need without mangling the original, but I would very much like something cleaner and more general/robust.  I currently have this working with four bits, but I have to pass them in as floats and am pretty certain that I won't always have that many extra CHANNELVALUE# semantic input slots for the shaders I use when I need to do this.  I'd like to be able to use all bits in one float, or at least a half, thereby only needing one input via the semantic, instead of one for each bit - which is grossly inefficient, especially if one wants to add more bits.

Given a known packing pattern, does anyone know how to unpack the bits within a shader and use them as bools?

~Rhys
February 28, 2008, 09:14:36 am
hi !

what if you cast the value to an integer with "asint()" ?
February 28, 2008, 03:05:49 pm
I was trying a straight up C-style cast (int).  I missed the asint() function.  I'll try that and tell you how it went.

EDIT:
Apparently not: asint() and asuint() are not available until shader model 4.  The shader I'm using it in is shader model 1.1 or at most shader model 2.

That does give me an idea, though.  I am unpacking them in the vertex shader.  I wonder whether - since there is software emulation of vertex shader models - it matters which vertex shader model I use...?  Perhaps I can still target the pixel shader to 1.1, but compile the vertex shader for 4 and the shader will run fine on 1.1-only compliant hardware.

Anyone have any other ideas?

~Rhys
February 28, 2008, 07:30:58 pm
All right.  I have resolved this.

I tried bit-shifting and that didn't work, either.  I'm not sure why they have the operators in there if they can't be used until shader model 4...  I can only assume I'm doing something wrong and the number I'm working with is either not an integer, or my syntax is wrong.

After trying that, I remembered how I used to deal with binary numbers in my head while I was going through discrete math.  Given that one knows the maximum number of bits in the given number, you can check for each bit being set by subtracting the value for the largest remaining one recursively.  For example, for a 4 bit number, there are four bits to check: 8, 4, 2, and 1.  The number passed may not be of greater precision (assuming 4 bits, the number processed can be no greater than 15, or this will not work). 

Check the 8 bit:
Subtract 8 from the number; if the result is greater than or equal to 0, then the 8 bit was set; set a boolean to true for this and actually subtract it; else do not subtract and leave the boolean as false.

Check the 4 bit:
Subtract 4 from the number; if the result is greater than or equal to 0, then the 4 bit was set; set a boolean to true for this and actually subtract it; else do not subtract and leave the boolean as false.

Check the 2 bit:
Subtract 2 from the number; if the result is greater than or equal to 0, then the 2 bit was set; set a boolean to true for this and actually subtract it; else do not subtract and leave the boolean as false.

Check the 1 bit:
Subtract 1 from the number; if the result is greater than or equal to 0, then the 1 bit was set; set a boolean to true for this and actually subtract it; else leave the boolean as false.

Perform logic using the set bools.

Example CGR attached.

~Rhys

* Packing.zip (11.63 KB - downloaded 292 times.)
February 29, 2008, 09:53:44 am
Oups ! i did not saw this instuction for shader 4.0 only..
Your code is a bit long to write but i guess it's nearly free to unpack this way, so it's a nice solution.
February 29, 2008, 03:15:56 pm
Yeah, I tried to make it fit into shader model 1.1, and it does fit, but you have to unpack each bool in a separate pass.  It's possible to make the vertex shader = null so you only need to call the pixel shaders, or you can unpack the bools into a float3 or 4 within the vertex shader then use the values within the pixel shaders, or wherever you need them.  Lastly, I tried using the conditions without the bools and the size jumped from ~1300 to ~1600, so, umm... yeah, I put them back Smiley

This is actually not a bad solution if you are strapped for shader inputs but want to be able to set a lot of boolean state variables which would otherwise take up one input apiece.

There are still trade-offs.  If you pass the bools as separate float inputs, then you can use shader model 1.1.  If you pass them with this method, you pretty much need shader model 2.0.

It's a handy piece of code, if I do say so myself.  Maybe I can hop it over to Ben and Kees and see if they can get a node working for ShaderFX.

~Rhys
March 21, 2008, 08:10:44 pm
Finally got some time to post over at Lumonix.  Maybe they will find some use for the code and get it integrated into ShaderFX.

EDIT:
Link: http://lumonixsoftware.com/yabb/YaBB.pl?num=1206126120

~Rhys
Pages: [1]   Go Down
  Print  
 
Jump to: