How GLSL bitfieldInsert Replaces Bit Segments
The built-in GLSL function bitfieldInsert allows
developers to pack and manipulate data at the bit level by overwriting a
specific range of bits within a target integer using bits from a source
integer. This guide explains the function's syntax, its internal
bit-replacement mechanics, and how it executes across both scalar
integers and vector types.
Function Syntax and Parameters
In GLSL, bitfieldInsert is overloaded for signed and
unsigned 32-bit integers, supporting both scalars and vectors:
genIType bitfieldInsert(genIType base, genIType insert, int offset, int bits);
genUType bitfieldInsert(genUType base, genUType insert, int offset, int bits);The function accepts four arguments:
base: The original integer scalar or vector that receives the new bits.insert: The integer scalar or vector containing the bits to be inserted.offset: The bit index where the insertion begins, counted from the least significant bit (bit 0).bits: The total count of bits to copy frominsertintobase.
The Replacement Mechanism
The function extracts the lowest bits from
insert (from bit 0 to bits - 1)
and writes them into base starting at offset
through offset + bits - 1. All bits in base
outside of this specified range remain unchanged.
Conceptually, bitfieldInsert executes the following
bitwise operations:
- A bitmask of width
bitsis created:mask = (1 << bits) - 1. - The relevant bits from
insertare isolated and shifted to the destination position:(insert & mask) << offset. - The target region in
baseis cleared:base & ~(mask << offset). - The cleared
baseand the shiftedinsertbits are combined with a bitwise OR operation.
If bits is equal to 0, the function leaves
base completely unmodified. If offset < 0,
bits < 0, or offset + bits > 32, the
result is undefined by the GLSL specification.
Scalar vs. Vector Processing
When applied to scalar types (int or uint),
bitfieldInsert operates on a single 32-bit sequence.
When applied to vector types (ivec2, uvec3,
ivec4, etc.), the replacement occurs component-wise:
- The
offsetandbitsparameters remain scalar integers that define the same range for every component. - For each component \(i\), the
lowest
bitsofinsert[i]overwrite the bit range[offset, offset + bits - 1]ofbase[i].
Practical Example
// Scalar example
uint baseValue = 0x00000000u;
uint insertValue = 0x0000000Fu; // 4 ones: 1111 in binary
int offset = 4;
int bitCount = 4;
// Inserts the lowest 4 bits of insertValue into baseValue starting at bit 4
uint resultScalar = bitfieldInsert(baseValue, insertValue, offset, bitCount);
// resultScalar is 0x000000F0u
// Vector example
uvec2 baseVec = uvec2(0xFFFFFFFFu, 0x00000000u);
uvec2 insertVec = uvec2(0x00000000u, 0xFFFFFFFFu);
// Overwrites bits 8 through 15 across both vector components
uvec2 resultVec = bitfieldInsert(baseVec, insertVec, 8, 8);
// resultVec.x becomes 0xFFFF00FFu
// resultVec.y becomes 0x0000FF00u