Skip to content
Narta Xaymar Dirks edited this page Oct 30, 2026 · 15 revisions
Blitz3D

Dither

Dither:Void enable:Int32
Parameter Mode Type Default Description
enable In Int32 required 0 (False) not to dither, 1 (True) to dither, and 2 to dither what blending makes as well, see HWDither. It is off by default, and unlike in the original it does not matter which color depth was asked for.

Description

Switches dithering on or off, which hides banding in gradients. With Dither on, lighting, textures and fog of 3D drawing also get noise of less than half a step of the 8 bit buffer before they are rounded to it (and before blending), so a smooth gradient in an RGBA8 buffer is a fine pattern instead of bands. Only a buffer of 8 bits per color or less gets this noise: the 10 and 16 bit buffers of Graphics3D depths 30 and 64 keep what the shader makes as it is, and the noise is added once, when the picture is turned into the 8 bits of the window. It uses the same moving noise (or the Bayer matrix, see DitherMode), costs a few operations per pixel, and colors that 8 bits can show exactly do not change. Blending is fixed-function with Dither 1, so what it makes is rounded again and a blend of a color over a gradient can still show bands. Besides that, the picture in the window gets temporal Interleaved Gradient Noise of up to half a step of the 8 bit output added when it is shown, so that the bands that rounding makes (for instance after SetGamma and UpdateGamma changed a gradient to values in between two steps) become a fine pattern that the eye averages out. The pattern moves from frame to frame (it repeats after 64 frames), which makes it average out over time as well; DitherTemporal keeps it in place instead. The noise is made on the GPU while the picture is shown, costs one pass over the screen, and does not change the buffers: ReadPixel and SaveBuffer see what was drawn (for the picture of the window; what 3D drawing made in a buffer of 8 bits or less is dithered when it is drawn, so ReadPixel sees that noise). A color that the picture can show exactly stays as it is.

Dither 2 is a BlitzLLVM extension that goes further: things that are drawn with a blend mode (alpha, multiply, add, or the texture blend modes that blend with what is there) are blended by their fragment shader instead of the fixed-function blender, which reads what the buffer holds at the pixel, mixes it as the blend mode says in floating point, adds the noise and only then rounds to 8 bits. That is how the result of a blend gets dithered, for instance a translucent fog sprite over a dark gradient. It takes the Vulkan extensions VK_KHR_dynamic_rendering_local_read and VK_EXT_rasterization_order_attachment_access, or else VK_EXT_fragment_shader_interlock (used with RGBA8 buffers, where the blending draws run in a pass of their own), which many current GPUs and drivers offer; HWDither says whether the one in use does. With the depths 16, 15 and 12 of Graphics3D the noise of 3D drawing is one step of the 5, 6 or 4 bits that the buffer has, and with the depth 8 the shader adds noise of one step of the palette (GraphicsPalette) after lighting and fog, before the nearest color is picked (Dither 2 blends first, so the blend is in palette colors). Dither 2 only blends in the shader when the target has 8 bits per color (alpha does not count), which is where the noise is needed: into the 10 and 16 bit buffers of Graphics3D depths 30 and 64 the fixed-function blender is used, as with Dither 1. Where the GPU can not do it, or while AntiAlias is on (smoothing needs the finished picture of the camera), Dither 2 does exactly what Dither 1 does. Blending in the shader costs a little more per blended pixel than the fixed-function blender, and the drawing of things that are not blended, or with Dither 0 or 1, does not use it.

Related Commands

CaptureWorld, DitherMode, DitherTemporal, HWDither

Home · Command Index



Differences
Language Features
BlitzBasic
Blitz3D
BlitzPlus

Clone this wiki locally