Comparing Structs with Equality Operators in GLSL
In the OpenGL Shading Language (GLSL), two structure instances can be
compared using the equality (==) and inequality
(!=) operators, provided they satisfy specific type and
member constraints. This article outlines the precise rules governing
struct equality in GLSL, detailing the requirements for type matching,
permissible member types, the prohibition of opaque types, and how the
underlying component-wise evaluation operates.
Exact Type Equivalence
For two struct instances to be compared with == or
!=, they must have the exact same structure type. GLSL uses
nominal typing for structures, meaning that two structs are not
considered equal in type simply because they share an identical layout
or identical field names and types. They must be declared using the same
struct type specifier. Implicit type conversion between different struct
types does not occur.
Permissible Member Types
Struct equality operates recursively down to each individual field. Therefore, every member defined within the struct must itself support the equality operator. Valid member types include:
- Scalar types (such as
float,int,uint, andbool) - Vector types (such as
vec2,vec3,vec4,ivec3, etc.) - Matrix types (such as
mat3,mat4, etc.) - Other nested structure types that also meet equality requirements
- Arrays of comparable types (in GLSL versions that support array equality, such as GLSL 1.30 and later)
Prohibition of Opaque Types
Two struct instances cannot be compared if the structure definition directly or indirectly contains opaque types. Opaque types do not support comparison operators. Members that invalidate a struct for equality comparison include:
- Texture samplers (e.g.,
sampler2D,samplerCube) - Image types (e.g.,
image2D) - Atomic counters (
atomic_uint) - Subpass inputs
If a struct definition contains any opaque type, attempting to
evaluate structA == structB will result in a compile-time
error.
Deep Component-Wise Evaluation
When two valid struct instances are compared using ==,
the operator performs a deep component-wise comparison:
- Every corresponding pair of members is evaluated for equality.
- For vectors and matrices, the equality operator checks that every individual component matches.
- For nested structures and arrays, each sub-element is recursively tested.
- The expression evaluates to
trueif and only if all corresponding fields are equal. If any field differs, the result isfalse.
The inequality operator (!=) is logically equivalent to
!(a == b), evaluating to true if any single
field differs between the two instances.