Skip to content

Using 32 bit float color depth

MWstudios edited this page Sep 10, 2021 · 6 revisions

How to do it

Starting with Ensoftener 2.0, float colors are supported for nearly every drawing command, from drawing lines and polygons to pixel shaders, removing the limitation of nested effects. The only unsupported commands are gradient brushes, because they're for some reason clamped to a range of 0-1 (but solid color isn't). Float colors, unlike regular byte colors, have a much wider channel range beyond 0-255. To prove that the bitmaps have float color depth, we'll use the following two shaders. The first shader will multiply texture coordinates by 4 and the second shader will frac them.

Texture2D InputTexture : register(t0);
SamplerState InputSampler : register(s0);

float4 main(float4 pos : SV_POSITION, float4 posScene : SCENE_POSITION, float4 uv0 : TEXCOORD0) : SV_Target
{
    return float4(uv0.xy * 4, 0, 1); //from 0...1 range to 0...4 range
}
Texture2D InputTexture : register(t0);
SamplerState InputSampler : register(s0);

float4 main(float4 pos : SV_POSITION, float4 posScene : SCENE_POSITION, float4 uv0 : TEXCOORD0) : SV_Target
{
    return float4(frac(InputTexture.Sample(InputSampler, uv0.xy).rgb), 1); //frac(3.5) = 0.5
}

Thanks to float colors, we can save a value of 4 on a texture, which would the equivalent to (0, 1024, 1024) in bytes. The result should look like this:

Keep in mind that using float colors also has a few drawbacks. For example, converting a float-based texture into a GDI bitmap takes much longer than a byte-based texture. If you want to create a context that uses the default byte colors, you can via the Global.AddSetups() command.

How does it work?

Since the only Direct2D components that can handle float colors is a DeviceContext, there is a separate context that converts the other ones into the B8G8R8A8 format and then sends it to the SwapChain at the end. In Ensoftener, you can find it under Global.FinalDC.

To be more exact, device contexts can change their format at runtime, but their render targets can't. When you're calling Global.AddSetups() with useFloats set to false, you're mainly influencing the creation of render targets (although the byte-based device contexts also have a few settings altered).

In this wiki you can find out all the information on how to use the Ensoftener library. For more information on how to add Ensoftener to your project, see "Installing and running". The rest is dedicated to the library's features.

Notice: This wiki shows information for Ensoftener 5.0 and is currently outdated.

Clone this wiki locally