What Are the Fundamental Scalar Types in GLSL?

The OpenGL Shading Language (GLSL) provides a core set of scalar data types designed specifically for programmable graphics pipelines. These fundamental types represent single-value numerical and logical quantities, serving as the essential building blocks for vectors, matrices, shader calculations, and vertex or fragment processing.

Core Scalar Data Types

GLSL defines five primary scalar data types:

  • bool: Represents conditional logic with values of either true or false. Boolean types are typically used for control flow, conditional statements, and branching logic within shaders.
  • int: Represents signed, two's-complement 32-bit integers. These are used for exact counting, loop indexing, bitwise operations, and array offsets.
  • uint: Represents unsigned 32-bit integers, designated in code by an appended u or U suffix (such as 42u). They are used for bitmask manipulation, texture indexing, and non-negative counts.
  • float: Represents single-precision 32-bit IEEE 754 floating-point numbers (such as 3.14159 or 1.0f). This is the most common data type in GLSL, utilized for coordinates, colors, lighting calculations, and interpolation.
  • double: Represents double-precision 64-bit floating-point numbers (available in modern GLSL versions, designated with an lf or LF suffix). It is used in specialized computations requiring high numerical precision.

Precision Qualifiers and Usage

In GLSL (especially OpenGL ES and WebGL), floating-point and integer types can be modified using precision qualifiers to optimize GPU register usage and performance:

  • lowp: Minimal precision, suitable for simple color operations.
  • mediump: Intermediate precision, suitable for texture coordinates and normalized ranges.
  • highp: Full 32-bit precision, suitable for world-space positions and vertex transformations.

Type Conversion and Strict Typing

GLSL enforces strict type checking and does not perform implicit type casting between different scalar types. Conversions must be handled explicitly through type constructors (for example, float(myInt) or int(myFloat)).