Difference between revisions of "OpenGL Shading Language"

From OpenGL.org
Jump to: navigation, search
(Fixed the intro, and changing some of the code.)
(Error Checking)
(39 intermediate revisions by 3 users not shown)
Line 1: Line 1:
The OpenGL Shading Language ('''GLSL''') is a high level [[shading language]] with a C-like syntax. It was approved by OpenGL Architecture Review Board (ARB) for programming OpenGL compliant programmable hardware, thus giving developers more control of the graphics pipeline at the lowest level.
+
{{infobox feature
 +
| core = 2.0
 +
| arb_extension = GL_ARB_shader_objects, GL_ARB_vertex_shader, GL_ARB_fragment_shader, GL_ARB_shading_language_100
 +
}}
  
==Background==
+
The '''OpenGL Shading Language''' (GLSL) is the principle [[shading languages]] for OpenGL. While there are several shading languages available for use in OpenGL, GLSL is the only one that is a part of the OpenGL core.
The first forms of programmable GPUs appeard with the nVidia TNT series and with them came the nVidia register combiners (NV_register_combiners) for programming them. Though register combiners were not strictly a programming language they did give the programmer more freedom in terms of manually setting up the fragment end of the pipeline and doing cool effects, that were previously achieved in software for educational purposes and were too slow to be commercially viable.  
+
  
Later on more support for fragment pipeline setup was provided in the form of NV_register_combiners2, NV_texture_shader, NV_texture_shader2 and NV_texture_shader3.  
+
GLSL is a C-style language. The language has undergone a number of version changes, and it shares the deprecation model of OpenGL. The current version of GLSL is 4.30.
  
NVidia, later on came up with vertex programs (NV_vertex_program) with their Geforce 3 series. Vertex programs were much more convenient and provided the programmers with an assembly language for programming the GPU and loading those programs via an API.
+
== Compilation model ==
 +
{{main|GLSL_Object}}
  
Over the years different efforts from different IHVs (Independent Hardware Vendors) were combined and finally resulted in ARB_vertex_program (approved by ARB in June, 2002) and ARB_fragment_program (approved by ARB in September, 2002), and ATI was the first IHV to support them with their Radeon 9700 card.  
+
GLSL is quite unique among shading languages due to its compilation model. It's compilation model is more like the standard C paradigm. Compilation is overseen by [[GLSL Object|a number of object types]]. Note that these do not follow the standard [[OpenGL Objects]] paradigm.
  
In the meantime 3DLabs had been considering options to "overhaul" the OpenGL API, dubbed OpenGL 2.0. This was supposed to be the first major revision of the API since OpenGL 1.1 back in the mid-90s. This was necessary because they were competing with, what was becoming an extremely popular API for games, DirectX 9.0 from Microsoft. Alongwith other proposals, one of the major component was a high level shading language that would provide the programmer with a high level syntax for programming the GPU. Dubbing it '''OpenGL Shading Language (GLSL)''' the proposal was presented to ARB and was finally accepted in June 2003 (OpenGL 1.5). New extensions (ARB_shading_language_100, ARB_shader_objects, ARB_vertex_shader, ARB_fragment_shader) were introduced which gave birth to GLSL 1.00 in June, 2003.
+
=== Terminology ===
  
In September, 2004 (SIGGRAPH) OpenGL 2.0 specifications were released by the ARB with GLSL 1.10 as the shading language (a few modifications from GLSL 1.00).  
+
Because of GLSL's unique compilation model, GLSL uses unique terminology.
  
==Details==
+
According to GLSL's standard terminology, a ''shader'' is just a compiled set of strings for a particular programmable stage; it does not even need to have the complete code for that stage. A ''program'' is a fully linked program that covers multiple programmable stages.
===Data types===
+
The OpenGL Shading Language Specification defines 22 basic data types, some are the same as used in the C programming language, while others are specific to graphics processing.
+
  
*void – used for functions that do not return a value
+
For the sake of clarity, we will adjust this slightly. When the term ''shader'' is used, it will be synonymous with the GLSL concept of ''program''. To refer to a GLSL shader, the term ''shader object'' will be used.
*bool – conditional type, values may be either true or false
+
*int – a signed integer
+
*float – a floating point number
+
*vec2 – a 2 component floating point vector
+
*vec3 – a 3 component floating point vector
+
*vec4 – a 4 component floating point vector
+
*bvec2 – a 2 component Boolean vector
+
*bvec3 – a 3 component Boolean vector
+
*bvec4 – a 4 component Boolean vector
+
*ivec2 – a 2 component vector of integers
+
*ivec3 – a 3 component vector of integers
+
*ivec4 – a 4 component vector of integers
+
*mat2 – a 2X2 matrix of floating point numbers
+
*mat3 – a 3X3 matrix of floating point numbers
+
*mat4 – a 4X4 matrix of floating point numbers
+
*sampler1D – a handle for accessing a texture with 1 dimension
+
*sampler2D – a handle for accessing a texture with 2 dimensions
+
*sampler3D – a handle for accessing a texture with 3 dimensions
+
*samplerCube – a handle for accessing cube mapped textures
+
*sampler1Dshadow – a handle for accessing a depth texture in one dimension
+
*sampler2Dshadow – a handle for accessing a depth texture in two dimensions
+
  
