Recommended Posts

is it possible? I am using directx 9.0 and as far as I know binary operations are not supported in dx9
I want to do something like that
WORD x, y;
DWORD z;
z = x<<16 | y;
but on HLSL and using floats.
The reason is I want to store both color and normal of each pixel in a texture. I can do that using two textures but two rendering is very slow for me. Is there any other alternative for that?

Share this post

Link to post

Share on other sites

I ran into a similar issue recently and as far as I know, this is not supported. At least the FX compiler complained that << is an unexpected token. From my Googling, I learned that bitwise operators are only supported in SM4 and onwards.

You could use Spherical coordinates to store a 3 float normal and a 3 float color value in a A32R32G32B32F (or any narrower you can get away with) texture though. Since both the normal and color can be normalized, you can drop the r component for the spherical coordinate and just store the theta and phi for both values. This is actually easier than it may sound, so check out that link on how to do the conversions [smile]

The only downside here is that you end up with sin and cos operations in your shader, which may potentially be slower than sampling two textures. If you're constraint on the number of input textures and/or the number of samples you want to fetch however, it might be a feasible alternative.

Edit - Reading ET3D's reply below though, this is not quite the easiest nor best solution, so you probably shouldn't use it. It is a fancy one though [grin]

0

Share this post

Link to post

Share on other sites

First of all, how slow? I agree that one texture access is likely to be faster than two, since each has some latency, but I can't imagine that two memory accesses per pixel will be extremely costly. What graphics card are you using?

Regarding storing them together, it's not that difficult to simulate shifts and or's with multiplication and addition, and so on. You don't need floats for normals. Low accuracy can work pretty well for them in most cases, and you can either store two shorts or three 10 bit values inside a DWORD.

So a format such as D3DFMT_A16B16G16R16 could be good enough. Your values will be transformed to the 0-1 range, and to extract a colour components you can use one directly and the other as frac(component*255).

Share this post

Link to post

Share on other sites

Original post by Adam_42You don't need to render the scene twice. What you can do is use multiple simultaneous render targets (MRT) to write to two render targets at the same time. This is often used in deferred shading.

Your code would look something like:

device->SetRenderTarget(0, colour_buffer);device->SetRenderTarget(1, normal_buffer);// Draw stuff with shader that outputs to both targets

Note that depending on your hardware both targets may need to be the same bit depth, but they can be different formats (e.g. one R32F and one D3DFMT_A2R10B10G10 is fine).

Oh, I didn't know about that, thanks! But how should I configure my pixel shader for drawing on two targets?

Btw, I second the request to ET3D to elaborate on his suggestion. I Googled quite a bit, but I couldn't find any code that could reliably do back and forth bitwise operations. I was specifically looking for something to transform a float into 4 bytes and back again, if you happen to need a simple case to explain [smile]