Deep Compositing Extended

OpenDCX 2.2.2 documentation


class DeepFlags

Per-deep sample metadata flag-bits class.

Stores surface-type flags and the partial subpixel-coverage bin count which indicates the subpixel-coverage weight applied to the deep channel values.


Important backwards compatibility note! Flags now require 32-bit storage. In 2.2.1 the 4 defined flags would fit easily inside the mantissa of a 16-bit half float, but with the addition of the partial subpixel-coverage weight it’s prudent to switch to 32-bit floats with 23 bits worth of mantissa space. This way additional bits can be allocated later on without changing the channel format (again.)

Surface-Type Flags
bits 0x01..0xff
Partial Subpixel-Coverage Weight
bits 0x0100..0xff00

If any of the 8 partial spcoverage bits are enabled the deep sample values include partial-coverage weighting equal to the binary value of the coverage bits. These bits work in conjunction with the ADDITIVE flag.

Partial-coverage count to partial-coverage weight conversion is biased by 1 so that 0xff00=0.996, 0x8000=0.5, 0x4000=0.25, 0x0000=0.0, etc. i.e:

weight = float((bits & PARTIAL_SPCOVERAGE_BITS) >> 8) / maxSpCoverageScale   or
weight = float(partialSpCoverageBits()) / 65536.0f                           or just use
weight = DeepFlags::getSpCoverageWeight()

Maximum coverage count is 256 (0x10000) indicating complete subpixel coverage and is logically the same as all bits off. Since both 0x00000 and 0x10000 effectively mean the same thing we don’t require the 9th bit to store the actual value 256. The methods to retrieve the bin count check for count==0 and ADDITIVE=1 and return maxSpCoverageCount instead.

So, when accumulating partial-coverage weight counts and maxSpCoverageCount is reached or exceeded, clear the coverage value to 0x00000 and clear the ADDITIVE flags to indicate full-coverage.

Reserved Bits (undefined)
bits 0x10000..0xf0000
void DeepFlags::setSurfaceFlags(const DeepFlags&)

Set or clear the surface flag bits. Partial subpixel-coverage bits are left untouched.

uint32_t DeepFlags::surfaceFlags() const

Get a subset range of flag bits.

bool DeepFlags::isHardSurface() const

Does the segment represent a solid (hard) or volumetric surface? If hard-surface - use linear interpolation between Zf/Zb. If volumetric - use log interpolation between Zf/Zb.

bool DeepFlags::isMatte() const

Should the segment cutout (act as a matte of) the segments behind it?

bool DeepFlags::isAdditive() const

Sample should be added to surrounding samples rather than under-ed This is used primarily for partial subpixel coverage.

bool DeepFlags::hasPartialSpCoverage() const

Does the sample have partial subpixel coverage baked into color, alpha, etc? If so the sample is handled as additive when composited. This normally indicates filtering or resampling of subpixel masks has been applied.

DeepFlags DeepFlags::operator&(uint32_t rhs) const

Bitwise flag ops - operates only on the surface flags bits. Partial subpixel-coverage bits are left untouched.

void DeepFlags::fromFloat(float)

Convert to/from floats. Does a simple int/float conversion and assumes storage in 32-bit floats which has 23 bits worth of mantissa capacity. Note: if stored in a 16-bit half the partial spcoverage bits will get truncated!

void DeepFlags::print(std::ostream&) const

Print the list of enabled flags