Apart from these built-in data types, user defined data types in the form of C structs are also supported. Refer to the GLSL specifications.
+
== Language ==
 +
{{main|GLSL Core Language}}
  
===Operators===
+
GLSL is a lot like C/C++ in many ways. It supports most of the familiar structural components (for-loops, if-statements, etc). But it has some important language differences.
GLSL provides many built-in operators for built-in data types. There is no need for the programmer to manually write overloaded operators (which is not supported anyway). Built-in common math operators like assignment, comparison, equality etc. are provided. Logical operators like logical and and or are also supported. Bitwise operators, although a part of the language (reserved tokens), are currently '''not''' supported as part of the GLSL 1.10 specifications. GLSL 1.20 specifications, however, promise a support for these operators.
+
Refer to the official [http://www.opengl.org/documentation/glsl/ GLSL specifications] for more details.
+
  
===Control Structures===
+
=== Standard library ===
All sorts of C like control structures like if-else statements and loops are supported. Note that goto is not supported. Refer to the official [http://www.opengl.org/documentation/glsl/ GLSL specifications] for more details.
+
  
===Functions===
+
The OpenGL Shading Language defines a number of '''standard functions'''. Some standard functions are specific to certain shader stages, while most are available in any stage. There is reference documentation for these functions available [http://www.opengl.org/sdk/docs/manglsl/ here].
Functions are also supported in GLSL. User-defined functions are supported and the standard GLSL library (GLSL stdlib) provides many built-in functions for performing mathematical and other graphics operations. This gives IHVs, the liberty to perform hardware specific optimizations for built-in functions.
+
  
===Compiling and Executing===
+
=== Variable types ===
GLSL shaders are not standalone applications. Like all other shading languages they require a host application to load and execute them. All major languages like C, C++, C#, Delphi, Java, VB and many others support OpenGL and therefore the host application can be written in any of these languages.
+
{{main|GLSL Types}}
GLSL shaders are simple text programs and the host application uses OpenGL API to compile and execute these shaders on the graphics hardware.
+
  
GLSL compiler is provided by the driver, which does not require the application to pre-compile the GLSL code into assembly. High level GLSL code can be compiled directly by the driver using OpenGL API calls. The compiled code can then be uploaded to the hardware. Refer to [http://www.opengl.org/documentation/glsl/ GLSL specifications] for more information.
+
C has a number of basic types. GLSL uses some of these, but adds many, many more.
  
====Caveats and Common Problems====
+
=== Type qualifiers ===
Vendor specific compiler, has its pros and cons. Vendors can have their own assembly and the compiler compiles GLSL code to that assembly. They can also have vendor specific optimizations both in the compiler and the code generation, depending on their hardware. However, non-standard GLSL compilers from vendors can result in non-portable GLSL code e.g. a shader compiled using compiler from Vendor A '''may not''' compile on a compiler from Vendor B if it contains some non-standard syntax that was allowed by Vendor A's compiler and not supported by Vendor B. Non-standard, does not necessarily mean a subset of the standard, it can easily be the '''superset''' of the standard, allowing high(er) level syntax, not supported by the standard.
+
{{main|GLSL Type Qualifiers}}
  
To remedy this problem 3DLabs released [http://developer.3dlabs.com/downloads/glslvalidate/index.htm GLSLvaidate] that is a standalone fully GLSL standard compliant compiler which can compile and check your code for syntax errors. A shader compiled with GLSLvalidate is guaranteed to be GLSL standard compliant and should compile on any driver supporting the minimal GLSL syntax.
+
GLSL's uses a large number of qualifiers to specify where the values that various variables contain come from. Qualifiers also modify how those variables can be used.
  
===A sample trivial GLSL Vertex Shader===
+
=== Interface blocks ===
<pre><nowiki>void main(void)
+
{{main|GLSL Interface Block}}
{
+
    gl_Position = ftransform();
+
    //The above is for GLSL 1.00, 1.10, 1.20
+
    //Below, is for GLSL 1.30
+
    //Define your own uniforms!!!
+
    //Define your own vertex attribute!!!
+
    //gl_Position = ProjectionModelviewMatrix * AttrVertex;
+
}</nowiki></pre>
+
  
The minimal job a fully working vertex shader must do is pass on
+
Certain variable definitions can be grouped into interface blocks. These can be used to make communication between different shader stages easier, or to allow storage for variables to come from a buffer object.
a vertex position by transforming it from object coordinates
+
to eye coordinates using the modelview matrix, and to clip coordinates
+
by transformation with the projection matrix. Here is such a minimal
+
shader:
+
  
<pre><nowiki>void main(void)
+
=== Predefined variables ===
{
+
{{main|GLSL Predefined Variables}}
    gl_Position = gl_ProjectionMatrix*gl_ModelViewMatrix*gl_Vertex;
+
    //The above is for GLSL 1.00, 1.10, 1.20
+
    //Below, is for GLSL 1.30
+
    //Define your own uniforms!!!
+
    //Define your own vertex attribute!!!
+
    //gl_Position = ProjectionModelviewMatrix * AttrVertex;
+
}
+
</nowiki></pre>
+
  
===A sample trivial GLSL Fragment Shader===
+
The different shader stages have a number of predefined variables for them. These are provided by the system for various system-specific use.
<pre><nowiki>void main(void)
+
{
+
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+
}</nowiki></pre>
+
  
The minimal fragment shader must set the gl_FragColor.  If you
+
== Using GLSL shaders ==
just want to pass on the fragment color without modifying it,
+
then the minimalist example would look like this:
+
  
<pre><nowiki>void main(void)
 
{
 
    gl_FragColor = gl_FrontColor;
 
    //For GLSL 1.30, do not use gl_FrontColor. Define your own varying variable
 
}
 
</nowiki></pre>
 
  
==References==
+
 
*Rost, Randi. ''OpenGL Shading Language''. 1st ed. Pearson Education, Inc, 2004. ISBN 0321197895
+
=== Building shaders ===
*Kessenich, John, & Baldwin, David, & Rost, Randi. ''The OpenGL Shading Language''. Version 1.10.59. 3Dlabs, Inc. Ltd. http://developer.3dlabs.com/documents/index.htm
+
 
 +
 
 +
==== Attributes and draw buffers ====
 +
For the stages at the start and end of the pipeline (vertex and fragment, respectively), the initial input values and final output values do not come from or go to shader stages. The input values to a vertex shader come from [[Vertex Attribute|vertex data]] [[Vertex Specification|specified]] in a [[Vertex Array Objects|vertex array object]], pulled from [[Vertex Buffer Objects|vertex buffer objects]] during [[Vertex Rendering]]. The output values of a fragment shader are piped to particular buffers for the currently bound framebuffer; either the [[Default Framebuffer|default framebuffer]] or a [[Framebuffer Objects|framebuffer object]].
 +
 
 +
Because of this, there is a mapping layer for the program's inputs and outputs. The vertex shader's input names are mapped to attribute indices, while the fragment shader's output names are mapped to draw buffer indices. This mapping can be created before the program is linked. If it is not, or if the mapping does not cover all of the inputs and outputs, then the linker will automatically define what indices are mapped to which unmapped input or output names. This auto-generated mapping can be queried by the user after the program is linked.
 +
 
 +
 
 +
=== Setting uniforms ===
 +
{{main|GLSL Uniform#Uniform management}}
 +
 
 +
Uniforms in GLSL a shader variables that are set from user code, but only are allowed to change between different {{code|glDraw*}} calls. Uniforms can be queried and set by the code external to a particular shader. Uniforms can be arranged into blocks, and the data storage for these blocks can come from buffer objects.
 +
 
 +
==== Setting samplers ====
 +
{{main|GLSL Sampler#Binding textures to samplers}}
 +
 
 +
Samplers are special types which must be defined as uniforms. They represent bound textures in the OpenGL context. They are set like integer, 1D uniform values.
 +
 
 +
=== Error Checking ===
 +
This piece of code shows the process of loading a vertex and fragment shaders. Then it compiles them and also checks for errors. The idea here is to encourage newcomers to GLSL to always check for errors. It is in C++ but that doesn't matter.
 +
 
 +
Note that the process of loading and compiling shaders hasn't changed much over the different GL versions.
 +
 
 +
{{:Example/GLSL Full Compile Linking}}
  
 
== See also ==
 
== See also ==
  
 
* GLSL
 
* GLSL
 +
** [[GLSL Sampler]]
 +
** [[GLSL Uniform]]
 +
** [[Uniform Buffer Object]]
 
** [[GLSL : common mistakes]]
 
** [[GLSL : common mistakes]]
** [[Multitexture with GLSL]]
 
 
** [[GLSL : nVidia specific features]]
 
** [[GLSL : nVidia specific features]]
 
** [[Hardware_specifics:_NVidia#GLSL_shader_conformance]]
 
** [[Hardware_specifics:_NVidia#GLSL_shader_conformance]]
 
** [[History of OpenGL]]
 
** [[History of OpenGL]]
* [[Cg]] shading language
 
* [[Shading languages]] (general)
 
** [[Shading languages]]
 
** [[Shading languages: General]]
 
** [[Shading languages: Which shading language should I use?]]
 
** [[Shading languages: How to detect shader model?]]
 
  
 
==External links==
 
==External links==
*[http://www.opengl.org The Official OpenGL Web Site]
+
*[http://www.opengl.org/documentation/glsl/ Current Specification for the OpenGL Shading Language]
*[http://www.opengl.org/documentation/glsl/ GLSL Specifications]
+
 
*[http://www.opengl.org/documentation/red_book/ OpenGL Red Book]
 
*[http://www.opengl.org/documentation/red_book/ OpenGL Red Book]
 
*[http://www.opengl.org/documentation/blue_book/ OpenGL Blue Book]
 
*[http://www.opengl.org/documentation/blue_book/ OpenGL Blue Book]
*[http://developer.3dlabs.com/ GLSL Resources and Documentation]
 
*[http://developer.3dlabs.com/downloads/glslvalidate/index.htm GLSLvalidate Compiler]
 
*[http://www.opengl.org/documentation/extensions/ OpenGL Extensions]
 
 
*[http://www.lighthouse3d.com/opengl/ Tutorials and Examples from Lighthouse3D]
 
*[http://www.lighthouse3d.com/opengl/ Tutorials and Examples from Lighthouse3D]
*[http://nehe.gamedev.net Tutorials and Examples from Nehe]
 
*[http://www.typhoonlabs.com A GLSL Development Environment]
 
 
*[http://www.ati.com/developer/rendermonkey/ RenderMonkey Shader Development Environment]
 
*[http://www.ati.com/developer/rendermonkey/ RenderMonkey Shader Development Environment]
*[http://www.mew.cx/glsl_quickref.pdf GLSL Quick Reference Guide (pdf)]
+
 
 +
[[Category:OpenGL Shading Language]]
 +
[[Category:Shading Languages]]

Revision as of 00:38, 22 January 2013

OpenGL Shading Language
Core in version 4.5
Core since version 2.0
ARB extension GL_ARB_shader_objects, GL_ARB_vertex_shader, GL_ARB_fragment_shader, GL_ARB_shading_language_100

The OpenGL Shading Language (GLSL) is the principle shading languages for OpenGL. While there are several shading languages available for use in OpenGL, GLSL is the only one that is a part of the OpenGL core.

GLSL is a C-style language. The language has undergone a number of version changes, and it shares the deprecation model of OpenGL. The current version of GLSL is 4.30.

Compilation model

GLSL is quite unique among shading languages due to its compilation model. It's compilation model is more like the standard C paradigm. Compilation is overseen by a number of object types. Note that these do not follow the standard OpenGL Objects paradigm.

Terminology

Because of GLSL's unique compilation model, GLSL uses unique terminology.

According to GLSL's standard terminology, a shader is just a compiled set of strings for a particular programmable stage; it does not even need to have the complete code for that stage. A program is a fully linked program that covers multiple programmable stages.

For the sake of clarity, we will adjust this slightly. When the term shader is used, it will be synonymous with the GLSL concept of program. To refer to a GLSL shader, the term shader object will be used.

Language

GLSL is a lot like C/C++ in many ways. It supports most of the familiar structural components (for-loops, if-statements, etc). But it has some important language differences.

Standard library

The OpenGL Shading Language defines a number of standard functions. Some standard functions are specific to certain shader stages, while most are available in any stage. There is reference documentation for these functions available here.

Variable types

C has a number of basic types. GLSL uses some of these, but adds many, many more.

Type qualifiers

GLSL's uses a large number of qualifiers to specify where the values that various variables contain come from. Qualifiers also modify how those variables can be used.

Interface blocks

Certain variable definitions can be grouped into interface blocks. These can be used to make communication between different shader stages easier, or to allow storage for variables to come from a buffer object.

Predefined variables

The different shader stages have a number of predefined variables for them. These are provided by the system for various system-specific use.

Using GLSL shaders

Building shaders

Attributes and draw buffers

For the stages at the start and end of the pipeline (vertex and fragment, respectively), the initial input values and final output values do not come from or go to shader stages. The input values to a vertex shader come from vertex data specified in a vertex array object, pulled from vertex buffer objects during Vertex Rendering. The output values of a fragment shader are piped to particular buffers for the currently bound framebuffer; either the default framebuffer or a framebuffer object.

Because of this, there is a mapping layer for the program's inputs and outputs. The vertex shader's input names are mapped to attribute indices, while the fragment shader's output names are mapped to draw buffer indices. This mapping can be created before the program is linked. If it is not, or if the mapping does not cover all of the inputs and outputs, then the linker will automatically define what indices are mapped to which unmapped input or output names. This auto-generated mapping can be queried by the user after the program is linked.


Setting uniforms

Uniforms in GLSL a shader variables that are set from user code, but only are allowed to change between different glDraw*​ calls. Uniforms can be queried and set by the code external to a particular shader. Uniforms can be arranged into blocks, and the data storage for these blocks can come from buffer objects.

Setting samplers

Samplers are special types which must be defined as uniforms. They represent bound textures in the OpenGL context. They are set like integer, 1D uniform values.

Error Checking

This piece of code shows the process of loading a vertex and fragment shaders. Then it compiles them and also checks for errors. The idea here is to encourage newcomers to GLSL to always check for errors. It is in C++ but that doesn't matter.

Note that the process of loading and compiling shaders hasn't changed much over the different GL versions.

Full compile/link of a Vertex and Fragment Shader.

//Read our shaders into the appropriate buffers
std::string vertexSource = //Get source code for vertex shader.
std::string fragmentSource = //Get source code for fragment shader.
 
//Create an empty vertex shader handle
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
 
//Send the vertex shader source code to GL
//Note that std::string's .c_str is NULL character terminated.
const GLchar *source = (const GLchar *)vertexSource.c_str();
glShaderSource(vertexShader, 1, &source, 0);
 
//Compile the vertex shader
glCompileShader(vertexShader);
 
GLint isCompiled = 0;
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isCompiled);
if(isCompiled == GL_FALSE)
{
	GLint maxLength = 0;
	glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength);
 
	//The maxLength includes the NULL character
	std::vector<GLchar> infoLog(maxLength);
	glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &infoLog[0]);
 
	//We don't need the shader anymore.
	glDeleteShader(vertexShader);
 
	//Use the infoLog as you see fit.
 
	//In this simple program, we'll just leave
	return;
}
 
//Create an empty fragment shader handle
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
 
//Send the fragment shader source code to GL
//Note that std::string's .c_str is NULL character terminated.
source = (const GLchar *)fragmentSource.c_str();
glShaderSource(fragmentShader, 1, &source, 0);
 
//Compile the fragment shader
glCompileShader(fragmentShader);
 
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isCompiled);
if(isCompiled == GL_FALSE)
{
	GLint maxLength = 0;
	glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength);
 
	//The maxLength includes the NULL character
	std::vector<GLchar> infoLog(maxLength);
	glGetShaderInfoLog(fragmentShader, maxLength, &maxLength, &infoLog[0]);
 
	//We don't need the shader anymore.
	glDeleteShader(fragmentShader);
	//Either of them. Don't leak shaders.
	glDeleteShader(vertexShader);
 
	//Use the infoLog as you see fit.
 
	//In this simple program, we'll just leave
	return;
}
 
//Vertex and fragment shaders are successfully compiled.
//Now time to link them together into a program.
//Get a program object.
GLuint program = glCreateProgram();
 
//Attach our shaders to our program
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
 
//Link our program
glLinkProgram(program);
 
//Note the different functions here: glGetProgram* instead of glGetShader*.
GLint isLinked = 0;
glGetProgramiv(program, GL_LINK_STATUS, (int *)&isLinked);
if(isLinked == GL_FALSE)
{
	GLint maxLength = 0;
	glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
 
	//The maxLength includes the NULL character
	std::vector<GLchar> infoLog(maxLength);
	glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);
 
	//We don't need the program anymore.
	glDeleteProgram(program);
	//Don't leak shaders either.
	glDeleteShader(vertexShader);
	glDeleteShader(fragmentShader);
 
	//Use the infoLog as you see fit.
 
	//In this simple program, we'll just leave
	return;
}
 
//Always detach shaders after a successful link.
glDetachShader(program, vertexShader);
glDetachShader(program, fragmentShader);

See also

External links