GLSL 1.20 to GLSL 1.30: Keywords and Matrix Types
The transition from GLSL 1.20 (introduced with OpenGL 2.1) to GLSL
1.30 (aligned with OpenGL 3.0) marked a pivotal shift in modern
programmable shading. This update stripped away legacy fixed-function
baggage by modernizing storage qualifiers into a unified
in/out syntax and refining how shaders
declare, manipulate, and transform matrix data. By replacing rigid,
stage-specific keywords and deprecating built-in state matrices, GLSL
1.30 established the foundational architecture still used in modern
graphics programming today.
Modernizing
Keyword Structures: The Shift to in and
out
In GLSL 1.20, data flow between pipeline stages relied on distinct,
stage-dependent keywords. Inputs to a vertex shader were declared using
attribute, while communication between the vertex shader
and fragment shader required both stages to declare the same variable as
varying. Outputs from the fragment shader typically relied
on built-in global variables such as gl_FragColor or
gl_FragData[n].
GLSL 1.30 unified and streamlined this model:
- Unified Qualifiers: The
attributeandvaryingkeywords were deprecated. In their place, GLSL 1.30 introduced genericinandoutqualifiers. Vertex shader inputs becamein, vertex shader outputs becameout, fragment shader inputs becamein, and fragment shader outputs became user-definedoutvariables. - Pipeline Symmetry: By using
inandout, data passing across any programmable stage became symmetrical and easier to read, paving the way for geometry shaders and future pipeline stages. - Explicit Fragment Outputs: Instead of automatically
writing to
gl_FragColor, GLSL 1.30 encouraged declaring custom output variables (e.g.,out vec4 fragColor;), providing direct support for multiple render targets (MRT) without relying on legacy array syntax. - Precision and Interpolation Modifiers: GLSL 1.30
formalized interpolation qualifiers such as
flat,noperspective, andcentroid, which could be prefixed directly toinandoutdeclarations to control how values interpolate across primitives.
Matrix Type Enhancements and Modernization
While non-square matrix types (such as mat2x3,
mat3x4, etc.) were introduced late in the GLSL 1.20
specification, GLSL 1.30 fully integrated and matured matrix operations
to align with modern hardware requirements.
- Deprecation of Built-In State Matrices: GLSL 1.20
heavily exposed OpenGL fixed-function matrices, including
gl_ModelViewMatrix,gl_ProjectionMatrix, andgl_ModelViewProjectionMatrix. GLSL 1.30 deprecated these built-ins, requiring developers to manage transformations through user-defined uniform matrices. This decoupled shader logic from implicit OpenGL state. - Native Matrix Functions: GLSL 1.30 expanded
built-in math support by standardizing functions like
transpose()andinverse()directly in the shading language. In GLSL 1.20, developers often had to compute matrix transpositions or inversions manually on the CPU or write verbose shader functions. - Strict Type Safety and Vector Mapping: GLSL 1.30
strengthened strict type checking for operations involving non-square
matrices. Column and row access patterns were formalized, ensuring that
multiplying non-square matrices with vectors (e.g., multiplying a
mat4x3by avec4to produce avec3) followed rigid mathematical rules without ambiguous type coercions.
Architectural Impact
The move to GLSL 1.30 transformed shader authoring from an extension
of the fixed-function pipeline into a fully explicit, programmable
environment. Unifying storage keywords into in and
out eliminated semantic confusion across shader stages,
while modernizing matrix manipulation ensured that shaders operated
independently of driver-managed matrix stacks. These changes set the
design template for all subsequent iterations of the OpenGL Shading
Language.