The OpenGL Shading Language

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 75

The OpenGL Shading Language

Language Version: 1.20


Document Revision: 8
07-Sept-2006
John Kessenich
Version 1.1 Authors: John Kessenich, Dave Baldwin, Randi Rost
Copyright 2002-2006 3Dlabs, Inc. Ltd.
This document contains unpublished information of 3Dlabs, Inc. Ltd.
This document is protected by copyright, and contains information proprietary to 3Dlabs, Inc. Ltd.
Any copying, adaptation, distribution, public performance, or public display of this document
without the express written consent of 3Dlabs, Inc. Ltd. is strictly prohibited. The receipt or
possession of this document does not convey any rights to reproduce, disclose, or distribute its
contents, or to manufacture, use, or sell anything that it may describe, in whole or in part.
This document contains intellectual property of 3Dlabs Inc. Ltd., but does not grant any license to
any intellectual property from 3Dlabs or any third party. It is 3Dlabs' intent that should an OpenGL
2.0 API specification be ratified by the ARB incorporating all or part of the contents of this
document, then 3Dlabs would grant a royalty free license to Silicon Graphics, Inc., according to the
ARB bylaws, for only that 3Dlabs intellectual property as is required to produce a conformant
implementation.
This specification is provided "AS IS" WITH NO WARRANTIES WHATSOEVER, WHETHER
EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, 3DLABS EXPRESSLY DISCLAIMS
ANY WARRANTY OF MERCHANTABILITY, NON-INFRINGEMENT, FITNESS FOR ANY
PARTICULAR PURPOSE, OR ANY WARRANTY OTHERWISE ARISING OUT OF ANY
PROPOSAL, SPECIFICATION, OR SAMPLE.
U.S. Government Restricted Rights Legend
Use, duplication, or disclosure by the Government is subject to restrictions set forth in FAR
52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights in Technical Data and Computer Software
clause at DFARS 252.227-7013 and/or in similar or successor clauses in the FAR or the DOD or
NASA FAR Supplement. Unpublished rights reserved under the copyright laws of the United States.
Contractor/manufacturer is 3Dlabs, Inc. Ltd., 9668 Madison Blvd., Madison, Alabama 35758.
OpenGL is a registered trademark of Silicon Graphics Inc.

1. INTRODUCCIN .................................................................................................................. 4
1.1 RECONOCIMIENTOS
1.2 CAMBIOS
1.3 VISIN GENERAL
1.4 GESTIN DE ERRORES
1.5 CONVENIOS TIPOGRFICOS
2. DESCRIPCIN DE OPENGL SHADING ................................................................................. 6
2.1 VERTEX PROCESSOR
2.2 FRAGMENT PROCESSOR
3 BSICO ................................................................................................................................... 7
3.1 CARACTERES RESERVADOS
3.2 SOURCE STRINGS
3.3 PREPROCESSOR
3.4 COMENTARIOS
3.5 TOKENS
3.6 KEYBOARDS
3.7 IDENTIFICADORES
4. VARIABLES Y TIPOS ........................................................................................................... 13
4.1 TIPOS BASICOS
4.1.1 VOID
4.1.2 BOOLEANS
4.1.3. Integers
4.1.4 Floats
4.1.5Vectors
4.1.6Matrices
4.1.7Samplers
4.1.8 Estructuras
4.1.9 Matrices
4.1.10 Conversiones implcitas
4.2 Alcance
4.3 Cualificadores de almacenado
4.3.1Cualificador de almacenado por defecto
4.3.2 Const
4.3.3 Expresiones constantes
4.3.4 Atributo
4.3.5 Uniforme
4.3.6 Mutantes
4.4 Cualificadores de Parmetros
4.5 Precisin y Cualificadores de Precisin
4.6 Mutantes y el Cualificador de Mutantes
4.6.1 El Cualificador Invariante
4.6.2Invarianza de Expresiones Constantes
4.7 Orden de los Cualificadores
5. Operaciones y Expresiones................................................................................................... 27
5.1 Operadores
5.2 Operaciones de Matrices
5.3 Llamadas de Funciones

5.4 Constructores
5.4.1 Conversin y Constructores Escalares
5.4.2. Vectores y matrices de constructores.
5.4.3. Constructor de estructuras
5.4.4. Constructor de arrays
5.5. Componentes de los vectores
5.6. Elementos de matrices
5.7. Operaciones con arrays y estructuras
5.8. Asignaciones
5.9. Expresiones
5.10. Operaciones con vectores y matrices
6. Sentencias y estructuras ....................................................................................................... 36
6.1 Definicin de funciones
6.1.1. Convenio de llamadas a funciones
6.2 Seleccin
6.3 Iteracin
6.4 Saltos
7 Variables Internas .................................................................................................................. 42
7.1 Variables especiales en Vertex Shaders
7.2 Variables especiales en Fragment Shaders
7.3 Atributos especiales en Vertex Shaders
7.4 Constantes especiales
7.5 Variables Uniformes de Estado
7.6 Variables no Uniformes
8 Funciones Propias ................................................................................................................. 49
8.1 Funciones
8.2 Funciones
8.3 Funciones
8.4 Funciones
8.5 Funciones
8.6 Funciones
8.7 Funciones
8.8 Funciones
8.9 Funciones

de ngulos y trigonomtricas
exponenciales
comunes
geomtricas
de matrices
relacionales de vectores
Lookup de texturas
de Procesado Fragmentado
de Ruido

9 Gramatica del lenguaje de Shading ........................................................................................ 59


10 Problemas............................................................................................................................ 67

1. INTRODUCCIN
Este documento especifica la version 1.20 de OpenGL Shading Language. Requiere
__VERSION__ sea 120, y #version aceptar 110 o 120.
1.1 RECONOCIMIENTOS
Esta especificacin esta basada en el trabajo de quienes contribuyeron a la version 1.10 del
OpenGL Language Specification, el OpenGL ES 2.0 Language Specification, versin 1.10 y las
siguientes contribuciones a esta versin:
Nick Burns
Chris Dodd
Michael Gold
Jeff Juliano
Jon Leech
Bill Licea-Kane
Barthold Lichtenbelt
Benjamin Lipchak
Ian Romanick
John Rosasco
Jeremy Sandmel
Robert Simpson
Eskil Steenberg
1.2 CAMBIOS
Cambios de la septima revisin, de la version 1.20
- Nmero 13 de la resolucin es actualizado con el cambio acordado en la revisin 7 en
cuanto al nmero de atributos de las franjas horarias es el nmero de columnas en una
matriz.
- Reiter la aritmtica operador comportamiento en la seccin 5,9 de subcontratacin, en
lugar de balas demasiado largo de un prrafo.
Cambios de la sexta revisin de la versin 1.20
- La gramtica es renovada
- mtodo de apoyo para .length( )
- constructores simplificados y reconocidos a travs de type_specifier
- el tipo de sintaxis para arrays soportado es float [5] y se aaden inicializadores para
arrays.
-Fijar la declaracin sobre el nmero de huecos de las matrices. Se dice erroneamente que se
utiliza el nmero mximo de filas y de columnas, pero se usa el nmero de columnas.
- Suprimido el ltimo prrafo de la seccin 5.10 por redundante o inconscientemente repetido de la
seccin 5.9, y aseguramos todos los contenidos que fueron incorporados dentro del operador
aritmetico-binario mantenidos en la seccin 5.9.
-Aclarar que, a pesar de ser invariantes los vrtices de salida, la declaracin de la invariant
tienen que coincidir entre el vrtice y el fragmento de las partes, para coincidir con los nombres.
Cambios de la revisin 5 de la versin 1.20
- Eliminado notacin mostrando adiciones y supresiones a la especificacin, aadido el ndice de
contenidos, y limpiado algunas referencias cruzadas y alguna parte del texto que reacaa en
cuestiones. Ningn cambio funcional.

Cambios de la revisin 4 a la versin 1.20


-Actualizacin de la gramtica (todava tiene que ser validado)
-Eliminado las estructuras incorporadas a la pareja de ES, esperar a la primicia del tipo del
operador de acceso incorporado.
-Las expresiones constantes son calculadas de una forma invariante.
-El uso de invariant y centroide debe coincidir entre el vrtice y el fragmento de shaders.
-Hecha la distincin de shaders como undidad de compilado y shader como ejecutable.
-Clarificado no hay linea continua de caracterers, y que los comentarios no borren nuevas lineas.
-Muchos cambios para reducir las diferncias con la especificacin ES.
Cambios de la revisin 3 de la versin 1.2
-Aadir la invariante de palabras clave y su soporte.
-Permitir redimensionar el constructor de los arrays (Esto todava hace explicito el tamao de los
arrays).
-Exigir explicitamente el tamao de los arrays para la asignacin y la comparacin.
-Permitir el calibrado del tamao del array de declaracin a travs del inicializador.
-Diferentes unidades de compilacin pueden ser de lenguajes distintos.
-Aadido el estilo de C++ ocultando las reglas.
-Reservado lowp, mediump, highp, y precission.
Cambios de la revisin 1 en la versin 1.2
-Desabilitados otros valores de retorno del main.
-Aclarar que ?: puede tener el mismo tipo el segundo y tercer operandos (por ejemplo la conversin
no es requerida).
-Decir que punteros sprite tienen que ser avilitados para conseguir valores de gl_PointCoord.
-Separar y distinguir entre el entre el almacenamiento y el parmetro de clasificacin lo que hace
ms fcil aadir la invariante al calificador.
-#version 120 necesaria para usar la version 1.20.
-mat2x3 significa dos columnas de tres filas.
-matriz en construccin de matriz permitida.
-aadido transpose().
-La marca de comparacin tiene en cuenta el tipo de conversin, ya que la ambigedad es un
error.
Cambios de la revisin 60 de la versin 1.10
-Aceptar "f", como parte de una constante de punto flotante. Ej "G de flotacin = 3.5f".
-Convertir directamente los tipos enteros a los tipos flotantes, en la medida de lo necesitado por el
contexto.
-Permitir inicializadores uniformes en las declaraciones. El valor se establece en tiempo de
compilacin.
-Permitir construir llamadas a funciones dentro de los inicializadores constantes.
-Soporte de matrices no cuadradas.
-Aadir matrixProduct () [ahora outerProduct ()] para multiplicar el rendimiento de los vectores de
una matriz.
-Los arrays se convierten en objetos de la primera clase, con constructores, comparacin, length(),
etc.
-Aadir gl_PointCoord para fragmentar shaders para consultar un fragmento de la posicin de un
punto dentro de sprites.
-Soportada interpolacin centroid en variaciones multi-sample.
1.3 VISIN GENERAL
Este documento describe The OpenGL Shading Language, version 1.20.
Independiente,la compilacin de unidades escrito en este idioma se llaman shaders. Un programa
es un conjunto completo de Shaders que son compilados y enlazados juntos. El objetivo de este
documento es especificar a fondo el Lenguaje de programacin. Los puntos de entrada se usan

para manipular comunicarse con los programas y los shaders son definidos en una especificacin
a parte.
1.4 GESTIN DE ERRORES
Los compiladores, en general, aceptan programas que estan mal formados, debido a la
imposibilidad de detectarlos todos. La portabilidad solo est garantizada para los programas bien
formados tal y comos se describen en esta especificacin. Los compiladores son alentados a
detectar programas mal formados y a emitir mensajes de diagnostico, pero noe s obligatorio en
todos los casos. Los compiladores tienen la obligacin de devolver mensajes de error en relacin
con el lxico, gramtica, o semntica incorrencta de los shaders.
1.5 CONVENIOS TIPOGRFICOS
Las opciones de negrita, cursiva y fuente se han usado en esta especificacin principalmente para
mejorar la legibilidad. Para los fragmentos de cdigo se utiliza una fuente de ancho fijo. Los
identificadores estn puestos en el texto en cursiva. Las palabras clave estn introducidas en el
texto en negrita. Los operadores son llamados por su nombre seguido su smbolo en negrita entre
parntesis. Para aclarar ms la gramtica del texto se usa negrita para literales y cursiva para nonterminals. La gramtica oficial en la seccin 9 Shading Language Gramar utiliza todos los
terminales en mayuscula y no-terminales en minuscula.

2.
DESCRIPCIN
SHADING

DE

OPENGL

El OpenGL Shading Language se trata realmente de dos lenguajes extrechamente relacionados.


Estos leguajes son usados para programar el proceso contenido en el pipeline de procesamiento
de OpenGL. A no ser que se indique en este documento, se hablar del lenguaje como uno solo
aun a pesar de referirse a varios lenguajes. Los lenguajes especificos sern mencionados por el
nombre del procesador objetivo: vertex o fragment.
Cualquier OpenGL utilizado por el estado de shaders son automticamente rastreados y puestos a
disposicin de shaders. Este mecanismo de seguimiento de estado automtico permite a la
aplicacin utilizar los comandos de estado OpenGL, la gestin del Estado, y tienen los valores
actuales de tal estado automticamente disponibles para su uso en los shaders.
2.1 VERTEX PROCESSOR
El procesador de vrtices es una unidad programable que opera en los vrtices y sus datos
asociados. Las unidades escritas en el OpenGL Shading Language para funcionar en este
procesador se llaman vertex shaders. Cuando un conjunto completo de vertex shaders son
compilados y lincados ellos dan como resultado un vertex shader ejecutable, que se ejecuta en el
vertex processor. El vertex processor funciona sobre un vrtice a la vez. Adems, no sustituye las
operaciones grficas que necesitan el conocimiento de varios vrtices a la vez.
El vrtice shaders se ejecuta en el procesador de vrtices que debe de calcular la posicin
homognea del prximo vrtice.
2.2 FRAGMENT PROCESSOR
El fragment processor es una unidad programable que opera sobre el fragmento de valores y sus
datos asociados. La compilacin y el lincado de unidades en el fragment processor da como
resultado fragment shaders que son ejecutados en el fragment processor. Un fragment shader no
puede cambiar su posicion (x,y). El acceso a los fragmets vecinos no est permitido. Los valores
usados para el computado de los fragment shaders son, en ltima instancia utilizados para

actualizar el frame-buffer de la memoria o el tecture-memory, en funcin del estado actual de


OpenGL y del comando OpenGL que gener el fragment.

3 BSICO
3.1 CARACTERES RESERVADOS
El conjunto de caracteres usados por el OpenGL Shading Language es un subconjunto del cdigo
ASCII. Incluye los siguientes caracteres:
-

Las letras a-z, A-Z y el subrayado ( _ ).


Los nmeros 0-9.
Los smbolos punto (.), ms (+), guin (-), barra (/), asterisco (*), porcentaje (%), entre
parntesis angulares (< y >), corchetes ([y]), parntesis ((y)), llaves ((y)), intercalacin (^),
barra vertical (|), comercial (&), de tildes (~), igualdad (=), signo de exclamacin (!), dos
puntos (:), punto y coma (;), coma (,), y signo de interrogacin (?).
El nmero signo (#) para uso del procesador.
Espacio en blanco: el espacio, el tabulador horizontal, tabulador vertical, la forma de
alimentacin, el carro de retorno, y de lnea.
Las lneas son importantes para el compilador y los mensajes de diagnstico, y para el
procesador. Estn terminados por el carro de retorno o de lnea. Si se utilizan los dos
juntos se cuentan como una nica lnea de terminacin. Para el resto de este documento,
todas las combinaciones son referenciadas como una nueva lnea. No hay el carcter de
lnea continua. En general, el lenguaje de uso de este tipo de caracteres es senseble a
maysculas y minsculas. No hay cadena de caracteres o tipo string, por lo que no son
citados. No existe carcter de final de archivo, sino que este es indicado por su tamao, no
por ningn carcter.

3.2 SOURCE STRINGS


La fuente para un sencillo shader es un arrar de strings de caracteres del conjunto de caracteres.
Un shader sencillo es hecho de la concatenacin de estos strings. Cada string puede contener
multimples lneas, separadas por salto de lnea. No necesariamente tienen que estar presentes los
saltos de lnea en un string; una nica lnea puede ser formada por multiples strings. Los saltos de
lnea y otros caracteres se insertan por la aplicacin cuando se concatenan los strings para dar
lugar al nuevo shader. Mltiples shaders pueden ser lincados para dar lugar a un nico programa.
Los mensajes de diagnstico devueltos de la compilacin de un shader deben identificar tanto el
nmero de lnea dentro de una string como la fuente del mensaje aplicado al string. La fuente de
las cadenas se cuentan consecutivamente con la primera cadena que ha de ser 0. El nmero de
lneas es uno ms que el nmero de saltos de lnea que han sido procesados.
3.3 PREPROCESSOR
Hay un preprocesador que procesa la fuente de los strings como una parte de la copilacin. La lista
completa de directivas de preprocesado es la siguiente:
#
#define
#undef
#if
#ifdef
#ifndef
#else
#elif
#endif

#error
#pragma
#extension
#version
#line
El siguiente operador est tambin disponible
defined
Cada numero signo (#) puede ser precedido en su lnea solo por espacios o tabuladores
horizontales. Tambin puede ser seguida de espacios y tabs horizontales, anteior a la directiva.
Cada directiva es terminada por un salto de lnea.
El preprocesamiento no cambia el nmero o la ubicacin relativa de los saltos de lnea de un un
string fuente.
El nmero signo (#) en una lnea por si mismo es ignorado. Cualquier directiva que no aparezca en
la lista de arriba causa un mensaje de diagnstico y hace que la aplicacin de shaders se trate
como mal formada.
#define y #undef funcionalmente son definidos como en C++ la definicin del preprocesado con
macros, con y sin parmetros macro.
Las siguientes predefinidas macros estn disponibles
__LINE__
__FILE__
__VERSION__
__LINE__ reemplazar un decimal constante que es uno ms que el nmero de saltos de lnea
anterior en la actual cadena origen.
__FILE__ reemplazar un decimal constante fuente que dice el nmero actual de cadenas que se
estn tramitando.
__VERSION__ reemplazar un decimal que refleja la version del OpenGL Shading Language. En
la versin descrita en este manual se sustituira __VERSION__ por 120.
Todos los nombres de macros que usan el doble subrayado descrito anteriormente ( __ ) estn
reservadas para un uso futuro como nombres de macros predefinidas. Todos los nombres de
macros prefijados con GL_ (GL seguido por un nico carcter de subrayado) tambin estn
reservados.
#if, #ifdef, #ifndef, #else, #elif, y #endif son defenidos de la misma forma que el preprocesado de
C++. Las expresiones siguientes #if y #elif estn restringidas para operandos con litorales enteros
constantes, adems de identificadores consumidos por el operador definido. Los caracteres
constantes no son compatibles. Los operadores disponibles son los siguientes:

El operador defined puede ser usado de cada una de las formas siguientes:
defined identifier
defined ( identifier )
No hay un nmero signo basado en operadores (sin #, #@, ##, etc), ni existe un operador sizeof.
La semntica de la aplicacin de los operadores a un literal entero en el preprocesado
corresponden a la norma del preprocesador de C++, no a los que estn en el OpenGL Shading
Language. La evaluacin de las expresiones, por tanto depender del preporcesador de acogida y
no del Shading Language.
#error har a la implementacin poner un mensaje de diagnostico dentro del log de informacion del
shader (ver la informacin del API externa para ver como se accede al log de un shader). El
mensaje sern los tokens siguientes a la directiva #error hasta el primer salto de lnea. En la
implementacin se debe entonces considerar si el shader est malformado.
#pragma permite a la aplicacin depender del control de compilador.
Si en una implementacin no se reconocen los tokens siguientes a #pragma entonces el programa
la ignorar. Los siguientes pragmas son definidos como parte del lenguaje.
#pragma STDGL
El programa STDGL se usa para reservar pragmas para un uno futuro en las revisiones de este
lenguaje. No puede usar una aplicacin pragma cuyo primer token es STDGL.
#pragma optimize(on)
#pragma optimize(off)
se pueden usar para activar o desactivar la ayuda en el desarrollo y depuracin de shaders. Solo
puede usarse fuera de definiciones de funciones. Por defecto, est activada la optimizacin de
todos los shaders. La depuracin pragma
#pragma debug(on)

#pragma debug(off)
puede ser usado para permitir la compilacin y anotacin de un shader con informacin de la
depuracin. Solo se puede usar fuera de la definicin de funciones. Por defecto, est desactivado.
Con los shaders debera declararse la versin del lenguaje en el que estn escritos. Se especifica
con
#version number
donde number debe ser el numero correspondiente a la versin del lenguaje, de la misma forma
que hemos visto ms arriba para __VERSION__. Por tanto, la directiva #version 120 nos indicara
que en ese shader se ha usado la versin 1.20 del lenguaje.
Cualquien nmero de versin del lenguaje que no sea compatible con el compilador generar un
error.
La versin 1.10 no necesita ser especificada dentro del shader, y por defecto si no se especifica la
version del shader, este ser tratado como si fuera de la versin 1.10.
El comportamiento de los shaders de la version 1.10 no se ver afectado por los cambios
introducidos en la versin 1.20. Diferentes shaders (unidades de copilacin) que estn unidos en el
mismo programa no tienen porque tener la misma versin; pueden ser una mezcla de la versin
1.10 con la versin 1.20.
La directiva #versin debe suceder en un shader antes que cualquier otra cosa excepto los
comentarios y los espacios en blanco.
Por defecto, estos lenguajes deben emitir en tiempo de compilacin los errores sintcticos,
gramaticales y semnticos que no se ajusten a la especificacin.
Cualquier comportamiento prorrogado debe estar especificado (habilitado). Las directivas que
controlan el comportamiento del compilador con respecto a las extensiones son declaradas con la
directiva #extension
#extension extension_name : behavior
#extension all : behavior
donde extension_name corresponde al nombre de la extensin. Los nombres de las extensiones
no estn documentados en esta especificacin. El smbolo all significa que el comportamiento es
aplicado a todas las extensiones del compilador. El comportamiento puede ser solo uno de los
siguientes
Comportamiento
require

enable

warn

Efecto
Comportarse segn lo especificado por la
extension extension_name.
Da un error sobre la #extension si la extensin
no es soportada, o si all est especificado.
Comportarse segn lo especidicado por la
extensin extension_name. Advierte sobre la
#extension si es soportada.
Da un error sobre la #extension si todo es
especificado.
Comportarse segn lo especificado por la
extensin extension_name, excepto emitir
advertencias sobre algn uso detectado de esa
extensin a no ser que dicho uso sea soportado
o requerido por otras extensiones.
Si todo est especificado entonces advertir
sonbre todos los usos detectados de cualquier
extensin usada.
Advertir
sobre
la
#extension
si
la

10

disable

extension_name no es compatible.
Comportarse (incluyendo el envio de errores y
advertencias)
como
si
la
extension
extension_name no formase parte de la
definicin del lenguaje. Si todo est especificado
entonces el comportamiento debe volver al de
no extendido de la versin bsica del lenguaje
que est siendo compilado.
Advertir
sobre
la
#extension
si
la
extension_name no es soportada.

La directiva extension es un simple mecanismo de bajo nivel para configurar el comportamiento de


cada extension. No definir polticas como en las cuales las combinaciones son apropiadas, deben
ser definidas en otros sitios. El orden de las directivas es importante realizarlo conforme al
comportamiento de cada extension: las directivas que ocurren ms tarde sobreescriben a las vistas
antes. La variante all coloca el comportamiento de todas las extensiones, sobreescribiendo todas
las previamente emitidas directivas extension, pero solo para los comportamientos warn and
disable.
El estado inicial del compilador es como si la directiva
#extension all : disable
fuese emitida, diciendo al compilador que todo error y toda advertencia deben ser informadas de
acuerdo a esta especificacin, ignorando cualquier extension. Cada extensin puede definir el
mbito permitido granularmente. Si no se dice nada, la granularidad es de un shader (esto quiere
decir una unidad simple de compilacin) y la directivas de extensin deben ocurrir antes que
cualquier simbolo del no-preprocesado. Si es necesario el lincador puede hacer valer
granularidades mayores que una nica unidad de compilacin, en el cual cada caso de shader
complejo tendr que contener necesariamente directivas de extensin.
La expansin macro no se realiza en las lneas que contengan directivas #extension y #version.
#line puede tener sustitucin macro, de una de las dos siguientes formas:
#line line
#line line source-string-number
donde line y source-string-number son expresiones enteras constantes. Despus de procesar esta
directiva (incluyendo el salto de lnea) la implementacin se comportar como si estuviera
compilando la lnea de nmero linea+1 y el string fuente de nmero source-string-number. El
posterior string fuente ser numerado secuenciamente, hasta que otra directiva #line sobreescriba
esa numeracin.
3.4 COMENTARIOS
Los comentarios son dilimitados por /* y */, o por // y un retorno de lnea. Los delimitadores de inicio
de comentario (/* o //) no se reconocen como delimitadores de comentarios dentro de uno mismo,
por tanto los comentarios no se pueden anidar. Si un comentario reside por entero en una sola
lnea, es sintcticamente tratado como un espacio solo. Los retornos de lnea no son eliminados
por los comentarios.
3.5 TOKENS
Este lenguaje es una secuencia de tokens (smbolos), un token puede ser
token:

11

keyword
identifier
integer-constant
floating-constant
operator
;{}
3.6 KEYBOARDS
Las siguientes son las palabras clave de este lenguaje, y no pueden ser usadas para cualquir otro
propsito definido por este documento:
attribute const uniform varying
centroid
break continue do for while
if else
in out inout
float int void bool true false
invariant
discard return
mat2 mat3 mat4
mat2x2 mat2x3 mat2x4
mat3x2 mat3x3 mat3x4
mat4x2 mat4x3 mat4x4
vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4
sampler1D sampler2D sampler3D samplerCube
sampler1DShadow sampler2DShadow
struct
Las siguientes son palabras clave reservadas para uso futuro. Usandolas el resultado ser un
error:
asm
class union enum typedef template this packed
goto switch default
inline noinline volatile public static extern external interface
long short double half fixed unsigned
lowp mediump highp precision
input output
hvec2 hvec3 hvec4 dvec2 dvec3 dvec4 fvec2 fvec3 fvec4
sampler2DRect sampler3DRect sampler2DRectShadow
sizeof cast
namespace using
Adems, todos los identificadores que contengan dos subrayados consecutivos ( __ ) son
reservados para un futuro puedan ser palabras clave.
3.7 IDENTIFICADORES
Los identificadores son usados para los nombres de las variables, nombres de funciones, nombres
de estructuras, y selectores de campos (los selectores de campos sellecionan componentes de
matrices y vectores similar al selector de campos de estructuras, tratado en la seccin 5.5
Componentes de los vectores y la seccin 5.6 Componentes de las matrices). Los
identificadores tienen la forma

12

identifier
nondigit
identifier nondigit
identifier digit
nondigit: one of
_abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
digit: one of
0123456789
Los identifecadores que comienzan con gl_ son reservados para uso de OpenGL, y no pueden
ser declarados en un shader como una variable o una funcin.

4. VARIABLES Y TIPOS
Todas las variables y funciones deben ser declaradas antes de ser utilizadas. Los nombres de las
variables y de las funciones son identificadores.
No hay tipos por defecto. Todas las declaraciones de variables y funciones deben tener un
tipo declarado, y opcionalmente calificadores. Una variable se declara especificando su tipo
seguido por uno o ms nombres separados por comas. En muchos casos, una variable puede ser
inicializada como parte de su declaracin utilizando el operador de asignacin (=). En la gramtica
al final de este documento, se proporciona una referencia completa de la sintaxis de la declaracin
de
variables.
Tipos definidos por el usuario se pueden definir usando struct para agregar una lista de los
tipos actuales en un solo nombre.
El Lenguaje de Sombreado OpenGL es de tipo seguro. No existen conversiones entre tipos
implcitos, con la excepcin de que un valor puede aparecer cuando un tipo de punto flotante se
espera, y se convertira en un valor de coma flotante. Exactamente cmo y cundo puede ocurrir
esto se describe en la Seccin 4.1.10 "Conversiones Implcitas", y como referencia en otras
secciones de esta especificacin.
4.1 TIPOS BASICOS
El Opengl Shading Language es compatible con los siguientes tipos de datos bsicos:
Type
void
bool
int
float
vec2
vec3
vec4
bvec2
bvec3
bvec4
ivec2
ivec3
ivec4

Meaning
para funciones que no devuelven un valor
un tipo condicional, toma un valor o verdadero o
falso
entero con signo
flotantes sencillos
vector de 2 componentes punto flotantes
vector de 3 componentes punto flotantes
vector de 4 comonentes punto flotantes
vector de 2 comonentes Boolean
vector de 3 comonentes Boolean
vector de 4 comonentes Boolean
vector de 2 comonentes enteros
vector de 3 comonentes enteros
vector de 4 comonentes enteros

13

mat2
mat3
mat4
mat2x2
mat2x3
mat2x4
mat3x2

matriz 2x2 de punto flotantes


matriz 2x3 de punto flotantes
matriz 2x4 de punto flotantes
algo como mat2
matriz con 2 columnas y 3 filas de punto flotantes
matriz con 2 columans y 4 filas de punto flotantes
matriz con 3 filas y dos columnas de punto
flotantes
algo como mat3
matriz de 3 filas y cuatro columnas de punto
flotantes
matriz de 4 filas y dos columnas de punto
flotantes
matriz de 4 filas y 3 columnas de punto flotantes
algo como mat4
un manejador para acceder a texturas 1D
un manejador para acceder a texturas 2D
un manejador para acceder a texturas 3D
un manejador para acceder a un cubo mapeado
de texturas
un manejador para acceder a una textura 1D con
comparacin
un manejador para acceder a una textura 2D con
comparacin

mat3x3
mat3x4
mat4x2
mat4x3
mat4x4
sampler1D
sampler2D
sampler3D
samplerCube
sampler1DShadow
sampler2DShadow

Adems un shader puede agregar estos usando arrays y estructuras para formar tipos ms
complejos.
4.1.1 VOID
Funciones que no devuelven un valor debe ser declarado nulo. No hay ningn tipo de retorno por
defecto
la
funcin.
El vaco de palabras clave no se puede utilizar en cualquier otras declaraciones (con excepcin de
las listas de parmetros formales vacos).
4.1.2 BOOLEANS
Para hacer una ejecucin condicional en el cdigo ms fcil de expresar, el tipo bool es
compatible. No hay expectativa de que el hardware soporte directamente las variables de este tipo.
Es un tipo especfico el booleano, la ocurrencia de slo uno de dos valores, ya sea verdadera o
falsa.
Dos
palabras
verdaderas
y
falsas
puede
ser
utilizado
como
literal
Boolean constantes. Se declaran las operaciones booleanas, y, opcionalmente, inicializada como
en la aplicacin de ejemplo:
bool success; // declare success to be a Boolean
bool done = false; // declare and initialize done
El lado derecho del operador de asignacin (=) puede ser cualquier expresin cuyo tipo es bool.
Las expresiones utilizadas para los saltos condicionales (si, por,?: Mientras, hacer-mientras) debe
evaluar el tipo bool.

14

4.1.3.

Integers

Los enteros vienen predefinidos en el lenguaje para ayudar al programador. A nivel de hardware,
su representacin real podra contribuir a la eficiencia de los bucles y de los ndices de los arrays,
as como referenciar las unidades de textura. Por ello no es requerido que los enteros
implementados en el lenguaje coincidan con su representacin hardware. Ni siquiera que soporte
el rango de los enteros. Dada su misin como mera ayuda, tan slo se exigen diecisis bits de
precisin, as como la representacin del signo; tanto para los lenguajes de vrtice como los de
fragmento. Una implementacin del OpenGL Shading Language podra convertir los enteros a
floats para operar con ellos. Se permite que una implementacin utilice ms de diecisis bits de
precisin para manipular los enteros, si bien la naturaleza de dicha implementacin no tendra que
ser soportada por otras mquinas. Aquellos shaders que sobrepasen los diecisis bits de precisin
podran no ser porttiles (portables).
Los enteros son declarados y opcionalmente inicializados con expresiones de tipo entero, como se
muestra en el siguiente ejemplo:
int i, j = 42;
Las constantes de tipo entero pueden ser expresadas en formato decimal (base 10), octal (base 8)
o hexadecimal (base 16) como sigue:
integer-constant:
decimal-constant
octal-constant
hexadecimal-constant
decimal-constant:
nonzero-digit
decimal-constant digit
octal-constant:
0
octal-constant octal-digit
hexadecimal-constant:
0x hexadecimal-digit
0X hexadecimal-digit
hexadecimal-constant hexadecimal-digit
digit:

0
nonzero-digit

nonzero-digit: uno de
123456789
octal-digit: uno de
01234567
hexadecimal-digit: uno de
0123456789
abcdef
ABCDEF

15

No se permiten espacios en blanco entre los nmeros que definen una constante, incluyendo
despus del 0 o del 0x o 0X. Si el signo - precede la constante ste ser interpretado como el
operador unario de negacin aritmtica, y no como parte de la constante. No hay sufijos con letra.
4.1.4.

Floats

Los flotantes estn disponibles para el uso de clculos escalares. Las variables de coma flotante
se definen como viene ejemplificado a continuacin:
float a, b = 1.5;
Como valor de entrada a una de las unidades de procesado, un valor en coma flotante se espera
que tenga la representacin del estndar IEEE para simple precisin y rango dinmico. No es
obligatorio que la precisin durante el procesado se ajuste a las especificaciones del IEEE, pero s
a las especificadas por la especificacin de OpenGL 1.4. Anlogamente, el tratamiento a
condiciones como la divisin por cero deberan desembocar en un resultado sin especificar, pero
en ningn caso ser causa de aborto de una ejecucin.
Las constantes en punto flotante son definidas como sigue:
floating-constant :
fractional-constant exponent-partopt floating-suffixopt
digit-sequence exponent-part floating-suffixopt
fractional-constant :
digit-sequence . digit-sequence
digit-sequence .
. digit-sequence
exponent-part :
e signopt digit-sequence
E signopt digit-sequence
sign : uno de
+
digit-sequence :
digit
digit-sequence digit
floating-suffix: uno de
fF
Un punto decimal (.) no es necesario si la parte del exponente est presente. No puede haber
ningn espacio en blanco interrumpiendo una secuencia de coma flotante. Si el signo - precede la
constante ste ser interpretado como el operador unario de negacin aritmtica, y no como parte
de la constante.
4.1.3.

Vectors

El lenguaje OpenGL Shading Language incluye tipos de datos correspondientes con vectores de
dos, tres y hasta cuatro dimensiones en coma flotante, enteros o booleanos. Los vectores de
variables en coma flotante pueden ser usadas para almacenar gran cantidad de informaciones muy
importantes en los grficos en computacin, como colores, normales, posiciones, coordinadas de
texturas, etc. Los vectores booleanos pueden ser usados para comparaciones entre vectores
numricos. Definir vectores como parte del lenguaje de shaders permite una relacin directa entre
el lenguaje y su representacin en el hardware de procesado grfico. En general, las aplicaciones
podrn aprovechar este paralelismo, ganando as en eficiencia. Algunos ejemplos de la declaracin
de vectores son:

16

vec2 texcoord1, texcoord2;


vec3 position;
vec4 myRGBA;
ivec2 textureLookup;
bvec3 less;
La inicializacin de vectores se puede realizar a travs de constructores, que sern explicados en
breve.
4.1.4. Matrices
El lenguaje OpenGL Shading Language tiene predefinidas matrices con valores en coma flotante
de 2x2, 2x3, 2x4, 3x2, 3x3, 3x4, 4x2, 4x3, 4x4. El primer nmero de este tipo es el nmero de
columnas, y el segundo el de filas. Son ejemplos de declaracin de matrices:
mat2 mat2D;
mat3 optMatrix;
mat4 view, projection;
mat4x4 view; // una forma alternativa de declarar una matriz 4x4
mat3x2 m; // una matriz con tres columnas y dos filas
La inicializacin de las matrices se hace mediante constructores (descritos en la seccin 5.4
1
Constructores) ordenando por columnas de mayor a menor .
4.1.7.

Samplers

Las variables de tipo Sampler son herramientas para trabajar con texturas. Son usadas con las
funciones predefinidas que actan sobre las texturas (descritas en la seccin 8.7 Funciones de
Bsqueda de Textura) para indicar a cul de ellas acceder. Slo pueden ser declaradas como
parmetros de funciones o variables uniformes (ver la seccin 4.3.5 Uniforme). Salvo el indexado
de las matrices, la seleccin del campo de la estructura y los parntesis, los samplers no pueden
ser operandos en una expresin, ni tratarse como l-valores, ni parmetros de salida o entrada y
salida de las funciones, ni pueden ser asignados dentro de una funcin. Como constantes, ellas
son inicializadas slo con la API de OpenGL, no pueden ser declaradas o inicializadas en un
shader. Como parmetros de funcin, slo los samplers deberan ser pasados a los samplers de
comparacin de tipos. Esto aporta robustez en la comparacin de los accesos de las texturas de
los shaders y el estado de las texturas de OpenGL antes de que se ejecute un shader.
4.1.8.

Estructuras

Los tipos definidos por el usuario pueden ser creados aadiendo otros tipos ya definidos dentro de
una estructura utilizando la palabra clave struct. Por ejemplo:
Struct light{
float intensity;
vec3 position;
} lightVar;
En este ejemplo, light es el nombre de un nuevo tipo, y lightVar es una variable del tipo light. Para
declarar variables del nuevo tipo se utiliza este nombre (sin la palabra clave struct).
light lightVar2;
De modo ms formal, las estructuras son declaradas como a continuacin. De todas formas, la
gramtica se ve en la seccin 9, Gramtica del Lenguaje de Shaders.
1

En el manual original el orden viene explicado como in column-major order

17

struct-definition :
qualifieropt struct nameopt { member-list } declaratorsopt ;
member-list :
member-declaration;
member-declaration member-list;
member-declaration :
basic-type declarators;
donde name es el tipo definido por el usuario, pudiendo ser usado para declarar variables de ste
nuevo tipo. El name comparte el mismo espacio de nombre que las otras variables, tipos y
funciones, quedando sujeto a las mismas reglas. El qualifier opcional slo se aplica a cualquier
declarators, y no forma parte del tipo definido por name.
Las estructuras deben tener al menos un miembro. Los miembros declarados no contienen ningn
cualificador, ni contienen campos de bits. Los tipos de los miembros deben estar ya definidos (no
hay referencias previas). Los miembros declarados no pueden contener inicializadores, aunque s
pueden contener matrices. Esas matrices deben tener un espacio especificado, y el tamao debe
ser una expresin entera constante mayor que cero (ver la seccin 4.3.3 Expresiones
Constantes). Cada nivel de la estructura tiene su propio espacio de nombre para su nombre dado
en los declaradores de miembro; tales nombres necesitan ser unicos solamente del espacio del
nombre. Las estructuras annimas no se permiten, ni tampoco las estructuras embebidas.
struct S { float f; };
struct T {
S; // Error: no se permiten estructuras annimas
struct { ... }; // Error: no se permiten estructuras embebidas
S s; // Ok: las estructuras anidadas con nombre son permitidas
};

Las estructuras pueden ser inicializadas en la declaracin usando constructores, que sern
explicados en la seccin 5.4.3 Constructores de Estructuras.
4.1.9.

Matrices

Las variables del mismo tipo pueden ser agrupadas en matrices declarando un nombre seguido de
unos parntesis ([]) encerrando opcionalmente un tamao. Cuando se especifica un tamao de la
matriz en la declaracin ste debe ser una expresin de tipo entero (ver la seccin 4.3.3
Expresiones Constantes) mayor que cero. Si una matriz es indexada con una expresin que no
es una expresin entera constante, o si la matriz es pasada como argumento a una funcin,
entonces su tamao debe ser declarado antes de su uso. Se permite declarar una matriz sin un
tamao y ms tarde redeclarar el mismo nombre como un array del mismo tipo indicando el
tamao. No se permite declarar una matriz con un tamao para, posteriormente (en el mismo
shader), indexar la misma matriz con una constante de tipo entero mayor o igual que la declarada.
Tampoco se permite indexar una matriz con una expresin entera constante negativa. Las matrices
declaradas como parmetros formales en la declaracin de una funcin deben especificar su
tamao. No est fefinido el comportamiento ante la indexacin de una matriz con una expresin no
constante que sea mayor o igual que el tamao del array, o bien sea menor que cero. Slo las
matrices de una dimensin podran ser declaradas. Todos los tipos y estructuras bsicas pueden
ser agrupadas en matrices. Algunos ejemplos son:
float frequencies[3];
uniform vec4 lightPosition[4];
light lights[];
const int numLights = 2;

18

light lights[numLights];
Un tipo de matriz puede ser creado especificando el tipo seguido de los parntesis cuadrados ([]) e
incluyendo el tamao:
float[5];
Este tipo puede ser usado en cualquier lugar donde otro tipo puediera ser usado, incluyendo el
valor de retorno de una funcin:
float[5] foo() {}
como constructor de una matriz:
float[5](3.4,4.2,5.0,5.2,1.1)
como un parmetro annimo:
void foo(float[5])
y como un modo alternativo de declarar una variable o un parmetro de funcin:
float[5] a;
Es un error declarar matrices de matrices:
float a[5][3]; //ilegal
float[5] a[3]; //ilegal
Las matrices pueden tener inicializadores formados por constructores de matrices:
float a[5] = float[5](3.4,4.2,5.0,5.2,1.1)
float a[5] = float[](3.4,4.2,5.0,5.2,1.1)
Las matrices sin signo pueden ser explcitamente dimensionadas por un inicializador en su
declaracin:
Float a[5];
...
float b[] = a; //b es de tamao 5
float b[5] = a; //es lo mismo
De todos modos, el dimensionamiento de las matrices no puede ser asignado. Resulta raro que los
inicializadores y las asignaciones parecieran tener diferentes semnticas.
Las matrices saben el numero de elementos que contienen. ste puede ser obtenido usando el
mtodo length:
a.length(); // devuelve 5 para las declaraciones anteriores
El mtodo length no puede ser invocado en una matriz que no ha sido explcitamente
dimensionada.

19

4.1.10. Conversiones implcitas


En determinadas situaciones una expresin y su tipo pueden ser convertidas a otro tipo diferente.
La siguiente tabla muestra todas las conversiones implcitas:
Tipo de expresin
entero
ivec2
ivec3
ivec4

Puede ser convertida implcitamente a


flotante
vec2
vec3
vec4

No hay conversiones implcitas entre matrices o estructuras. Por ejemplo, una matriz de enteros no
podra ser convertida a una matriz de flotantes.
Cuando se realiza una conversin implcita no se realiza una reinterpretacin de su valor, sino una
conversin al valor equivalente en el otro tipo. Por ejemplo, el entero 5 ser convertido al valor en
coma flotante 5,0.
Las conversiones de la tabla superior son realizadas slo en los casos indicados en otras
secciones de este manual.
4.2.

Alcance

El alcance de una variable se establece en el momento de su declaracin. Si es declarada fuera de


todas las definiciones de funciones, sta tiene un alcance global, existiendo desde el momento que
es declarada hasta la terminacin del shader en el que ha sido declarada. Si es declarada en un
bucle for o while, sta durar hasta la salida del bucle. En cualquier caso, si es declarada en una
sentencia simple tendra alcance en la sentencia compuesta de la que forme parte. Si es declarada
como parmetro de una funcin sta tendr alcance dentro de la funcin. El cuerpo de una funcin
tiene alcance slo dentro de la misma. La sentencia if no permite la declaracin de variables en su
interior, de modo que no puede hablarse de su alcance.
Dentro de una declaracin, el alcance de una variable comienza inmediatamente antes del
inicializador si ste estuviese presente o inmediatamente despus de que su nombre haya sido
declarado en el caso contrario. Algunos ejemplos son:
int x = 1;
{
int x = 2, y = x; // y es inicializada a 2
}
struct S
{
int x;
};
{
S S = S(0,0); // S slo es visible como estructura y constructor
S; // S ahora es visible como variable
}
int x = x; // Error si x no ha sido previamente definido
Todos los nombres de variables, de tipos de estructuras y de funciones para un determinado
alcance comparten un mismo espacio de nombres. Los nombres de las funciones pueden ser
redeclarados en el mismo alcance, con un nmero de parmetros igual o diferente, sin que esto

20

sea un error. Una matriz con tamao implcito puede ser redeclarada en el mismo alcance como
una matriz del mismo tipo base. En cualquier caso, dentro de una unit, un nombre declarado no
puede ser redeclarado en el mismo alcance; ello conllevara un error de redeclaracin. Si un
alcance anidado redeclara un nombre usado en otro alcance ste oculta todos los usos de ese
nombre. No hay forma de acceder a ste nombre oculto ni de hacer que sea visible sin salir del
alcance que lo ha escondido.
Las funciones predefinidas tienen un alcance dentro de otro alcance diferente al alcance global de
usuario(donde son definidas las variables globales). Es decir, un alcance global de shaders donde
el usuario escribe las variables globales y las funciones, est anidado en otro alcance donde
vienen las funciones predefinidas. Cuando el nombre de una funcin es redefinido en un alcance
anidado oculta aquellas funciones que tenan el mismo nombre en alcances diferentes. La
declaracin de funciones (prototipo) no pueden ser definidas dentro de otras funciones. Tienen que
definirse en el alcance global, o, para las funciones predefinidas, fuera del alcance global.
Las shared globals son variables globales declaradas con el mismo nombre en unidades
compiladas independientes (shaders) del mismo lenguaje (de vrtice o de fragmento) que son
ensambladas para hacer un programa.
Las shared globals comparten el mismo, y deben ser declaradas con el mismo tipo. Compartirn el
mismo lugar de almacenamiento. Las matrices compartidas globales deben tener el mismo tipo
base y el mismo tamao explcito. Una matriz con tamao implcito en un shader puede pasar a
tener el tamao explcito por otro shader. Si ninguno de los shaders tiene un tamao explcito para
la matriz sta adquirir el mayor tamao implcito. Los escalares deben tener exactamente el
mismo tipo y la misma definicin de tipo. Las estructuras deben tener el mismo nombre, la misma
secuencia de nombres y definiciones de tipo, y los campos asociados a cada nombre deben de ser
del mismo tipo. Esta regla se aplica recursivamente a los tipos anidados. Todos los inicializadores
para un shared global tienen que tener el mismo valor, o se producir un error en el ensamblado.
4.3.

Cualificadores de almacenado

La declaracin de variables podra tener un cualificador de almacenado delante del tipo. Vienen
descritos como sigue:
Cualificador
< none: default >
const
attribute
uniform
varying
centroid varying

Significado
lectura/escritura en memoria local o parmetro de
entrada de una funcin
una constante en tiempo de compilacin o un parmetro
de slo lectura
unin entre un shaders de vrtice y OpenGL para datos
de vrtices
valor invariable durante el procesado de la primitiva,
forman la unin entre un shader, OpenGL y la aplicacin
unin entre un shader de vrtice y uno de fragmento
para la interpolacin de datos

Las variables globales slo pueden usar como cualificadores const, attribute, uniform, varying o
centroid varying.
Las variables locales slo pueden usar el cualificador de almacenado const.
Los parmetros de funcin slo pueden usar el cualificador const. Los cualificadores de parmetros
son comentados con ms detalle en la seccin 6.1.1 Convencin de Llamadas a Funciones.
Los tipos de retorno de funciones y los campos de estructuras no usan cualificadores de
almacenado.

21

No existen tipos de datos para la comunicacin desde la ejecucin de un shader a su prxima


ejecucin (para la comunicacin entre fragmentos o vrtices). Esto debera prevenir la ejecucin en
paralelo del mismo shader en mltiples vrtices o fragmentos.
Los inicializadores slo pueden ser usados en variables globales sin cualificador de almacenado,
con el cualificador const o con el cualificador uniform. Las variables globales sin cualificador de
almacenado que no estn inicializadas en su declaracin o por la aplicacin no sern inicializadas
por OpenGL, o mejor dicho sern entendidas en el main() como valores indefinidos.
4.3.1.

Cualificador de almacenado por defecto

Si no hay ningn cualificador presente en una variable global entonces sta no puede ser usada en
la aplicacin o en otros shaders que se estn ejecutando en procesadores distintos. Para variable
global o local sin cualificar, la declaracin servir para reservar memoria del procesador que
corresponda. Esta variable permitira las operaciones de acceso a lectura y escritura para esta
memoria destinada.
4.3.2.

Const

Las llamadas constantes en tiempo de ejecucin pueden ser declaradas usando el cualificador
const. Cualquier variable con el cualificada como constante es de slo lectura para ese shader.
Declarar las variables como constantes permite codificar shaders de modo mucho ms descriptivo
que usando constantes numricas. El cualificador const puede usarse con cualquier tipo de datos
bsico. Es un error asignar una constante fuera de su declaracin; tiene que ser inicializada con
sta. Por ejemplo:
const vec3 zAxis = vec3 (0.0,0.0,1.0);
Los campos de las estructuras no pueden ser cualificados con const, si bien las estructuras
pueden ser declaradas con const y ser inicializadas con un cosntructor.
Los inicializadores para declaraciones constantes deben ser expresiones constantes, como se
explica en la seccin 4.3.3 Expresiones Constantes.
4.3.3.

Expresiones constantes

Una expresin constante es una de:

un valor literal (por ejemplo, 5 o true)


una variable local o global cualificada con const (sin inclur los parmetros de funcin)
una expresin formada por operadores y operandos que constituyen una expresin
constante, incluyendo tomar el elemento de una matriz, un campo de una estructura
constante, o componentes de un vector constante
un constructor cuyos argumentos son todos expresiones constantes
la llamada a una funcin predefinida cuyos argumentos son expresiones constantes, a
excepcin de las funciones de apariencia de texturas, las funciones de ruido y ftransform.
Las funciones predefinidas dFdx, dFdy y fwith deben devolver 0 cuando son evaluadas
dentro de un inicializador con un argumento que es una expresin constante

Las llamadas a funciones definidas por el usuario (funciones no predefinidas) no pueden usarse
como expresiones constantes
Una expresin constante literal es una expresin que se evala a un entero escalar.

22

Las expresiones constantes sern evaluadas sern evaluadas siempre del mismo modo para que
en distintos shaders las mismas expresiones den lugar a los mismos resultados. Ver la seccin
4.6.1 El Cualificador Constante para ms detalles sobre cmo crear expresiones constantes.
4.3.4.

Atributo

El cualificador attribute se usa para declarar variables que son pasadas a un shader de vrtice
desde OpenGL a una base para vrtices. Es un error declarar una variable como atributo en
cualquier shader que no sea de tipo vrtice. Las variables atributo son de slo lectura para el
shader de vrtice. Los valores de dichas variables son pasadas al shader de vrtice desde la API
de vrtice de OpenGL como parte de una matriz de vrtice. Tales valores transportan los atributos
de vrtice al shader de vrtice y se espera que cambien cada vez que se ejecuta un shader de
vrtice. El cualificador de atributo slo puede ser usado con flotantes, vectores de flotantes y
matrices, mientras que no puede ser usado en estructuras.
Ejemplos de declaraciones:
attribute vec4 position;
attribute vec3 normal;
attribute vec2 texCoord;
Todos los atributos de vrtice estndares de OpenGL tienen nombres de variables predefinidos
para permitir una mayor integracin entre los programas de OpenGL y las funciones de vrtice. Ver
la seccin 7 Variables Predefinidas para ver la lista completa de los nombres de atributos
predefinidos.
Se espera que el hardware grfico tenga un pequeo nmero de lugares destinados al paso de los
atributos de vrtice. Por lo tanto, el lenguaje GLSL define las varialbes que no sean matrices como
si tuviesen espacio para hasta cuatro valores en coma flotante. ste es un lmite de
implementacin en el nmero de variables de tipo atributo que pueden ser usadas. Si ste fuese
excedido se producira un error de ensamblado (las varialbes atributo declaradas no usadas no se
tienen en cuenta a la hora de verificar el lmite). Un atributo flotante cuenta de la misma forma que
un vector de tipo vec4, por lo que podra contemplarse el agrupar de cuatro en cuatro los atributos
flotantes en un vec4 a fin de aprovechar mejor el hardware subyacente al shader. Una matriz como
atributo usara varios lugares de de atributo; tantos como nmero de columnas tenga.
Las variables atributo son necesarias para tener un alcance global y deben ser declaradas fuera
del cuerpo de las funciones antes de ser usadas.
4.3.5.

Uniforme

El cualificador uniform se usa para declarar variables cuyos valores son los mismos durante la
misma primitiva que se est procesando. Todas las variables uniformes son de slo lectura y son
inicializadas externamente bien durante el ensamblado o bien por medio de la API. El valor inicial
durante el ensamblado puede ser el valor del inicializador, de estar ste presente; o 0, si no lo
estuviera. Los tipos muestreados no pueden tener inicializadores.
Son ejemplos de declaracin:
uniform vec4 ligthPosition;
uniform vec3 color = vec3(0.7,0.7,0.2);
El cualificador uniforme puede utilizarse con cualquier tipo de datos bsico, declarando una
estructura, una matriz o cualquier otra variable.

23

Hay un lmite debido a la implementacin en la cantidad de almacenamiento de uniformes que


pueden ser usados para cada tipo de shader y, de excederse, causara un error en tiempo de
compilacin o de ensamblado. Las variables uniformes que son declaradas pero no usadas no se
tienen en cuenta a la hora de verificar el lmite. El nmero de variables uniformes definidas por el
usuario y predefinidas que son usadas en un shader se emplean para determinar si se excede el
citado lmite.
Si se ensamblan juntos varios shaders stos compartirn el espacio reservado a las uniformes. Por
tanto, los tipos e inicializadores de variables uniformes con el mismo nombre deberan coincidir en
todos los shaders a ensamblar para crear un ejecutable. Se permite que algunos shaders aporten
su propio inicializador para una variable mientras que otros no lo aporten, pero todos los
inicializadores deben ser iguales.
4.3.6.

Mutantes

Las variables mutantes proporcionan la interfaz entre los shaders de vrtice, los de fragmento y la
2
funcionalidad arreglada entre ellos. Los shaders de vrtice procesan valores de vrtice (como el
color, la textura, las coordinadas, etc) y las escriben en variables declaradas con el cualificador
varying. Adems, tal vez lea variables declaradas como varying, devolviendo los mismos valores
si fueran escritos. Leer un mutante en un shader de vrtice devuelve valores indefinidos si stos
fuesen ledos antes de ser escritos.
Por definicin, los mutantes son establecidos por vrtice e interpolados respecto a la perspectiva
sobre la primitiva que est siendo renderizada. En single-sampling, el valor es interpolado al centro
del pixel, y el cualificador centroid, de estar presente, sera ignorado. En multi-sampling y el
varying no est cualificado por el centroid, el valor debe ser interpolado al pixel del centro, en
cualquier lugar en el pixel o en uno de los pixels de muestra. Si estuviese presente el centroid
entonces el valor deber ser interpolado que descanse tanto en el pixel como en en la primitiva que
est renderizndose, o bien en uno de los pixeles de muestra que estn dentro de la primitiva.
Debido a la menor regularidad de ubicacin de los centroides, sus derivadas podran ser menos
precisos que las variables mutantes que no tengan centroide.
Cuando se usa la palabra reservada centroid sta debe preceder al cualificador varying.
Un shader de fragmento podran leer de variables mutantes y su valor sera el valor interpolado de
las variables, como una funcin de la posicin de los fragmentos en la primitiva. Un shader de
fragmento no puede escribir en un mutante.
El tipo y presencia de los cualificadores centroid y invariant de variables mutantes con el mismo
nombre declarados en en los shaders de vrtice y fragmentos ensamblados debe coincidir, o se
producir un error de ensamblado. Slo aquellos mutantes usadas en shaders de fragmento
ejecutable deben escribirse a travs de un shader de vrtice ejecutable. Declarar mutantes
superfluos en un shader de vrtice es admitido.
Ejemplos de declaracin de mutantes:
varying vec3 normal;
centroid varying vec2 TextCoord;
invaring centroid varying vec4 Color;
El cualificador varying slo se puede aplicar a flotantes, vectores de flotantes, o matrices de
flotantes. Las estructuras no pueden ser mutantes.

En el manual original se refiere a ello como fixed functionality

24

Si no hay ningn shader de vrtice activo, el camino de datos de funcionalidad corregida de


OpenGL procesar valores de los mutantes predefinidos que sern consumidos por el shader de
fragmento ejecutable. Igualmente, si no hubiese ningn shader de fragmento activo sera el shader
de vrtice el responsable de procesar y escribir los mutantes que son necesitados por el camino de
datos de funcionalidad corregida de OpenGL.
Los mutantes se necesitan para tener un alcance global, y deben ser declarados fuera de los
cuerpos de funciones antes de su primer uso.
4.4.

Cualificadores de Parmetros

Los parmetros pueden tener los siguientes cualificadores:


Cualificador
<none : default>
in
out
inout

Significado
lo mismo que in
para parmetros de funcin recibidos por una funcin
para parmetros de funcin devueltos por una funcin, pero no
inicializados cuando son pasados
para parmetros de funcin que son recibidos y devueltos

Los cualificadores de parmetros son explicados con mayor detalle en la seccin 4.1.1
Convenciones de Llamadas a Funciones.
4.5.

Precisin y Cualificadores de Precisin

Nmero de seccin reservado para los cualificadores de precisin (reservado para usarlo
posteriormente).
4.6.

Mutantes y el Cualificador de Mutantes

En esta seccin los mutantes hacen referencia a la posibilidad de conseguir diferentes valores de
la expresin en diferentes programas. Por ejemplo, dados dos shaders de vrtice, en diferentes
programas, para el mismo uso de gl_Position, no son exactamente los mismos valores cuando el
programa se ejecuta. Es posible, debido a la compilacin independiente de los dos shaders, que
los valores asignados a gl_Position no sean los mismos durante la ejecucin. En este ejemplo
esto podra causar problemas de alineacin en la geometra de un algortimo que se ejecute en
varios pasos.
En general, dicha variacin entre los shaders es permitida. Cuando tal varianza no existe se dice
que la variable es invariante.
4.6.1.

El Cualificador Invariante

Para asegurar que una variable devuelta es invariante es necesario utilizar el cualificador
invariant. Incluso se puede usar este cualificador despus de declarar la variable.
invariant gl_Position; // hacer la posicin gl_Position invariante
varying vec3 Color;
invariant Color; // hacer el Color existente invariante
o como parte de una declaracin cuando una variable es declarada:
invariant varying vec3 Color;

25

El cualificador invariante puede preceder a cualquier cualificador de almacenamiento (varying)


cuando son combinados en una declaracin. Slo las variables de salida de un shader de vrtice
son candidatas a ser invariantes. Esto excluye las variables definidas por el usuario, los mutantes
predefinidos de lado de vrtice y las variables especiales de vrtice gl_Position y gl_PointSize.
Para los mutantes que estn saliendo de un shader de vrtice a un shader de frangmento con el
mismo nombre la palabra clave invariant debe estar presente en ambos shaders. Dicha palabra
puede estar precedida de una lista de indentificadores previamente declarados separada por una
3
coma . Cualquier uso de los invariantes debe ser de alcance global, y antes del mismo la variable
debera de estar previamente declarada.
Para garantizar la inmutabilidad de una variable de salida en dos programas deben cumplirse las
siguientes condiciones:

La variable de salida est declarada como invariante en ambos programas

Deben tener los mismos valores todas aquellas variables de entrada que contribuyan por
medio de expresiones y de flujo de control a la asignacin de la variable de salida

El formato de texturas, valores de texel y el filtrado de texturas son establecidos de la


misma forma para todas las llamadas de funciones de texturas que contribuyan al valor de la
variable de salida

Todos los valores de entrada son operados de la misma forma. Todas las operaciones en
las expresiones de consumo y en cualquier expresin intermedia deben ser las mismas, con el
mismo orden de operandos y la misma asociatividad, a fin de tener el mismo orden de evaluacin.
Las variables intermedias y las funciones deben ser declaradas con el mismo tipo con los mismos
cualificadores de precisin, explcitos o implcitos. Cualquier flujo de control que afece al valor de
salida debe ser el mismo, y cualquier expresin evaluada para determinar dicho flujo deben estar
sujetos a estas reglas

Todos los datos de flujo y control de flujo destinados a establecer la variable invariante de
salida deben de estar en una nica unidad de compilacin
Bsicamente, todos los flujos y controles de flujo que afecten al valor de salida deben coincidir.
Inicialmente, por defecto, todas las variables de salida pueden ser mutantes. Para forzar a que
todas las variables de salida sean invariantes puede usarse la directiva
#pragma STDGL invariant(all)
antes de todas las declaraciones del shader. Si esta directiva es usada despus de la declaracin
de alguna variable o de alguna funcin el comportamiento de la directiva no est definido. Es un
error utilizar esta directiva en un shader de fragmento.
Generalmente la invarianza se consigue en detrimento de la flexibilidad en las optimizaciones, as
que la puesta en marcha puede ser peor a causa de la invarianza. Por tanto el uso de esta
directiva es entendida como una tarea de depuracin, para evitar que se declaren individualmente
todas las salidas como invariantes.
4.6.2.

Invarianza de Expresiones Constantes

La invarianza debe de estar garantizada para las expresiones constantes. El resultado de la


evaluacin de una expresin constante debe ser siempre el mismo si ste apareciese de nuevo en
el mismo o en otro shader. Esto implica a la misma expresin apareciendo en shaders tanto de
fragmento como de vrtice o la misma expresin apareciendo en diferentes shaders de fragmento
o vrtice.
3

En el manual original la frase dice The invariant keyword can be followed by a comma
separated list of previously declared identifiers
26

Las expresiones constantes deben tener el mismo resultado cuando se opera con ellas en todas
las situaciones descritas anteriormente.
4.7.

Orden de los Cualificadores

Cuando hay varios cualificadores presentes stos deben seguir un orden estricto. Este orden es el
siguiente:
Cualificador invariante cualificador de almacenamiento
Cualificador de almacenamiento cualificador de parmetro

5. Operaciones y Expresiones
5.1.

Operadores

El GLSL tiene los siguientes operadores. Reservar estas marcas es ilegal.


Precedencia Clase de Operadores
1 (la mayor) establecimiento de prioridad
2
funcin de llamada a una matriz,
constructor
de
campos
de
estructuras o selector de mtodo,
incremento y decremento prefijo y
postfijo
3
incremento y decremento unario(la
tilde es reservada)
4
multiplicativo
(el
mdulo
es
reservado)
5
aditivo
6
desplazamiento de bits(reservado)
7
relacional
8
igualdad
9
y de bit (reservado)
10
o exclusiva de bit (reservado)
11
o inclusiva de bit (reservado)
12
y lgica
13
o exclusiva
14
O inclusiva
15
seleccin
16
asignaciones aritmticas (el mdulo,
el desplazamiento y los de bit estn
reservados)
17(la menor) secuencia

Operadores
()
[]
()
.
++ --

Asociatividad
Ninguna
de izquierda a derecha

++ -+-~!
*/%

de derecha a izquierda

+<< >>
< > <= >=
== !=
&
^
|
&&
^^
||
?:
=
+= -=
*= /=
%= <<= >>=
&= ^= |=
,

de izquierda a derecha
de izquierda a derecha
de izquierda a derecha
de izquierda a derecha
de izquierda a derecha
de izquierda a derecha
de izquierda a derecha
de izquierda a derecha
de izquierda a derecha
de izquierda a derecha
de derecha a izquierda
de derecha a izquierda

de izquierda a derecha

de izquierda a derecha

No hay un operador de direccin ni un operador de desreferenciado. Tampoco hay operador de


conversin de tipos; se usan los constructores en su lugar.
5.2.

Operaciones de Matrices

stas estn descritas en la seccin 5.7 Operaciones de Estructuras y Matrices.

27

5.3.

Llamadas de Funciones

Si una funcin devuelve un valor, entonces la llamada de la funcin podr ser usada como una
expresin, cuyo tipo ser el usado para declarar o definir la funcin.
Las definiciones de funciones y las convenciones de llamada se explican en la seccin 6.1
Definiciones de Funciones.
5.4.

Constructores

Los constructores usan la sintaxis de las funciones de llamada, donde el nombre de la funcin es
un tipo y la llamada hace al objeto de se tipo. Los constructores pueden usarse en expresiones y
en inicializaciones. (ver la seccin 9 Gramtica del Lenguaje de Shading para ms detalles). Los
parmetros son utilizados para inicializar el valor construido. Los constructores pueden ser usados
para convertir un tipo escalar a otro tipo escalar, o para construir tipos de mayor rango a partir de
tipos de menor rango, o reducir un tipo de mayor rango a uno de menor rango.
En general, los constructores no son funciones predefinidas con prototipos determinados. Para las
matrices y las estructuras debe haber exactamente un argumento por cada elemento o campo.
Para los dems tipos los argumentos deben de dar un nmero suficiente de elementos para
realizar la inicializacin, y es un error inclur ms argumentos de los que pueden ser usados. Las
reglas se detallan a continuacin. Los prototipos actualmente citados abajo son slo un
subconjunto de ejemplos.
5.4.1.

Conversin y Constructores Escalares

La conversin entre diferentes tipos escalares se hace como los siguientes ejemplos indican:
int(bool); // convierte un valor booleano en un entero
int(float); // convierte un valor flotante en un entero
float(bool); // convierte un valor booleano en un flotante
float(int); // convierte un valor entero en un flotante
bool(int); // convierte un valor entero en un booleano
bool(float); // convierte un valor flotante en un booleano
Cuando los constructores se utilizan para convertir un flotante a un entero la parte fraccional del
valor en coma flotante se desprecia.
Cuando un constructor se utiliza para convertir un entero o un flotante en un booleano, 0 y 0.0 son
convertidos a false y cualquier otro valor es convertido a true. Cuando un constructor se usa para
convertir un booleano a un entero o a un flotante false es convertido a 0 o 0.0 y true es convertido
a 1 o 1.0.
Los constructores identidad, como float(float) tambin se permiten, aunque no tienen utilidad.
Los constructores escalares sin parmetros escalares pueden usarse para tomar el primer
elemento de un tipo no escalar. Por ejemplo, el constructor float(vec3) seleccionar el primer
elemento del parmetro vec3.
5.4.2. Vectores y matrices de constructores.
Estos pueden ser usados para crear vectores o matrices a partir de un conjunto de escalares,
vectores y matrices. Esto incluye la capacidad de reducir el tamao de vectores.

28

Si hay un parmetro escalar para convertirlo en un vector, inicializaremos todos los componentes
del constructor del vector con sus valores escalares. Por otro lado si queremos conseguir una
matriz se inicializar la diagonal de la matriz y el resto de valores quedarn a cero.
Si un vector es construido por mltiples escalares, vectores, matrices o una mezcla de estos, los
componentes del vector sern construidos en el mismo orden que los argumentos. Los argumentos
se leern de izquierda a derecha y se trabajar cada argumento y no se comenzar con el
siguiente hasta acabar con el anterior. De forma similar se construye una matriz a partir de
escalares y vectores. Los componentes de la matriz sern construidos y trabajados por columnas.
En este caso debera haber la condicin de que el argumento fuese inicializado para todos los
valores del constructor. Es un error considerar ms argumentos de los necesarios ms all del
argumento usado.
Si una matriz es construida a partir de otra matriz, entonces cada componente (columna i, fila j) en
el resultado se corresponde con otro par i,j. de los valores de inicializacin. Los otros componentes
sern inicializados a la matriz identidad. Si dan a un argumento de la matriz un constructor de la
matriz, es un error tener cualquier otro argumento.
Si el tipo bsico (boolean, entero, o decimal) de un parmetro de un constructor no empareja el tipo
bsico del objeto construido, las reglas de construccin escalares son usadas para convertir los
parmetros.
Estos son algunos usos del constructor de vectores:
vec3(float) // Inicializa cada componente con el decimal
vec4(ivec4) // Convierte un ivec4 a u vec4
vec2(float, float) // Incializa vec2 con 2 decimales
ivec3(int, int, int) // Incializa un ivec3 con 3 enteros
bvec4(int, int, float, float) // Convierte 4 valores a un vector de boolean
vec2(vec3) // Elimina la tercera componente del vec3
vec3(vec4) // Elimina la cuarta componente del vec4
vec3(vec2, float) // vec3.x = vec2.x, vec3.y = vec2.y, vec3.z = decimal
vec3(float, vec2) // vec3.x = decimal, vec3.y = vec2.x, vec3.z = vec2.y
vec4(vec3, float)
vec4(float, vec3)
vec4(vec2, vec2)
Algunos ejemplos de esto son:
vec4 color = vec4(0.0, 1.0, 0.0, 1.0);
vec4 rgba = vec4(1.0); // Pone cada componente a 1.0
vec3 rgb = vec3(color); // Elimina la cuarta componente
Para inicializar los elementos de la diagonal de una matriz dejando los otros a cero:
mat2(float)
mat3(float)
mat4(float)
Para inicializar una matriz a partir de vectores o escalares especificos, los componentes se asignan
a los elementos de la matriz por columnas:
mat2(vec2, vec2); // Una columna por argumento
mat3(vec3, vec3, vec3); // Una columna por argumento
mat4(vec4, vec4, vec4, vec4); // Una columna por argumento
mat3x2(vec2, vec2, vec2); // Una columna por argumento
mat2(float, float, // Primera columna
float, float); // Segunda columna
mat3(float, float, float, // Primera columna
float, float, float, // Segunda columna

29

float, float, float); // tercera columna


mat4(float, float, float, float, // Primera columna
float, float, float, float, // segunda columna
float, float, float, float, // tercera columna
float, float, float, float); // Cuarta columna
mat2x3(vec2, float, // primera columna
vec2, float); // segunda columna
Exite una amplia gama de posibilidades, para construir una matriz a partir de vectores y escalares,
tan larga como componentes son necesarios para inicializarla
Para construir una matriz a partir de una matriz:
mat3x3(mat4x4); // Escoge la matriz superior izquierda de 3x3 de la mat4x4
mat2x3(mat4x2); // Escoge la matriz superior izquierda de 2x2 de la mat4x4, ultima fila a 0,0
mat4x4(mat3x3); // coloca la mat3x3 en la parte superior izquierda, pone el componente inferior
derecho a 1, y el resto a 0
5.4.3. Constructor de estructuras
Una vez que una estructura es definida, y dan a su tipo un nombre, un constructor est disponible
con el mismo nombre para construir dicha estructura. Por ejemplo:
struct luz {
float intensidad;
vec3 posicion;
};
luz luzVariable = luz(3.0, vec3(1.0, 2.0, 3.0));
Los argumentos del constructor sern usados para poner los campos de la estructura, usando un
argumento por campo. Cada argumento debe ser del mismo tipo que el campo que este pone, o
ser un tipo que puede ser convertido al tipo del campo segn la Seccin 4.1.10" Conversiones
Implcitas. "
Los constructores de estructuras pueden ser usados como inicializadores o en expresiones.
5.4.4. Constructor de arrays
El tipo array puede usarse como nombre de constructor, el cual tambien puede usarse en
expresiones o inicializaciones.
Por ejemplo:
const float c[3] = float[3](5.0, 7.2, 1.1);
const float d[3] = float[](5.0, 7.2, 1.1);
float g;
...
float a[5] = float[5](g, 1, g, 2.3, g);
float b[3];
b = float[3](g, g + 1.0, g + 2.0);
Debe haber exactamente el mismo numero de argumentos como tamao del array al ser
construido. Si el tamao no esta presente en el constructor, entonces el array tendr como tamao
el numero de argumentos. Los argumentos son asignados en orden, comenzando por el cero hasta
el final del array. Cada argumento debe ser del mismo tipo que los elementos del array, o ser de un
tipo que pueda ser convertido de acuerdo con la seccin: 4.1.10 Conversiones implicitas

30

5.5. Componentes de los vectores


Los nombres de los componentes de un vector se denotan por una letra minscula. Por convenio,
se entiende que las letras maysculas se asocian con otro componente relacionados con
posiciones, colores y texturas. Se puede acceder a la componente de un vector siguiendo el
nombre de la variable con un punto y el nombre de la componente.
Estos son los nombres para las componentes:
{x,y,z,w}
{r,g,b,a}
{s,t,p,q}

Acceso a vectores que representan puntos o


normales
Vectores que representan colores
Vectores que representan texturas

Los nombres de las componentes x,r, y s son, por ejemplo, sinominos para referirnos a la primera
componente.
Notese que la tercera componente de las texturas, en OpenGL, ha sido renombra como p para
evitar la confusion con r (de rojo) en el color.
Es un error acceder a componentes que van ms all de las que tenemos declarados, por ejemplo:
vec2 pos;
pos.x // is legal
pos.z // is illegal
La sintaxis para seleccionar componentes permite que multiples componentes sean selecionadas
aadiendo sus nombres (desde la misma seleccion) despus del punto( . ).
vec4 v4;
v4.rgba; // es un vec4 y es como usar como v4,
v4.rgb; // es un vec3,
v4.b; // es un decimal,
v4.xy; // es un vec2,
v4.xgba; // es un error- El nombre de la componente no pertenece al mismo conjunto

El orden de las componentes puede ser diferente o incluso estar replicados:


vec4 pos = vec4(1.0, 2.0, 3.0, 4.0);
vec4 swiz= pos.wzyx; // swiz = (4.0, 3.0, 2.0, 1.0)
vec4 dup = pos.xxyy; // dup = (1.0, 1.0, 2.0, 2.0)

Esta notacin es ms concisa que la sintaxis de constructor. Para formar un valor de r, puede ser
aplicado a cualquier expresin que causa un valor de r.
La notacin de grupo componente puede aparecer al lado izquierdo de una expresin.
vec4 pos = vec4(1.0, 2.0, 3.0, 4.0);
pos.xw = vec2(5.0, 6.0); // pos = (5.0, 2.0, 3.0, 6.0)
pos.wx = vec2(7.0, 8.0); // pos = (8.0, 2.0, 3.0, 7.0)
pos.xx = vec2(3.0, 4.0); // Error - 'x' usado dos veces
pos.xy = vec3(1.0, 2.0, 3.0); // Error- Desajuste entre un vec2 y un vec3
Para formar un valor de l, debe ser aplicado a un valor de l del tipo de vector, no contener ningunos
componentes dobles, y esto causa un valor de l escalar o del tipo de vector, dependiendo del
nmero de componentes especificados.
La sintaxis de arrays puede tambin ser aplicada a vectores con ndices numricos:
vec4 pos;

pos[2] se refiere al tercer elemento de pos y equivale a pos.z. Esto permite que las variables sean
indexadas en un vector, como un acceso generico. Cualquier expresin de enteros puede ser
usada.

31

La primera componente es el indice 0. Leyendo o escribiendo en un vector usando cualquier


expresin que tenga un valor negativo o mayor que el tamao del array produce un error.
Cuando indexamos con expresiones no constantes, su comportamiento no esta definido cuando el
valor es negativo o mayor que el tamao del vector.
5.6. Elementos de matrices
Los elementos de las matrices pueden ser accedidos usando la sintaxis de los arrays. Aplicando un
subndice a una matriz considera la matriz como un conjunto de columnas, y selecciona solo una,
cuyo tipo es un vector del mismo tamao de la matriz. La columna de ms a la izquierda es la
columna 0. Un segundo ndice actuara sobre la columna,. Entonces, dos subndices seleccionan
uno las columnas y otro la fila.
mat4 m;
m[1] = vec4(2.0); // Incializa la segunda columna con valor 2.
m[0][0] = 1.0; // Elemento superior izquierda valor 1.0
m[2][3] = 2.0; // Cuarto elemento de la segunda columna con valor 2.0

El comportamiento se considera indefinido cuando se accede a un elemento que esta fuera de los
limites de la matriz con una expresin no constante.
Es un error acceder a un elemento de una matriz que esta fuera de los limites de esta con una
expresin constante
5.7. Operaciones con arrays y estructuras
Los campos de un estructura y el procedimiento length de los arrays se llaman usando un punto (

.)

En total, solo los siguientes operadores son usados para operar con arrays y estructuras:
Seccionar un campo
Igualdad
Asignacin
Acceso con ndices(solo arrays)

.
== !=
=
[]

Los operadores de asignacin y igualdad son solo permitidos si los dos operandos tienen el mismo
tamao y son del mismo tipo. Las tipos de estructuras deben ser de la misma declaracin de la
estructura. Los dos operadores en los arrays deben tener el mismo tamao explcito. Cuando
usamos el operador de igualdad, dos estructuras son iguales si y solo si todos los campos son
exactamente iguales, y dos arrays son iguales si y solo si, todos los elementos del array son
exactamente iguales.
Los elementos de los arrays son accedidos usando el operador []. Un ejemplo de acceso en un
array es:
difusseColor+= IntensidadLuz[3] * NdotL;
El ndice de los arrays empieza en 0. El acceso a los elementos usa un expresin que trabaja con
tipos enteros.
El comportamiento es indefinido cuando el ndice vinculado a un array es menor que 0 o mayor o
igual que el tamao con el que fue declarado.
Los arrays pueden ser accedidos tambin con el operador ( .) y el mtodo length para conocer la
longitud del array.
IntensidadLuz.length() // devuelve el tamao del array

32

5.8. Asignaciones
La asignacin de valores a nombres de variables son hechos con el operador ( = ), como:
lvalor=expresin
El operador de asignacin almacena el valor de la expresin en la variable lvalor. Expresin y lvalor
deben ser del mismo tipo, o la expresin debe tener su tipo en la seccin 4.1.10 Conversiones
implcitas para convertir al tipo de lvalor. En este caso la conversin implcita debe realizarse antes
de la asignacin. Cualquier otro tipo de conversin deseada debe ser especificado en el
constructor. Lvalor tiene que ser modificable. Las variables que se crean a partir de tipos,
estructuras o arrays, campos de estructuras, lvalor con el selector de campos (.) aplicado para
seleccionar componentes sin campos repetidos, lvalor con parntesis y lvalor referenciado con el
subndice del array ([]). Otras expresiones binarias, nombres de funciones, y constantes que no
pueden ser l-valor. El operador ternario (?: tan bien se permite como un l-valor.
La expresin que esta a la izquierda de la asignacin es evaluada antes de la expresin de la
derecha de la asignacin.
Otros operadores de asignacin son:
 La asignacin aritmtica de suma ( += ), resta ( -= ), multiplicacin ( *= ) y divisin ( /= ).
La expresin
lvalor op=expresin
Equivale a la expresin:
lvalor = lvalor op expresin;
y lvalor y la expresin deben satisfacer los requisitos en la semntica tanto para op como para
igualdad.
 La asignacin en conjuntos, desplazamiento a la derecha (>>=), desplazamiento a la
izquierda (<<=), perteneciente(incluido) a ( |= ), y exclusivo ( ^=) son reservados para mas
adelante.
Leer una variable antes de escribirla ( o inicializarla) esta permitido, sin embargo su valor es
indefinido.
5.9. Expresiones
Las expresiones en el lenguaje de shading se crean a partir de las siguiente:

Constantes de tipo bolean, enteras o decimales, todo tipo de vectores y todo tipo de
matrices
 Constructores de todo tipo
 Nombres de variables de todo tipo
 El nombre de un array con el mtodo para obtener su longitud.
 Nombres de subndices de arrays
 Llamadas a funciones que devuelven un valor.
 Campos seleccionados y resultados de acceso a arrays por subndice.
 Expresiones entre parntesis. Algunas expresiones se pueden expresar entre parntesis.
Los parntesis se usan para agrupar operaciones. Las operaciones entre parntesis se
realizan con prioridad frente a las que no los llevan.
 La aritmtica de operadores binarios, suma (+), resta ( - ), multiplicacin (*) y divisin ( / )
operan con enteros y escalares en punto flotante, vectores y matrices. Si uno de los
operadores esta en punto flotante y el otro no, entonces se aplican las conversiones de la
seccin 4.1.10 conversin implcita al operando no decimal. Todas las operaciones
binarias tienen como resultado un nmero en punto flotante o entero. La operacin se
realiza despus de la conversin de tipos. Tras la conversin se pueden dar los siguientes
casos:

33

Los dos elementos sean escalares. En este caso la operacin se realiza,


resultado: escalar.
o Si un operando es escalar y el otro es un vector o una matriz, Se realiza la
operacin escalar independientemente a cada elemento de la matriz o del vector.
resultado: Vector o matriz con el mismo tamao.
o Si los dos son vectores del mismo tamao entonces la operacin se realiza cada
elemento con su homologo en el otro vector (elemento a elemento) Resultado:
Vector del mismo tamao.
o Si la operacin es suma, o resta y trabajamos con dos matrices del mismo tamao
entonces la operacin se realiza elemento a elemento dando como resultado otra
matriz del mismo tamao.
o Con la operacin de multiplicar, siendo ambos operadores matrices o vectores. El
operando de la derecha se considera un vector columna y el de la izquierda como
un vector fila. En todo caso, es necesario que el numero de columnas del
operando de la izquierda sea el mismo que el numero de filas del operando de la
derecha. De esta forma la multiplicacin realiza una multiplicacin algebraica
lineal, obtenindose como resultado un objeto que va a tener el mismo numero de
filas que el elemento de la izquierda y las mismas columnas que el elemento de la
derecha. En la seccin 5.10 Operaciones con vectores y matrices se explica con
mas detalle con se operan estos.
Todos los otros casos son errneos.

La divisin por cero no produce una excepcin pero el resultado da un valor indefinido.
Usar las funciones definidas: dot, cross, matrixCompMult y outerProduct, para
conseguir, respectivamente, producto dot de vectores, producto cross de vectores,
multiplicacin elemento a elemento de matrices, y el producto de matrices de una
columna por una fila.
 La operacin modulo (%) se reserva para mas adelante.
 La operacin unitaria de cambio de signo ( - ), la de incrementar o decrementar
(++ , --) funcionan tanto para enteros como para decimales(incluyendo
vectores y matrices)Todos los operadores unitarios trabajan elemento a
elemento. El resultado mantiene el mismo tipo que el operando. Para
incrementar y decrementar, la expresin tiene que ser un valor que se pueda
asignar a un l-valor. Pre-incrementar y pre-decrementar sumando o restando 1
o 1.0 al contenido de la expresin que ellos operan, y el valor del incremento o
decremento es el valor resultante de la modificacin. Otra opcin es
incrementar o decrementar el valor despus de realizar la operacin, pero el
resultado de la expresin es el valor resultante antes de ejecutar el incremento
o decremento.
 Las operaciones de comparacin, mayor que (>). menor que (<), mayor o igual
que (>=) y menor o igual que (<=) solo operan con escalares enteros o punto
flotante. El resultado es un escalar boolean. Los tipos de los operandos deben
hacer coincidir, o las conversiones de la Seccin 4.1.10" Conversiones
Implcitas " sern aplicadas al operando entero, para que despus los tipos
deben coincidir.
 Para realizar una comparacin elemento a elemento en un vector se puede
usar las funciones predefinidas lessThan, lessThanEqual,greaterThan y
greaterThanEqual.
 El operador de igualdad(==) y el de desigualdad(!=) operan con cualquier tipo
de dato. El resultado se da en un booleano escalar. Si los tipos no coinciden
entonces se debera aplicar una conversin de la seccin 4.1.10, aplicndolo
en un operando que pueda hacer coincidir, en este caso la conversin se
realiza. para vectores, matrices, estructuras y arrays todos los elementos o
campos de un operando deben tener la misma correspondencia con el
elemento o campo del otro operando para ser considerados iguales. Para

34

obtener un vector de igualdad elemento a elemento de dos vectores usar la


funcion equal y notEqual.
 El operador binario and(&&), or (||) y el or exclusivo (^^) solo operan con
expresiones booleanas y tiene como resultado una expresin bolean. And(&&)
solo ser evaluado la parte derecha de la operacin si la parte izquierda tiene
un valor trae. Or (||) solo ser evaluada la parte derecha de la operacin si la
parte izquierda de esta tiene un false. El or exclusivo siempre son evaluadas
ambas partes.
 El operador lgico not(!). Este operador solo funciona en expresiones
booleanas y tiene como resultado otra. para usarlo en vectores hay que utilizar
la funcin predefinida not

La secuencia ( , )opera en expresiones que devuelven el tipo y el valor de
desde la parte mas a la derecha en la lista separada por comas. Todas las
expresiones son evaluadas, en orden, de izquierda a derecha.
 La operacin ternaria (?:) Esta operacin se aplica a tres expresiones (exp1 ?
exp2 : exp3). Evalua la primera expresin, cuyo resultado debera ser un valor
boolean, Si es cierto, pasa a evaluar la segunda expresin, en otro caso
evalua la tercera. Solo una de la segunda y tercera expresin es evaluada. La
segunda y tercera expresin puede ser de cualquier tipo, pudiendo hacer falta
una conversin de la seccion 4.1.10. El tipo del resultado obtenido es el tipo de
toda la expresin.
 El operador and(&), or(|) or exclusivo(^),not, desplazamiento a la derecha (>>) ,
desplazamiento a la izquierda (<<). Estos son reservados para mas adelante.
Para una completa espeficicacion de la sintaxis de expresiones ver la seccion 9
Gramatica del lenguaje Shading
5.10. Operaciones con vectores y matrices
Con unas pocas es excepciones, las operaciones son elemento a elemento. Normalmente, cuando
una operacin se realiza sobe un vector o matriz, se opera independientemente con cada elemento
de la matriz o vector. Por ejemplo:
vec3 v,u;
float f;
v = u +f;
Equivaldra a:
v.x = u.x + f;
v.y = u.y + f;
v.z = u.z + f;

y
vec3 v, u, w;
w = v + u;

Equivaldra a:
w.x = v.x + u.x;
w.y = v.y + u.y;
w.z = v.z + u.z;

de la misma forma para mas operaciones con enteros y decimales. La excepcion es la


multiplicacin de un vector por una matriz, o una matriz por un vector, o producto de matrices. No
se evala elemento a elemento, se realiza una multiplicacin algebraica lineal:

35

vec3 v, u;
mat3 m;
u = v * m;

Equivale:
u.x = dot(v, m[0]); // m[0] columna izquierda de m
u.y = dot(v, m[1]); // dot(a,b) es el producto entre a y b
u.z = dot(v, m[2]);
u = m * v;
Equivale:
u.x = m[0].x * v.x + m[1].x * v.y + m[2].x * v.z;
u.y = m[0].y * v.x + m[1].y * v.y + m[2].y * v.z;
u.z = m[0].z * v.x + m[1].z * v.y + m[2].z * v.z;

y
mat3 m, n, r;
r = m * n;

Equivale:
r[0].x = m[0].x * n[0].x + m[1].x * n[0].y + m[2].x * n[0].z;
r[1].x = m[0].x * n[1].x + m[1].x * n[1].y + m[2].x * n[1].z;
r[2].x = m[0].x * n[2].x + m[1].x * n[2].y + m[2].x * n[2].z;
r[0].y = m[0].y * n[0].x + m[1].y * n[0].y + m[2].y * n[0].z;
r[1].y = m[0].y * n[1].x + m[1].y * n[1].y + m[2].y * n[1].z;
r[2].y = m[0].y * n[2].x + m[1].y * n[2].y + m[2].y * n[2].z;
r[0].z = m[0].z * n[0].x + m[1].z * n[0].y + m[2].z * n[0].z;
r[1].z = m[0].z * n[1].x + m[1].z * n[1].y + m[2].z * n[1].z;
r[2].z = m[0].z * n[2].x + m[1].z * n[2].y + m[2].z * n[2].z;

De forma similar para otros tamaos de matrices y vectores.

6. Sentencias y estructuras
Los bloques usados principalmente en el lenguaje de Shading en OpenGL son:
 Estados y declaraciones
 Definicin de funciones
 Selecciones (if else)
 Bucles (for, while, y do-while)
 saltos (discard,return,break y continue)
En general, las estructuras de un shader son como sigue:
Unidad-translacin:
Declaracin global
Unidad de translacin declaracin global
Declaracin global
Definicin de la funcin
Declaracin
Es decir, un shader es una secuencia de declaraciones y cuerpos de funciones. Los cuerpos de
las funciones se definen as:

36

Definicin de la funcin:
Funcin prototipo {lista de Sentencia }
Lista de Sentencia:
Sentencia
Lista de Sentencia Sentencia
Sentencia
Sentencia compuesto
Sentencia simple
Los lazos son usados en las secuencias de grupo de estados en estados compuestos.
Sentencia compuesto
{lista de Sentencia }
Sentencia simple:
declaracion
Expresin
Seleccin
Bucle
Salto
La declaracin simple, la expresin, y las sentencias de salto acaban en un punto y coma.
Esto es ligeramente simplificado, y la gramtica completa especificada en la Seccin 9 "
Gramtica del lenguaje Shading " debera ser usada como la especificacin definitiva.
Las declaraciones y expresiones ya han sido comentadas.
6.1 Definicin de funciones
Como indica la gramtica, un shader valido es una secuencia de sentencias globales y definicin
de funciones. Una funcin es declarada como muestran los siguientes ejemplos:
// prototipo
DevuelveTipo nombreFuncion (tipo0 arg0, , tipoN argN);
y una funcin se define:
// definicin
tipoDevuelve nombreFuncion ((tipo0 arg0, , tipoN argN);
{
// hace algun computo
return ValorDevuelto;
}
Donde indica TipoDevuelto debe incluirse un tipo de dato. Cada uno de los tipoN deben incluir un
tipo y pueden opcionalmente incluir un parmetro constante o variable.
Una funcin se llama usando el nombre seguido de una lista de parmetros entre parntesis.
Los arrays pueden ser argumentos y tambin un tipo de dato devuelto. En ambos casos, el array
debe tener su tamao especificado. Un array se pasa o se devuelve usando su nombre, sin
corchetes y su tamao debe estar especificado en la definicin de la funcin.
Las estructuras tambin se permiten como argumentos. Tambin se puede devolver una
estructura.

37

Ver la seccin 9.Gramtica del lenguaje Shading para referencias concretas en la sintaxis de
definicin y declaracin de funciones.
Todas las funciones deben ser declaradas con un prototipo o definidas con un cuerpo antes de
que les llamen. Por ejemplo:
float mifunc (float f, // f parametro de entrada
out float g); // g parametro de salidar
Las funciones que no devuelven ningn valor deben ser declaradas como vaco. Las funciones
que no aceptan ninguno argumento de entrada no tienen que usar vaco en la lista de argumento
porque requieren prototipos (o definiciones) y por lo tanto no hay ninguna ambigedad cuando una
lista de argumento vaca " () " es declarada. Proporcionan " (vaco) " como una lista de parmetro
por convenio.
Los nombres de funcin pueden ser sobrecargados. Esto permite que el mismo nombre de una
funcin puede usarse para mltiples funciones, siempre que tengan la lista de argumentos
distintas. Si coinciden el nombre de la funcin y los argumentos, entonces su tipo devuelto tambin
coincidir. Ningunos calificadores son incluidos comprobando si existe coincidencia de tipos, la
funcin correspondiente est basado slo en el parmetro que escriben. Tambin se rehsan
nombres para las funciones predefinidas. Cuando se produce una llamada, se busca una
coincidencia en el parmetro formal de la funcin escrita. Esto incluye que tambin tiene que
coincidir el tamao de un array. Si se encuentra esta coincidencia, la otra definicin se ignora y la
coincidente se usa. En otro caso, si no se encuentra una igual, entonces se aplicarn las
conversiones implcitas de la seccin 4.1.10, para los argumentos de llamada si puede hacer que
coincidan los tipos. En este caso, es un error de semntica si existen mltiples caminos para que al
aplicar la conversin de los argumentos actuales puedan ir por varias definiciones de la funcin.
Por ejemplo, la funcin predefinida para el producto escalar tiene los siguiente prototipos:
float dot (float x, float y);
float dot (vec2 x, vec2 y);
float dot (vec3 x, vec3 y);
float dot (vec4 x, vec4 y);

Las definiciones de los usuarios pueden tener varias declaraciones pero solo una definicin. Un
Shader puede redefinirse con funciones predefinidas. Si una funcin predefinida se vuelve a
declarar en un shader (i.e. un prototipo es visible) antes de llamarlo, entonces el enlace solo se
intentara resolver en el conjunto de los shaders que estn dentro de este.
la funcin main (principal) se usa como el punto de comienzo de un shader ejecutable. Un shader
no necesita contener una funcion llamada main pero uno dentro del conjunto de shaders tiene que
enlazarse con un shader ejecutable. La funcin no coge argumentos, no devuelve un valor, y se
debe declarar con el tipo vacio (void).
void main()
{

}
La funcin main puede contener usos de return. Ver la seccin 6.4. Saltos para ms detalle.
Es un error declarar o definir una funcin main con otro tipo de nombre o tipo.
6.1.1. Convenio de llamadas a funciones
Las funciones se llaman por el valor que devuelven. Esto significa que los argumentos de entrada
se copian dentro de la funcin al llamarla, y los argumentos de salida se copian al que los llamo
antes de salir de la funcin. La funcin trabaja con copias locales de los parmetros, as no hay
solapamiento de los valores de las variables dentro de una funcin. Cuando se llama, los

38

argumentos de entrada son evaluados en orden, de izquierda a derecha. Sin embargo no esta
definido cual es el orden en el que se copian los argumentos de salida.
Para controlar que los parmetros son copiados en y/o hacia fuera por una definicin de funcin o
la declaracin:
 La palabra clave IN se usa para denotar que un parmetro ha sido copiado dentro pero no
fuera.
 La palabra clave OUT se usa para denotar si un parmetro ha sido copiado fuera pero no
dentro. Esto se debera usar siempre para evitar copias innecesarias.
 La palabra clave INOUT se usa para denotar si un parmetro ha sido copiado tanto dentro
como fuera.
 Un parmetro de una funcin declarado sin tal calificador significa lo mismo que si fuese
declarado con in.
En una funcin, se puede escribir en parmetros de entrada. Solo las copias de la funcin son
modificadas. Esto se puede prevenir declarando los parmetros como constantes.
Cuando llamamos a una funcin, las expresiones que no evala un l-valor no pueden ser pasadas
como parmetros declarados como out o inout
No se permite calificar al tipo que devuelve la funcin.
funcion prototipo :
tipo nombreFunc(const-qualifier parameter-qualifier type name array-specifier, ... )
type :
cualquier tipo basico, tipo array, nombre estructura, o definicin de estructura
const-qualifier :
vacio
const
parameter-qualifier :
vacio
in
out
inout
nombre :
vacio
identificador
array-specifier :
vacio
[ entero-constante-expresion]
Sin embargo, el calificador const no se puede usar con out o inout. Es usado para declarar
funciones (excepto prototipos) y definir funciones. De ah que la definicin de funciones puede
tener argumentos sin nombres.
La recursividad no esta permitida, no estticamente. La recursividad esttica est presente si el
grfico de llamada de funcin esttico del programa contiene ciclos.
6.2

Seleccin
La estructura condicional en el lenguaje GSLS se consigue mediante if o if-else:
if ( exp-booleana )
cdigo para exp-booleana verdadera
o
if ( exp-booleana )
cdigo para exp-booleana verdadera

39

else
cdigo para exp-booleana falsa
Si la expresin booleana se evala como verdadera el cdigo correspondiente ser
ejecutado. Por el contrario, si la evaluacin es falsa solo se ejecutar el cdigo
correspondiente a la rama del else si este existese.
Cualquier expresin cuyo resultado despus de evaluada sea un valor booleano puede ser
usado como condicin en esta estructura. No se permite el tipo Vector como expresin
booleana.
Las sentencias condicionales pueden ser anidadas.
6.3

Iteracin
Los bucles For, While y Do se construyen como sigue:
for ( exp-comienzo; exp-condicion; exp-bucle )
cdigo iterativo
while ( exp-condicion )
cdigo iterativo
do
cdigo iterativo
while ( exp-condicion )
Mirar seccin 9 Gramtica GSLS para la especificacin definitiva de los bucles.
Primero, el bucle for evala la exp-comienzo, luego evala exp-condicin. Si la expcondicin resulta verdadera, se ejecuta el cuerpo del bucle. Despus de que este sea
ejecutado, el bucle for evaluara la exp-bucle, y luego volver a comenzar hasta que expcondicin sea falso. Cuando esto sucede, el bucle finaliza pasando por el cuerpo del
mismo sin ejecutarlo. Las variables modificadas en la exp-bucle mantienen su valor una
vez se finaliza la ejecucin del bucle. Por el contrario, las variables modificadas en la expcomienzo o en la exp-condicin solo se mantienen mientras se ejecuta el cuerpo del bucle
for.
El bucle while evala primero la exp-condicin. Si es verdadera, el cuerpo es ejecutado.
Este se repite hasta que la exp-condicin es falsa, saliendo del bucle. Las variables
declaradas en el cuerpo de un bucle while son nicamente vlidas durante la ejecucin del
mismo.
El bucle do-while ejecuta inicialmente el cuerpo del bucle para luego comproba la expcondicin. Esto se repite hasta que la expresin es falsa, momento en el que el bucle
finaliza.
El resultado de evaluar exp-condicin debe ser un booleano.
Exp-condicin y exp-comienzo pueden ser utilizadas para declarar una variable, excepto en
el bucle do-while, que no puede declararlas en su exp-condicin. Estas variables tienen
validez hasta la ltima instruccin del cuerpo del bucle.
Estos tres tipos de bucles pueden ser anidados.

40

Los bucles infinitos estn permitidos y sus consecuencias son dependientes de la


plataforma sobre la que se ejecuten.
6.4

Saltos
Su expresin es:
jump_stat:
continue;
break;
return;
return expresin;
discard;
// solo en el lenguaje fragment shader
No existe el goto ni ningn tipo de control no estructurado como en otros leguajes.
Los saltos continue son nicamente utilizados en bucles. Su funcin es la de evitar el
cuerpo restante del bucle en el que est incluido. Para bucles while y do-while, este salto
lleva al programa a la siguiente evaluacin de las exp-condicin de los bucles. En bucles
for, el salto es a la exp-bucle, seguida de la exp-condicin.
El salto break solo puede ser usado en bucles. Cuando se encuentra un break en un
bucle, este finaliza directamente sin ningn tipo de comprobacin de sus expresiones.
La palabra clave discard esta nicamente permitida en fragment shaders. Puede ser
usado para abandonar la operacin actual en el actual fragmento. Esto provoca el descarte
del fragmento y consecuentemente la no actualizacin de cualquier buffer. Tpicamente,
discard es utilizado con algn tipo de construccin condicional del tipo:
if ( intensity < 0.0)
discard;
Un fragment shader puede testear el valor alpha y descartarse basndose en este test.
Por el contrario, debemos indicar que el test de cobertura se produce despus que el
fragmento sea ejecutado, y este puede cambiar el valor alpha.
El salto return produce la salida inmediata de la funcin actual. Si contiene una expresin,
esta fijar el valor devuelto por la funcin.
La funcin main puede utilizar el return. Esto produce la salida del programa de la misma
forma en que lo hara una funcin que ha alcanzado su final. Esto no implica el uso de
discard en un fragment shader. El uso de return en el main antes de definir las salidas
tendr el mismo comportamiento que alcanzar el final del main sin haberlas definido.

41

7 Variables Internas
7.1

Variables especiales en Vertex Shaders


Algunas operaciones en OpenGL continan manteniendo su operatividad entre el
procesador de vrtices y el de fragmentos. Otras, por el contrario, suceden despus del
procesador de fragmentos. Los shaders se comunican con OpenGL a travs de sus
variables.
La variable gl_Position est disponible nicamente en el Vertex Language y su funcin es
la de describir homogneamente la posicin de los vrtices. Toda ejecucin de un vertex
shader bien formado tiene necesariamente que escribir un valor en esta variable. Puede
ser escrito en cualquier momento durante la ejecucin del mismo. Tambin podra ser
escrito por un vertex shader despus de que este fuese escrito. Este valor ser usado en la
fase primitiva de ensamblado, clipping, culling y otras operaciones funcionales que operan
sobre las primitivas luego de que el procesador del vrtice suceda. El compilador podra
generar un diagnostico de error si detecta que la variable no ha sido escrita, o ha sido
accedida para lectura antes de ser cubierta, pero no todos los casos son detectables. Su
valor ser indefinido si el vertex shader se ejecuta y no cubre su valor.
La variable gl_PointSize est disponible nicamente en el Vertex Language y su funcin
primitiva es la de especificar el tamao de punto para su rasterizacin. Se mide en pixels.
La variable gl_ClipVertex est tambin nicamente disponible en el Vertex Language y nos
provee de un lugar en el que los shaders podrn escribir las coordenadas que luego sern
utilizadas en los planes de recorte del usuario. El usuario debe asegurarse que el recorte
del vrtice y el propio vrtice se encuentren en el mismo espacio de coordenadas. Estos
planes del usuario solo sern operativos mediante transformaciones lineales. No se puede
asegurar lo que ocurrir en caso de ser no lineales.
Las variables de comunicacin anteriores son declaradas intrnsecamente de la forma:
vec4 gl_Position;
float gl_PointSize;
vec4 gl_ClipVertex;

// tiene que ser escrita


// debe ser escrita
// debe ser escrita

Si gl_PointSize o gl_ClipVertex no son escritas, sus valores son indefinidos. Cualquiera de


estas variables podrn ser accedidas por el shader despus de escribir en l, para
recuperar el valor de las mismas. Hacer esto antes de ser escrito tendr un
comportamiento no definido. En caso de escribir las variables mltiples veces, el ltimo
valor ser el que se almacene.
Estas variables tienen una mbito global.
7.2

Variables especiales en Fragment Shaders


La salida de la ejecucin de un fragment shader ser procesada en el final del pipeline de
OpenGL. Las salidas de los fragment shaders sern comunicadas al pipeline mediante las
variables gl_FragColor, gl_FragData y gl_FragDepth, a menos que se ejecute un discard.

42

Estas variables podran ser escritas ms de una vez. Si esto ocurre, el ltimo valor
asignado ser el llevado al pipeline. Los valores dados a las variables podrn ser
accedidos despus de cubiertos. La lectura previa a la asignacin devolver valores
indefinidos. Para asignar un valor a la variable de profundidad gl_FragDepth este valor
debe ser obtenido mediante la lectura de la variable gl_FragCoord.z, descrita ms abajo.
La variable gl_FragColor establece el color que ser utilizado a la hora de establecer el
color al fragmento en el pipeline de OpenGL. Una vez este valor se consume a la hora de
pintar el fragmento, y si otro cdigo de ejecucin del shader no actualiza el valor de esta
variable, este quedar indefinido.
Si el frame buffer est configurado como un index color buffer el comportamiento es
indefinido cuando usamos un fragment shader.
gl_FragDepth establecer el valor de profundidad para el shader que se ejecute en ese
momento. Si el buffer de profundidad esta activado, y el shader no cubre la variable
descrita, el valor actual de la variable(proveniente de otro cdigo no perteneciente al
shader)ser utilizado como valor de profundidad. Si un shader de forma esttica asigna un
valor a gl_FragDepth, y hay un camino de ejecucin a travs del shader que no fija el valor
de la variable, entonces el valor de la profundidad ser indefinido para ejecuciones que
recorran dicho camino.
(Un shader contiene una asignacin esttica a una variable x si, antes del pre-procesado,
el shader contiene una sentencia que escribira a x, que se ejecutar independientemente
de si la sentencia est en el flujo de ejecucin o no)
La variable gl_FragData es un array. Escribiendo gl_FragData[n] se especifica el fragmento
de datos que ser ejecutado en el pipeline para los datos n. Si en esta ejecucin se
consume el valor del fragmento de datos, esta variable pasa a tener un valor indefinido.
Si un shader asigna estticamente un valor a gl_FragColor, no puede asignar un valor a
cada uno de los elementos del array gl_FragData. Igualmente, si asigna un valor a cada
uno de los elementos del array gl_FragData, no puede asignarle ningn valor a
gl_FragColor. Esto es, un shader solo puede asignar un valor a una de estas dos variables,
pero no a ambas. La ejecucin de multiples shaders enlazados tiene que ser controlada
para que esto no suceda. No puede dejar las variables en estado inconsistente.
Si un shader ejecuta la orden discard, el fragmento es descartado, y los valores de las
variables anteriormente explicadas es irrelevante.
La variable gl_FragCoord es de acceso para solo lectura y su misin es fijar los valores
x,y,z y l/w para el fragmento. Si estamos trabajando con un multi-sampling, este valor
puede ser para dentro de cualquier pixel, o uno de las muestras de fragmento. El uso de
las variaciones de centroid no permite restringir estos valores para estar dentro de la
primitiva. Este valor es el resultado de la funcionalidad en OpenGL que interpola las
primitivas despus del procesado de vrtices para generar fragmentos. La componente z
es la profundidad que ser aplicada al shader si no se ha especificado un valor en la
variable gl_FragDepth. Esto es muy til cuando un shader interpreta gl_FragDepth en
algunos casos y en otros lo calcula sin recurrir a la variable.
Los fragment shaders tienen acceso a otra variable de solo lectura, gl_FrontFacing. Su
valor ser verdadero si el fragmento pertenece a una primitiva que est enseando su cara
frontal. Un uso de esto es la emulacin de una iluminacin de dos caras seleccionando uno
o dos colores calculados por el vertex shader.

43

Las variables accesibles desde un fragment shader tienen unos tipos intrnsecos que se
detallan a continuacin:
vec4
bool
vec4
vec4
float

gl_FragCoord;
gl_FrontFacing;
gl_FragColor;
gl_FragData[gl_MaxDrawBuffers];
gl_FragDepth;

Sin embargo, no se comportan como variables de almacenamiento. Su funcinamiento es el


descrito anteriormente. Tienen mbito global.
7.3

Atributos especiales en Vertex Shaders


Los siguientes atributos son parte del OpenGL vertex language y pueden ser usados desde
un cdigo de este tipo para leer y modificar estas variables de OpenGL. Las referencias a
pginas se refieren a la especificacin del lenguaje OpenGL 1.4

//
// Atributos Vertex, p. 19.
//
attribute vec4 gl_Color;
attribute vec4 gl_SecondaryColor;
attribute vec3 gl_Normal;
attribute vec4 gl_Vertex;
attribute vec4 gl_MultiTexCoord0;
attribute vec4 gl_MultiTexCoord1;
attribute vec4 gl_MultiTexCoord2;
attribute vec4 gl_MultiTexCoord3;
attribute vec4 gl_MultiTexCoord4;
attribute vec4 gl_MultiTexCoord5;
attribute vec4 gl_MultiTexCoord6;
attribute vec4 gl_MultiTexCoord7;
attribute float gl_FogCoord;
7.4

Constantes especiales
Las siguientes constantes son vlidas tanto en vertex shaders como fragment shaders
//
// Constantes dependientes de la implementacin. En el ejemplo siguiente,
// los valores son los mnimos permitidos para esos mximos
//
const int gl_MaxLights = 8;
// GL 1.0
onst int gl_MaxClipPlanes = 6;
// GL 1.0
const int gl_MaxTextureUnits = 2;
// GL 1.3
const int gl_MaxTextureCoords = 2;
// ARB_fragment_program
const int gl_MaxVertexAttribs = 16;
// ARB_vertex_shader
const int gl_MaxVertexUniformComponents = 512;
// ARB_vertex_shader
const int gl_MaxVaryingFloats = 32;
// ARB_vertex_shader
const int gl_MaxVertexTextureImageUnits = 0;
// ARB_vertex_shader
const int gl_MaxCombinedTextureImageUnits = 2;
// ARB_vertex_shader
const int gl_MaxTextureImageUnits = 2;
// ARB_fragment_shader

44

const int gl_MaxFragmentUniformComponents = 64;// ARB_fragment_shader


const int gl_MaxDrawBuffers = 1
// ARB_draw_buffers propuestos
7.5

Variables Uniformes de Estado


Como ayuda para acceder al estado de procesado de OpenGL, las siguientes variables
han sido incluidas dentro del lenguaje de shaders. Todas las referencias son a la
especificacin 1.4 del lenguaje.
//
// Estado de la matriz p. 31, 32, 37, 39, 40.
//
uniform mat4 gl_ModelViewMatrix;
uniform mat4 gl_ProjectionMatrix;
uniform mat4 gl_ModelViewProjectionMatrix;
uniform mat4 gl_TextureMatrix[gl_MaxTextureCoords];
//
// Matriz de estado derivada que devuelve inversas y transpuestas
// de las matrices de arriba. Matrices en mal estado pueden resultar en
// impredecibles valores de sus matrices inversas.
//
uniform mat3 gl_NormalMatrix; // transpuesta de la inversa triangular
// superior izquierda de la gl_ModelViewMatrix
uniform mat4 gl_ModelViewMatrixInverse;
uniform mat4 gl_ProjectionMatrixInverse;
uniform mat4 gl_ModelViewProjectionMatrixInverse;
uniform mat4 gl_TextureMatrixInverse[gl_MaxTextureCoords];
uniform mat4 gl_ModelViewMatrixTranspose;
uniform mat4 gl_ProjectionMatrixTranspose;
uniform mat4 gl_ModelViewProjectionMatrixTranspose;
uniform mat4 gl_TextureMatrixTranspose[gl_MaxTextureCoords];
uniform mat4 gl_ModelViewMatrixInverseTranspose;
uniform mat4 gl_ProjectionMatrixInverseTranspose;
uniform mat4 gl_ModelViewProjectionMatrixInverseTranspose;
uniform mat4 gl_TextureMatrixInverseTranspose[gl_MaxTextureCoords];
//
// Escalado normal p. 39.
//
uniform float gl_NormalScale;
//
// Rango de profundidad en las coordenadas de la ventana p. 33
//
struct gl_DepthRangeParameters {
float near;
// n
float far;
// f
float diff;
// f - n
};
uniform gl_DepthRangeParameters gl_DepthRange;
//
// Clip planes p. 42.

45

//
uniform vec4 gl_ClipPlane[gl_MaxClipPlanes];
//
// Tamao de punto p. 66, 67.
//
struct gl_PointParameters {
float size;
float sizeMin;
float sizeMax;
float fadeThresholdSize;
float distanceConstantAttenuation;
float distanceLinearAttenuation;
float distanceQuadraticAttenuation;
};
uniform gl_PointParameters gl_Point;
//
// Estado del material p. 50, 55.
//
struct gl_MaterialParameters {
vec4 emission;
// Ecm
vec4 ambient;
// Acm
vec4 diffuse;
// Dcm
vec4 specular;
// Scm
float shininess;
// Srm
};
uniform gl_MaterialParameters gl_FrontMaterial;
uniform gl_MaterialParameters gl_BackMaterial;
//
// Estado de las luces p 50, 53, 55.
//
struct gl_LightSourceParameters {
vec4 ambient;
// Acli
vec4 diffuse;
// Dcli
vec4 specular;
// Scli
vec4 position;
// Ppli
vec4 halfVector;
// Derived: Hi
vec3 spotDirection;
// Sdli
float spotExponent;
// Srli
float spotCutoff;
// Crli
// (range: [0.0,90.0], 180.0)
float spotCosCutoff;
// Derived: cos(Crli)
// (range: [1.0,0.0],-1.0)
float constantAttenuation;
// K0
float linearAttenuation;
// K1
float quadraticAttenuation;
// K2
};
uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights];
struct gl_LightModelParameters {
vec4 ambient;
// Acs
};
uniform gl_LightModelParameters gl_LightModel;
//

46

// Estados derivados de los productos de luces y material


//
struct gl_LightModelProducts {
vec4 sceneColor;
// Derived. Ecm + Acm * Acs
};
uniform gl_LightModelProducts gl_FrontLightModelProduct;
uniform gl_LightModelProducts gl_BackLightModelProduct;
struct gl_LightProducts {
vec4 ambient;
// Acm * Acli
vec4 diffuse;
// Dcm * Dcli
vec4 specular;
// Scm * Scli
};
uniform gl_LightProducts gl_FrontLightProduct[gl_MaxLights];
uniform gl_LightProducts gl_BackLightProduct[gl_MaxLights];
//
// Entorno de textura y generation, p. 152, p. 40-42.
//
uniform vec4 gl_TextureEnvColor[gl_MaxTextureUnits];
uniform vec4 gl_EyePlaneS[gl_MaxTextureCoords];
uniform vec4 gl_EyePlaneT[gl_MaxTextureCoords];
uniform vec4 gl_EyePlaneR[gl_MaxTextureCoords];
uniform vec4 gl_EyePlaneQ[gl_MaxTextureCoords];
uniform vec4 gl_ObjectPlaneS[gl_MaxTextureCoords];
uniform vec4 gl_ObjectPlaneT[gl_MaxTextureCoords];
uniform vec4 gl_ObjectPlaneR[gl_MaxTextureCoords];
uniform vec4 gl_ObjectPlaneQ[gl_MaxTextureCoords];
//
// Niebla p. 161
//
struct gl_FogParameters {
vec4 color;
float density;
float start;
float end;
float scale;
// Derived: 1.0 / (end - start)
};
uniform gl_FogParameters gl_Fog;
7.6

Variables no Uniformes
Este tipo de variables no tiene un correspondencia uno a uno entre el vertex language y el
fragment language. Se nos presentan en dos conjuntos, uno para cada lenguaje. Sus
relaciones se muestran ms abajo.
Las siguientes variables estn disponibles para ser utilizadas con vertex shader. En
particular, una de ellas deber ser escrita si el fragmento correspondiente al shader o si el
pipeline la usa a ella o a un estado derivado de ella. En otro caso, el comportamiento ser
indefinido.
varying vec4 gl_FrontColor;
varying vec4 gl_BackColor;
varying vec4 gl_FrontSecondaryColor;
varying vec4 gl_BackSecondaryColor;

47

varying vec4 gl_TexCoord[];


// como mximo ser gl_MaxTextureCoords
varying float gl_FogFragCoord;
Para gl_FogFragCoor, el valor escrito ser usado como valor c en la pgina 160 de la
especificacin de OpenGL 1.4. Por ejemplo, si la coordenada z deseada del fragmento en
el espacio de visin es c, entonces este ser el valor que el cdigo del vertex shader
debera almacenar en gl_FogFragCoord.
Como con todos los arrays, los ndices usados para acotar gl_TextCoord tienen que ser
una expresin integral constante, o este array tendr que ser redeclarado por el shader con
un tamao. El tamao podr ser como mximo del valor contenido en la variable
gl_MaxTextureCoords. Usando ndices prximos al 0 se ayuda a preservar recursos.
Las siguientes variables est disponibles para lectura dentro de un fragmento shader.
gl_Color y gl_SecondaryColor son los mismos nombres de atributos pasados al lenguaje
vertex, aunque no se producir conflicto de nombres debido a que estas variables solo son
visibles dentro un fragmento shader.
varying vec4 gl_Color;
varying vec4 gl_SecondaryColor;
varying vec4 gl_TexCoord[];
// como mximo ser gl_MaxTextureCoords
varying float gl_FogFragCoord;
varying vec2 gl_PointCoord;
Los valores de gl_Color y gl_SecondaryColor sern derivados y cubiertos automticamente
por el sistema desde gl_FrontColor, gl_BackColor, gl_FrontSecondaryColor, y
gl_BackSecondaryColor basndose en la cara que sea visible en cada momento. Si la
funcionalidad de pipeline fijo se usa para el procesado de vrtices, entonces
gl_FogFragCoord ser la coordenada z en el espacio de visin, o la interpolacin de la
coordenada de la niebla, como se describe en la seccin 3.10 de la especificacin de
OpenGL 1.4.
Los ndices del array gl_TexCoord son como se describe arriba en el texto referente a los
vertex shaders.
Los valores en gl_PointCoord son coordenadas bidimensionales que indican donde dentro
de una primitiva de punto se localiza el fragmento actual. Su rango va desde 0.0 a 1.0
sobre el punto. Si la primitiva no es de punto, el valor ledo de gl_PointCoord es indefinido.

48

8 Funciones Propias
OpenGL define un conjunto de funciones propias para el trabajo y operaciones con
escalares y vectores. Muchas de estas funciones pueden usarse en ms de un tipo de
shader, pero algunas de ellas son una forma de mapeo directa sobre el hardware y por eso
son tiles para un tipo especfico de sombreado.
Estas funciones se pueden dividir en 3 categoras:

Provienen al usuario de alguna funcionalidad hardware, como por ejemplo el acceso a


un mapeo de textura. No hay manera de emular dicho comportamiento mediante un
shader.
Funciones que representan una operacin trivial, que a pesar muy sencillas de escribir
por el usuario, tienen una representacin directa y podran tener un soporte directo en
hardware. Es un problema muy complicado para el compilador mapear expresiones a
complejas instrucciones de ensamblado.
Funciones que representan una operacin grfica sobre el hardware que es posible
acelerar en algn punto. Las funciones trigonomtricas entran en esta categora.

Muchas de estas funciones tienen un nombre similar a las del lenguaje C, pero soportan
entradas de vectores adems de escalares.
El usuario debe intentar usar las funciones que implementa el lenguaje en lugar de crear
las suyas propias, dado que las propias estn implementadas para un rendimiento ptimo.
A pesar de lo anterior, las funciones pueden ser fcilmente reemplazadas por el cdigo del
usuario de forma muy sencilla. Basta con redefinir la funcin con el mismo nombre y los
mismos parmetros.
En las funciones especificadas a continuacin, cuando la entrada de argumentos (y la
correspondiente salida) puede ser float, vec3 o vec4, genType se usa como argumento.
Para cualquier funcin especfica redefinida, el tipo debe ser igual tanto en los parmetros
como en las salidas. Para mat ocurre lo mismo, puede ser cualquier tipo de matriz bsica.

49

8.1

Funciones de ngulos y trigonomtricas


Los parmetros especificados como ngulo se asumen en sus unidades correspondientes,
los radianes. Si en algn caso se produce una divisin por cero, el resultado ser
indefinido.
A continuacin se detallan las funciones por componentes
Sintaxis
genType radians (genType grados)

Descripcin
Convierte grados a radianes

genType degrees (genType radianes)

Convierte radianes a grados

genType sin (genType angulo)

Funcin seno

genType cos (genType angulo)

Funcin coseno

genType tan (genType angulo)

Funcin tangente

genType asin (genType x)

Arco seno. Devuelve el ngulo cuyo seno es x. El


rango de valores devueltos est entre [-/2, /2]
Si |x| > 1 el resultado es indefinido

genType acos (genType x)

Arco seno. Devuelve el ngulo cuyo coseno es x. El


rango de valores devueltos est entre [0, ]
Si |x| > 1 el resultado es indefinido

genType atan (genType y, genType x)

Arco tangente. Devuelve el ngulo cuya tangente


es y/x. El signo de x e y es usado para determinar
en que cuadrante est el ngulo. El rango de
valores devuelto por la funcin es [-, ]. Si x e y
son ambos 0, el resultado es indefinido.

genType atan (genType y_over_x)

Arco tangente. Devuelve el ngulo cuya tangente


es y sobre x. El rango de valores devuelto por la
funcin es [-/2, /2].

50

8.2

8.3

Funciones exponenciales

Sintaxis

Descripcion

genType pow (genType x, genType y)

Devuelve el valor de x elevado al valor de y


El resultado es indefinido si x < 0
El resultado es indefinido si x = 0 e y <= 0

genType exp (genType x)

Devuelve la exponecial natural de x

genType log (genType x)

Devuelve el logaritmo neperiano de x


El resultado es indefinido si x <= 0

genType exp2 (genType x)

Devuelve 2 elevado al valor de x

genType log2 (genType x)

Devuelve el valor del logaritmo en base 2 de x


El resultado es indefinido si x <= 0

genType sqrt (genType x)

Devuelve x
El resultado es indefinido si x < 0

genType inversesqrt (genType x)

Devuelve 1 / x
El resultado es indefinido si x <= 0

Funciones comunes
Syntax

Description

genType abs (genType x)

Devuelve x si x >= 0, en otro caso devuelve -x

genType sign (genType x)

Devuelve 1.0 si x > 0, 0.0 si x = 0, o -1.0 si x < 0

51

Sintaxis

Descripcin

genType floor (genType x)

Devuelve el valor entero ms prximo por defecto o


igual a x

genType ceil (genType x)

Devuelve el valor entero ms prximo por


exceso o igual a x

genType fract (genType x)

Devuelve x floor(x)

genType mod (genType x, float y)

Mdulo. Devuelve x y * floor (x/y)

genType mod (genType x, genType y)

Mdulo. Devuelve x y * floor (x/y)

genType min (genType x, genType y)


genType min (genType x, float y)

Devuelve y si y < x, en otro caso devuelve x

genType max (genType x, genType y)


genType max (genType x, float y)

Devuelve y si x < y, en otro caso devuelve x

genType

Devuelve min (max (x, minVal), maxVal)

clamp (genType x,
genType minVal,
genType maxVal)
genType clamp (genType x,
float minVal,
float maxVal)

Si minVal > maxVal el resultado es


indefinido

genType mix (genType x,


genType y,
genType a)
genType mix (genType x,
genType y,
float a)

Devuelve la ecuacin lineal de x e y


Por ejemplo, x(1 a) + y a

genType step (genType edge, genType x) Devuelve 0.0 si x < edge, sino devuelve 1.0
genType step (float edge, genType x)
genType

genType

Devuelve 0.0 si x <= edge0 y 1.0 si x >= edge1 y


realiza el polinomio de Hermite entre 0 y 1 cuando
edge0 < x < edge1.
Esto es til en casos cuando se desea una funcin
que ponga un umbral para detectar transiciones con
saltos.
Si edge0 >= edge1 los resultados sern indefinidos

smoothstep (genType
edge0, genType
edge1, genType
x)
smoothstep
(float
edge0, float
edge1,
genType x)

52

8.4

Funciones geomtricas
Estas funciones operan con vectores y como vectores, no como componentes

Sintaxis

Descripcin

float length (genType x)

Devuelve la longitud del vector x

float distance (genType p0, genType p1)

Devuelve la distancia entre p0 y p1


Equivalente a length(p0 p1)

float dot (genType x, genType y)

Devuelve el producto de x e y
x[0] y[0] + x[1] y[1] +

vec3 cross (vec3 x, vec3 y)

Devuelve el producto cruzado de x e y


x[1] y[2] y[1] x[2]
x[2] y[0] y[2] x[0]
x[0] y[1] y[0] x[1]

genType normalize (genType x)

Devuelve un vector unitario en la misma direccin


de x

vec4 ftransform()

Solamente en vertex shaders. Esta funcin


asegurar que el valor del vrtice de entrada ser
transformado de la forma que produzca exactamente
el mismo resultado que la misma funcionalidad en el
lenguaje OpenGL. Su intencin es la de ser utilizada
para calcular gl_Position, i.e,
gl_Position = ftransform()
Esta funcin debe ser usada, por ejemplo, cuando
una aplicacin est renderizando la misma
geometra en pasos separados, y un paso utiliza una
funcionalidad cuyo camino est fijado y otro paso
utiliza shaders programables
Si dot(Nref, I) < 0 devuelve N, en otro caso -N

genType faceforward(genType N,
genType
I,
genType Nref)

53

Sintaxis

Descripcin

genType reflect (genType I, genType N) Devuelve la direccin de reflexin del vector


incidente I sobre la superficie orientada por N
I 2 * dot(N,I) * N
N debe estar ya inicializado para obtener el valor
deseado

genType refract(genType I, genType


N, float eta)

Para el vector de incidencia I y la superficie normal


N, y el radio de ndices de refraccin eta, devuelve
el vector de refraccin. El resultado es calculado
por
k = 1.0 eta * eta * (1.0 dot(N,I) * dot(N,I))
if(k < 0.0)
return genType(0.0)
else
return eta * I (eta * dot(N,I) + sqrt(k)) * N
Los vectores I y N deben estas normalizados para
obtener los resultados deseados

8.5 Funciones de matrices


Sintaxis

Descripcin

mat matrixCompMult (mat x, mat y)

Multiplica la matriz x por la matriz y elemento a


elemento, por ejemplo, result[i][j] es el producto
escalar de x[i][j] por y[i][j].
Nota: para obtener la multiplicacin algebraica lineal,
usar el operador de multiplicacin (*).

mat2 outerProduct(vec2 c, vec2 r)


mat3 outerProduct(vec3 c, vec3 r)
mat4 outerProduct(vec4 c, vec4 r)

Devuelve el primer parmetro c como un vector


columna (matriz con una columna) y el segundo
parmetro r como un vector fila (matriz con una fila)
y realiza una multiplicacin algebraica lineal de c * r,
generando una matriz cuyo nmero de filas es el
numero de componentes en c y cuyo nmero de
columnas es el nmero de componentes en r.

mat2x3 outerProduct(vec3 c, vec2 r)


mat3x2 outerProduct(vec2 c, vec3 r)
mat2x4 outerProduct(vec4 c, vec2 r)
mat4x2 outerProduct(vec2 c, vec4 r)
mat3x4 outerProduct(vec4 c, vec3 r)
mat4x3 outerProduct(vec3 c, vec4 r)
mat2 transpose(mat2 m)
mat3 transpose(mat3 m)
mat4 transpose(mat4 m)

Devuelve una matriz la cual es la matiz transpuesta


de m. La matriz de entrada no se modifica.

mat2x3 transpose(mat3x2 m)
mat3x2 transpose(mat2x3 m)
mat2x4 transpose(mat4x2 m)

54

mat4x2 transpose(mat2x4 m)
mat3x4 transpose(mat4x3 m)
mat4x3 transpose(mat3x4 m)

8.6 Funciones relacionales de vectores


Operadores relacionales y de igualdad (<, <=, >, >=, ==, !=) estn definidos (o reservados) para
producir resultados Booleanos escalares. Para resultados vectoriales, usar las siguientes funciones
implementadas. Debajo, bvec toma valores de tipo bvec2, bvec3, o bvec4, ivec toma valores de
tipo ivec2, ivec3, o ivec4, y vec toma valores de tipo vec2, vec3, o vec4. Para todos estos casos,
los tamaos de los vectores de entrada y salida en una llamada en particular deben coincidir.
Sintaxis

Descripcin

bvec lessThan(vec x, vec y)


bvec lessThan(ivec x, ivec y)

Devuelve para cada elemento la comparacin x<y.

bvec lessThanEqual(vec x, vec y)


bvec lessThanEqual(ivec x, ivec y)

Devuelve para cada elemento la comparacin x<=y.

bvec greaterThan(vec x, vec y)


bvec greaterThan(ivec x, ivec y)

Devuelve para cada elemento la comparacin x>y.

bvec greaterThanEqual(vec x, vec y)


bvec greaterThanEqual(ivec x, ivec y)

Devuelve para cada elemento la comparacin x>=y.

bvec equal(vec x, vec y)


bvec equal(ivec x, ivec y)
bvec equal(bvec x, bvec y)

Devuelve para cada elemento la comparacin x==y.

bvec notEqual(vec x, vec y)


bvec notEqual(ivec x, ivec y)
bvec notEqual(bvec x, bvec y)

Devuelve para cada elemento la comparacin x!=y.

bool any(bvec x)

Devuelve true solo si todos los componentes de x


son true.

bool all(bvec x)

Devuelve true si algn componente de x es true.

bvec not(bvec x)

Devuelve para cada elemento el complemento lgico


de x.

8.7 Funciones Lookup de texturas


Las funciones Lookup de texturas se pueden usar con vertex y fragment shaders. Sin embargo,
el nivel de detalle no esta definido por funcionalidades fijas para vertex shaders, hay pequeas
diferencias en operacin entre vertex y fragment texturas lookup. Las funciones en la tabla inferior
proporcionan acceso a texturas a travs de samplers, como estn definidas en el API de OpenGL.
Las propiedades de la textura tales como tamao, formato de pixel, numero de dimensiones,
mtodo de filtrado, numero de niveles de mip-map, profundidad de comparacin, y otras estn
tambin definidas por la llamadas al Api de OpenGL. Tales propiedades son tomadas en cuenta a
medida que la textura es accedida a travs de las funciones implementadas que se definen abajo.
Si se realiza una llamada de textura que no es una sombra a un sampler que representa una
textura profunda con profundas comparaciones activadas, entonces los resultados son indefinidos.
Si se realiza una llamada de textura de sombra a un sampler que representa una textura profunda
con comparaciones profundas desactivadas, entonces los resultados son indefinidos. Si se realiza

55

una llamada de textura de sombra a un sampler que no representa una textura profunda, entonces
los resultados son indefinidos.
En todas las funciones situadas debajo, el parmetro bias es opcional para los fragment shaders.
El parmetro bias no est aceptado en un vertex shader. Para un fragment shader, si bias esta
presente, se aade al calculado del nivel de detalle previo para mejorar la operacin de acceso a la
textura. Si el parmetro bias no existe, entonces la implementacin automticamente selecciona el
nivel de detalle: Para una textura que no esta mip-mapped, esta se usa directamente. Si esta
mip-mapped y ejecutndose en un fragment shader, la LOD computada por la implementacin es
usada para hacer la consulta de la textura. Si esta mip-mapped y ejecutndose en un vertex
shader, entonces se usa la textura base.
Las funciones con Lod estn permitidas solo en un vertex shader. Para las funciones etiquetadas
con Lod, Lod es usado directamente como nivel de detalle.
Sintaxis

Descripcin

vec4 texture1D (sampler1D sampler,


float coord [, float bias] )
vec4 texture1DProj (sampler1D sampler,
vec2 coord [, float bias] )
vec4 texture1DProj (sampler1D sampler,
vec4 coord [, float bias] )
vec4 texture1DLod (sampler1D sampler,
float coord, float lod)
vec4 texture1DProjLod (sampler1D sampler,
vec2 coord, float lod)
vec4 texture1DProjLod (sampler1D sampler,
vec4 coord, float lod)

Usa la textura coordinada coord para hacer un


lookup de textura en la textura 1D tratada a
sampler. Para la versin descriptiva (Proj), la
textura coordinada coord.s es dividida por la ultima
componente de coord.

vec4 texture2D (sampler2D sampler,


vec2 coord [, float bias] )
vec4 texture2DProj (sampler2D sampler,
vec3 coord [, float bias] )
vec4 texture2DProj (sampler2D sampler,
vec4 coord [, float bias] )
vec4 texture2DLod (sampler2D sampler,
vec2 coord, float lod)
vec4 texture2DProjLod (sampler2D sampler,
vec3 coord, float lod)
vec4 texture2DProjLod (sampler2D sampler,
vec4 coord, float lod)

Usa la textura coordinada coord para hacer un


lookup de textura en la textura 2D tratada a
sampler. Para la versin descriptiva (Proj), la
textura coordinada (coord.s, coord.t) es dividida por
la ultima componente de coord. La tercera
componente de coord es ignorada por la variante
vec4 coord.

vec4 texture3D (sampler3D sampler,


vec3 coord [, float bias] )
vec4 texture3DProj (sampler3D sampler,
vec4 coord [, float bias] )
vec4 texture3DLod (sampler3D sampler,
vec3 coord, float lod)
vec4 texture3DProjLod (sampler3D sampler,
vec4 coord, float lod)

Usa la textura coordinada coord para hacer un


lookup de textura en la textura 3D tratada a
sampler. Para la versin descriptiva (Proj), la
textura coordinada es dividida por coord.q.

vec4 textureCube (samplerCube sampler,


vec3 coord [, float bias] )
vec4 textureCubeLod (samplerCube sampler,

Usa la textura coordinada coord para hacer un


lookup de textura en la textura de mapa de cubo
tratada a sampler. La direccin de coord es usada

56

vec3 coord, float lod)

para seleccionar la cara para hacer un lookup de


textura bidimensional, como se describe en la
seccin 3,8,6 en la versin 1,4 de la especificacin
de OpenGL.

vec4 shadow1D (sampler1DShadow sampler,


vec3 coord [, float bias] )
vec4 shadow2D (sampler2DShadow sampler,
vec3 coord [, float bias] )
vec4 shadow1DProj (sampler1DShadow sampler,
vec4 coord [, float bias] )
vec4 shadow2DProj (sampler2DShadow sampler,
vec4 coord [, float bias] )
vec4 shadow1DLod (sampler1DShadow sampler,
vec3 coord, float lod)
vec4 shadow2DLod (sampler2DShadow sampler,
vec3 coord, float lod)
vec4
shadow1DProjLod(sampler1DShadow
sampler, vec4 coord, float lod)
vec4
shadow2DProjLod(sampler2DShadow
sampler, vec4 coord, float lod)

Usa la textura coordinada coord para hacer un


lookup de comparacin de profundidad en la
textura profunda tratada a sampler, como se
describe en la seccin 3,8,14 de la versin 1,4 de la
especificacin de OpenGL. La tercera componente
de coord (coord.p) es usada como el valor R La
textura tratada a sampler debe ser una textura
profunda, o los resultados son indefinidos. Para la
versin descriptiva (Proj) de cada funcin, la
textura
coordinada
es
dividida
por
coord.q,obteniendo un valor R profundo de
coord.p/coord.q. La segunda componente de coord
es ignorada para las variantes 1D .

8.8 Funciones de Procesado Fragmentado


Las Funciones de Procesado Fragmentado estn solo disponibles en los fragment shaders.
Derivadas pueden ser muy costosas computacionalmente hablando y/o numricamente inestables.
Sin embargo, una implementacin en OpenGL puede aproximar las verdaderas derivadas usando
un rpido, pero no completamente exacto derivado computo.
El comportamiento esperado de una derivada es especificado usando forward/backward
differencing.
Forward differencing:
F xdxF x ~ dFdx xdx

1a

F xdxF x
dFdx x ~ ---------------------------1b
dx
Backward differencing:
F xdxF x ~dFdx x dx

2a

F xF xdx
dFdx x ~ ---------------------------dx

2b

Con single-sample rasterization, dx <= 1.0 en las ecuaciones 1b y 2b. Para multi-sample
rasterization, dx < 2.0 en las ecuaciones 1b y 2b.
dFdy es aproximado de modo similar, con y reemplazando x. sujeto a las siguientes condiciones:
1. El mtodo puede usar aproximaciones lineales. Tales aproximaciones lineales implican las
derivadas de orden mas alto, dFdx(dFdx(x)) y superiores, son indefinidas.

57

2. EL mtodo puede asumir que la funcin evaluada es continua. Sin embargo las derivadas
en el cuerpo de un condicional no uniforme, son indefinidas.
3. EL mtodo puede diferir por fragmento, sujeto a la limitacin que el mtodo puede variar
por las coordenadas de la ventana, no las coordinadas de la pantalla. EL requisito
invariante descrito en la seccin 3,1 de la especificaron de OpenGL 1.4 es mas dbil para
los clculos derivados, porque el mtodo puede ser una funcin de una localizacin
fragment
Otras propiedades que son deseables, pero no requeridas, son:
4. Las funciones deben ser evaluadas en el interior de una primitiva (interpolada, no
extrapolada).
5. Las funciones para dFdx deben ser evaluadas mientras se mantiene y constante. Las
funciones para dFdy deben ser evaluadas mientras se mantiene x constante. Sin embargo,
mezcladas derivadas de orden elevado, como dFdx(dFdy(y)) y dFdy(dFdx(x)) son
indefinidas.
6. Derivadas de argumentos constantes deben ser 0.
En algunas implementaciones, variando grados de derivadas la exactitud puede ser obtenida
consultando los consejos GL (seccin 5.6 de la especificacin OpenGL 1.4), permitiendo al usuario
obtener calidad de imagen en contra de velocidad.
Sintaxis

Descripcin

genType dFdx (genType p)

Devuelve la derivada en x usando diferenciacin


local para el argumento de entrada p.

genType dFdy (genType p)

Devuelve la derivada en y usando diferenciacin


local para el argumento de entrada p.
Estas dos funciones son comnmente usadas para
estimar el filtro de anchura usado para las texturas
anti-alias procedural. Estamos asumiendo que la
expresin esta siendo evaluada en paralelo en un
array SIMD de modo que un punto cualquiera dado
el valor de la funcin es conocido en los puntos
representados por el array SIMD. LA diferenciacin
local entre los elementos del array SIMD pueden por
lo tanto ser usados para derivar dFdx, dFdy, etc.

genType fwidth (genType p)

Devuelve la suma de la derivada absoluta en x e y


usando la diferenciacin local para el argumento de
entrada p, p.e.:
abs (dFdx (p)) + abs (dFdy (p));

8.9 Funciones de Ruido


Las funciones de ruido estn disponibles para ambos fragment y vertex shaders. Son funciones
estocsticas que pueden ser usadas para incrementar la complejidad visual. Los valores
retornados por las siguientes funciones de ruido proporcionan la apariencia de aleatoriedad, pero
no son verdaderamente aleatorias. Las funciones de ruido se definen a continuacin para las
siguientes caractersticas:
 El/los valor/es retornados estn siempre en el rango [-1.0,1.0], y cubren al menos el rango
[-0.6,0.6], con una distribucin similar a la Gaussiana.

58









El/los valor/es retornados tienen un promedio general de 0.0


Son repetibles, en ese caso particular como valores de entrada siempre producirn el
mismo valor retornado.
Son estticamente invariantes bajo la rotacin (p.e. no importa como el dominio es rotado,
tiene el mismo carcter esttico)
Tienen una invarianza esttica bajo la translacin (p.e. no importa como es trasladado el
dominio, tiene el mismo carcter esttico)
Tpicamente dan diferentes resultados bajo translacin
La frecuencia espacial esta concentrada, centrada en algn sitio entre 0.5 y 1.0.
Son C1 continuas en cualquier punto (p.e. la primera derivada es continua)

Sintaxis

Descripcin

float noise1 (genType x)

Devuelve un 1D ruido valor basado en el valor de


entrada x.

vec2 noise2 (genType x)

Devuelve un 2D ruido valor basado en el valor de


entrada x.

vec3 noise3 (genType x)

Devuelve un 3D ruido valor basado en el valor de


entrada x.

vec4 noise4 (genType x)

Devuelve un 4D ruido valor basado en el valor de


entrada x.

9 Gramatica del lenguaje de Shading


La gramtica es alimentada de la salida de anlisis lxico. Las seales devueltas del anlisis lxico
son:
ATTRIBUTE CONST BOOL FLOAT INT
BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN
BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4
MAT2 MAT3 MAT4 IN OUT INOUT UNIFORM VARYING
CENTROID
MAT2X2 MAT2X3 MAT2X4
MAT3X2 MAT3X3 MAT3X4
MAT4X2 MAT4X3 MAT4X4
SAMPLER1D
SAMPLER2D
SAMPLER3D
SAMPLERCUBE SAMPLER1DSHADOW
SAMPLER2DSHADOW
STRUCT VOID WHILE
IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT BOOLCONSTANT
FIELD_SELECTION
LEFT_OP RIGHT_OP
INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP
AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN
MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
SUB_ASSIGN
LEFT_PAREN
RIGHT_PAREN
LEFT_BRACKET
RIGHT_BRACKET
LEFT_BRACE
RIGHT_BRACE DOT

59

COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT
LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION
INVARIANT
Lo que procede describe la gramtica para el lenguaje de shading de OpenGL en trminos de las
susodichas seales.
variable_identifier:
IDENTIFIER
primary_expression:
variable_identifier
INTCONSTANT
FLOATCONSTANT
BOOLCONSTANT
LEFT_PAREN expression RIGHT_PAREN
postfix_expression:
primary_expression
postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET
function_call
postfix_expression DOT FIELD_SELECTION
postfix_expression INC_OP
postfix_expression DEC_OP
integer_expression:
expression
function_call:
function_call_or_method
function_call_or_method:
function_call_generic
postfix_expression DOT function_call_generic
function_call_generic:
function_call_header_with_parameters RIGHT_PAREN
function_call_header_no_parameters RIGHT_PAREN
function_call_header_no_parameters:
function_call_header VOID
function_call_header
function_call_header_with_parameters:
function_call_header assignment_expression
function_call_header_with_parameters COMMA assignment_expression
function_call_header:
function_identifier LEFT_PAREN
// Nota gramtica: Los constructores asemejan funciones, pero analizados medicamento
reconocidos la mayora de ellos como claves. Ahora son reconocidos a travs de type_specifier.
function_identifier:
type_specifier
IDENTIFIER
FIELD_SELECTION

60

unary_expression:
postfix_expression
INC_OP unary_expression
DEC_OP unary_expression
unary_operator unary_expression
// Nota gramtica : Ningn estilo tradicional escribe moldes.
unary_operator:
PLUS
DASH
BANG
TILDE // reservados
// Nota gramtica : No hay operaciones unarias '*' o '&'. Los punteros no estan soportados.
multiplicative_expression:
unary_expression
multiplicative_expression STAR unary_expression
multiplicative_expression SLASH unary_expression
multiplicative_expression PERCENT unary_expression // reserved
additive_expression:
multiplicative_expression
additive_expression PLUS multiplicative_expression
additive_expression DASH multiplicative_expression
shift_expression:
additive_expression
shift_expression LEFT_OP additive_expression // reserved
shift_expression RIGHT_OP additive_expression // reserved
relational_expression:
shift_expression
relational_expression LEFT_ANGLE shift_expression
relational_expression RIGHT_ANGLE shift_expression
relational_expression LE_OP shift_expression
relational_expression GE_OP shift_expression
equality_expression:
relational_expression
equality_expression EQ_OP relational_expression
equality_expression NE_OP relational_expression
and_expression:
equality_expression
and_expression AMPERSAND equality_expression // reserved
exclusive_or_expression:
and_expression
exclusive_or_expression CARET and_expression // reserved
inclusive_or_expression:
exclusive_or_expression
inclusive_or_expression VERTICAL_BAR exclusive_or_expression // reserved

61

logical_and_expression:
inclusive_or_expression
logical_and_expression AND_OP inclusive_or_expression
logical_xor_expression:
logical_and_expression
logical_xor_expression XOR_OP logical_and_expression
logical_or_expression:
logical_xor_expression
logical_or_expression OR_OP logical_xor_expression
conditional_expression:
logical_or_expression
logical_or_expression QUESTION expression COLON assignment_expression
assignment_expression:
conditional_expression
unary_expression assignment_operator assignment_expression
assignment_operator:
EQUAL
MUL_ASSIGN
DIV_ASSIGN
MOD_ASSIGN // reservado
ADD_ASSIGN
SUB_ASSIGN
LEFT_ASSIGN // reservado
RIGHT_ASSIGN // reservado
AND_ASSIGN // reservado
XOR_ASSIGN // reservado
OR_ASSIGN // reservado
expression:
assignment_expression
expression COMMA assignment_expression
constant_expression:
conditional_expression
declaration:
function_prototype SEMICOLON
init_declarator_list SEMICOLON
function_prototype:
function_declarator RIGHT_PAREN
function_declarator:
function_header
function_header_with_parameters
function_header_with_parameters:
function_header parameter_declaration
function_header_with_parameters COMMA parameter_declaration
function_header:

62

fully_specified_type IDENTIFIER LEFT_PAREN


parameter_declarator:
type_specifier IDENTIFIER
type_specifier IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET

parameter_declaration:
type_qualifier parameter_qualifier parameter_declarator
parameter_qualifier parameter_declarator
type_qualifier parameter_qualifier parameter_type_specifier
parameter_qualifier parameter_type_specifier
parameter_qualifier:
/* empty */
IN
OUT
INOUT
parameter_type_specifier:
type_specifier
init_declarator_list:
single_declaration
init_declarator_list COMMA IDENTIFIER
init_declarator_list COMMA IDENTIFIER LEFT_BRACKET RIGHT_BRACKET
init_declarator_list COMMA IDENTIFIER LEFT_BRACKET constant_expression
RIGHT_BRACKET
init_declarator_list COMMA IDENTIFIER LEFT_BRACKET
RIGHT_BRACKET EQUAL initializer
init_declarator_list COMMA IDENTIFIER LEFT_BRACKET constant_expression
RIGHT_BRACKET EQUAL initializer
init_declarator_list COMMA IDENTIFIER EQUAL initializer
single_declaration:
fully_specified_type
fully_specified_type IDENTIFIER
fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET
fully_specified_type IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET
fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET EQUAL initializer
fully_specified_type IDENTIFIER LEFT_BRACKET constant_expression
RIGHT_BRACKET EQUAL initializer
fully_specified_type IDENTIFIER EQUAL initializer
INVARIANT IDENTIFIER // Vertex solo
// Nota gramatica: No 'enum', o 'typedef'.
fully_specified_type:
type_specifier
type_qualifier type_specifier
type_qualifier:
CONST
ATTRIBUTE // Vertex solo
VARYING

63

CENTROID VARYING
INVARIANT VARYING
INVARIANT CENTROID VARYING
UNIFORM
type_specifier:
type_specifier_nonarray
type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET
type_specifier_nonarray:
VOID
FLOAT
INT
BOOL
VEC2
VEC3
VEC4
BVEC2
BVEC3
BVEC4
IVEC2
IVEC3
IVEC4
MAT2
MAT3
MAT4
MAT2X2
MAT2X3
MAT2X4
MAT3X2
MAT3X3
MAT3X4
MAT4X2
MAT4X3
MAT4X4
SAMPLER1D
SAMPLER2D
SAMPLER3D
SAMPLERCUBE
SAMPLER1DSHADOW
SAMPLER2DSHADOW
struct_specifier
TYPE_NAME
struct_specifier:
STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE
STRUCT LEFT_BRACE struct_declaration_list RIGHT_BRACE
struct_declaration_list:
struct_declaration
struct_declaration_list struct_declaration
struct_declaration:
type_specifier struct_declarator_list SEMICOLON
struct_declarator_list:

64

struct_declarator
struct_declarator_list COMMA struct_declarator
struct_declarator:
IDENTIFIER
IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET
initializer:
assignment_expression
declaration_statement:
declaration

sentencia:
sentencia_compuesta
sentencia_simple
// Nota Gramatical: No etiquete sentencias; 'goto' no est soportado.
sentencia_simple:
sentencia_declaracion
sentencia_expresion
sentencia_seleccion
sentencia_iteracion
sentencia_salto
sentencia_compuesta:
LAZO_IZQUIERDO LAZO_DERECHO
LAZO_IZQUIERDO lista_sentencias LAZO_DERECHO
sentencia_no_nuevo_ambito:
sentencia_compuesta_no_nuevo_ambito
sentencia_simple
sentencia_compuesta_no_nuevo_ambito
LAZO_IZQUIERDO LAZO_DERECHO
LAZO_IZQUIERDO lista_sentencias LAZO_DERECHO
lista_sentencias:
sentencia
lista_sentencias sentencia
sentencia_expresion:
PUNTO_Y_COMA
expresion PUNTO_Y_COMA
sentencia_seleccion:
IF
PARENTESIS_IZQUIERDO
sentencia_selecciones_restantes

expresion

sentencia_selecciones_restantes:
sentencia ELSE sentencia
sentencia
// Nota Gramatical: No 'switch'. Switch no estn soportados.

65

PARENTESIS_DERECHO

condicion:
expresion
tipo_completamente_especificado IDENTIFICADOR EQUAL inicializador
sentencia_iteracion:
WHILE
PARENTESIS_IZQUIERDO
condicion
PARENTESIS_DERECHO
sentencia_no_nuevo_ambito
DO sentencia WHILE PARENTESIS_IZQUIERDO expresion PARENTESIS_DERECHO
PUNTO_Y_COMA
FOR PARENTESIS_IZQUIERDO para_sentencia_inicial para_sentencias_restantes
PARENTESIS_DERECHO sentencia_no_nuevo_ambito
para_sentencia_inicial:
expresion_sentencia
declaracion_sentencia
condicionopt:
condicion
/* vacio */
para_sentencias_restantes:
condicionopt PUNTO_Y_COMA
condicionopt PUNTO_Y_COMA expresion
sentencia_salto:
CONTINUE PUNTO_Y_COMA
BREAK PUNTO_Y_COMA
RETURN PUNTO_Y_COMA
RETURN expresion PUNTO_Y_COMA
DISCARD PUNTO_Y_COMA //Solo fragmento de shader.
// Nota Gramatical: No goto; 'goto' no est soportado..
unidad_traduccion:
declaracion_externa
unidad_traduccion declaracion_externa
declaracion_externa:
definicion_funcion
declaracion
definicion_funcion:
funcion_prototipo sentencia_compuesta_no_nuevo_ambito

66

10 Problemas
1.
Es un error tener concordancia ambigua de los parmetros en una funcin como la
siguiente?
void foo(int);
void foo(float);
foo(3);

SOLUCIN: No. Si el tipo exacto est disponible, sin conversin, no hay error de ambigedad.
2.
Es un error tener concordancia ambigua de los parmetros en una funcin como la
siguiente?
void foo(float, int)
void foo(int, float)
foo(2, 3);

SOLUCIN: S. Esto debera plantear un error en la llamada ambigua. Siempre hay dos formas de
combinar a travs de la conversin, y no hay concordancia exacta sin conversin, debera
producirse un error.
3.
Qu debe suceder si los tipos del segundo y tercer operandos del operador ternario (?:)
no coinciden? stos deben ser convertidos a otro tipo, o debe retrasarse la conversin para que
coincida con el modo en que se utiliza la expresin ternaria (ms difcil)?
SOLUCIN: Deben ser convertidos para coincidir con los dems, a fin de que la expresin sea del
tipo determinado por la expresin.
4.
Queremos dFdx, dFdy, y fwidth devuelvan 0 si su argumento es una expresin constante
con la finalidad de utilizarlos en inicializadores constantes. La especificacin actual permite
tericamente que estos derivados no sean cero.
SOLUCIN ALTERNATIVA: Diga que debe devolver 0, en teora que nadie nunca ha
implementado una devolucin que no sea cero, o si lo hiciesen, los shaders debera funcionar bajo
la nueva norma.
SOLUCIN ALTERNATIVA: Deshabilitar estos en las inicializaciones.
SOLUCIN: Digamos que slo tienen que devolver 0 cuando se utiliza en inicializadores.
5.

Hay que aadir los obvios constructores de la matriz de desaparecidos?

SOLUCIN ALTERNATIVA: Para restantes Cm, deje indefinido.


SOLUCIN ALTERNATIVA: Exigir P> = N y Q> = M. Es decir, slo se puede ir a matrices ms
pequeas.
SOLUCIN: Para
matPxQ m;
matNxM Cm = matNxM(m)
para cada ndice en 2D [e] [j] que existe en ambos, m y Cm, coloque Cm [e] [j] en m [e] [j]. Todos
los restantes Cm [e] [j] se ponen los de la matriz de identidad .
5A.
Se debera aadir constructores de matrices que permitan la construccin de filas de
informacin?

67

SOLUCIN: Es aceptable.
6.
Debemos exigir operadores de array para ser explcitamente dimensionados antes de ser
utilizado con un operador == o !=?
SOLUCIN: S.
6A.
Debemos exigir operadores de array para ser explcitamente dimensionados antes de ser
utilizado con un una asignacin?
SOLUCIN: S.
7.
Puede utilizarse un constructor sin tamao? Est claro lo que se entiende por el nmero
de argumentos enumerados. Hay dos caminos a tomar aqu, que tambin puede afectar al
problema 8. Esto es, "float []" significar implcitamente una matriz de tamao, o queremos
reservar eso en el sentido de una referencia para estar disponible en un futuro? Si implcitamente
el tamao del array se ajusta perfectamente en el que "float [] (1, 4)" es un array explcitamente
dimensionado a 2, al igual que "float a[ ] = float[2](1, 4)" ya est. Incluso podramos permitir "float a[
] = float[ ](1, 4);".
SOLUCIN: S, pueden utilizarse constructores sin tamao, como tambin se puede declaraciones
sin tamao que son dimensionadas en la inicializacin. Tenemos que llegar a una sintaxis de las
diferentes referencias en el futuro que es ortogonal con el tipo (corchetes habra sido una sintaxis
referida especfica a un array). Tenga en cuenta que esto no es otra forma de crear implcitamente
tamao arrays, como un array que de inmediato termina con un tamao explcito que no se puede
cambiar.
Dejar clara la nueva diferencia entre la inicializacion y la asignacin para arrays sin dimensionar,
porque ya hemos dicho el inicializador puede inicializar sintcticamente lo que parece una array sin
dimensionar, mientras que la cesin no puede.
8.
Puede un parmetro de la funcin ser un array sin dimensionar? Las funciones pueden
clonado internos, y / o arrays pasado por referencia internamente (que sigue satisfaciendo el noaliasing y pasa por una copia semntica externamente). Esta funcin interna de clonacin surgir
de nuevo, si hablamos de pasar por referencia semntica, y hablamos de la necesidad de
diferentes cuerpos de la funcin para transmitir, por ejemplo, en arrays uniformes frente a arrays
globales, porque el objeto tiene que ser diferente.
SOLUCIN: Es aceptable. Requiere de compilacin en relacin a tiempo comportamiento.
Posiblemente estamos en el camino de un solo cuerpo de la funcin aceptando los arrays de
diferentes tipos y dimensiones, y que los corchetes vacios (arrays sin dimensionar) significa
aceptar mltiples tamaos, frente el significado de aceptar una referencia a un array.
9.
Deberamos tener una matriz de aliasing para matrices cuadradas, por ejemplo, __
Mat2x2 es lo mismo que mat2?
SOLUCIN: S.
10.
Deberamos tener una matriz alias para vectores, por ejemplo, __ Mat1x2 es lo mismo
que vec2? Del mismo modo necesitamos esto, o tenemos una funcin incorporada para multiplicar
un vector fila por un vector columna, y devuelve una matriz.
SOLUCIN: No, no alias de vectores. No es un alias de verdad, porque los vectores son ambiguos
respecto a ser vectores fila o columna. Aadir la funcin incorporada "matN outerProduct (vecN,
vecN)", en su lugar (vase el problema 12).

68

11.
El primer nmero en una matriz no cuadrada es el nmero de filas o el nmero de
columnas? Nmero de filas es ms intuitivo. Nmero de columnas es ms coherente con el orden
existente de la indexacin.
SOLUCIN ALTERNATIVA: El primer nmero es el nmero de filas. Queremos movernos en esta
direccin de todos modos... que lo principal es independiente del diseo abstracto. Nosotros
podemos estar agregando una estructura para pedir el orden fila-mayor, que diga lo que la
indexacin significa, pero podemos mantener el tipo de declaracin de la misma manera, diciendo
que el primer nmero es el nmero de filas.
SOLUCIN: Nunca agregue un modo para pedir operaciones basado en filas, y nunca avanzar
hacia la lengua que est ms basado en filas. El primer nmero significa el nmero de columnas.
11A. Hay que aadir un mtodo de seleccin de una fila fuera de una matriz, por ejemplo,
M.row (i)?
SOLUCIN: Esto es aceptable.
12.
Cul debera ser la verdadera ortografa para el producto de matrices? (Vase el
problema 10.)
SOLUCIN: outerProduct
13.
Cul es el nmero de posiciones del atributo que se necesita para guardar una matriz?
el nmero de filas, el nmero de columnas, o el mximo de stos?
SOLUCIN ALTERNATIVA: El mximo, para permitir implementaciones de la eleccin para el
movimiento de datos ms eficiente.
SOLUCIN: El nmero de columnas; debido a la situacin actual de los arrays vertex, la
cartografa de las columnas a las franjas horarias es vulnerable.
14.
Cmo de cerca queremos definir donde est ubicado el centroide? "Prximo" parece un
poco vaga.
SOLUCIN: Por lo menos tiene que estar en la interseccin de la primitiva y el pixel, o uno de los
fragmentos que se inscribe en la primitiva. Preferiblemente, es el centroide de la interseccin. El
centroide de las muestras situadas en esta interseccin es tambin una buena eleccin. La
ubicacin de las muestras dentro de la interseccin que estn cerca de estos centroides tambin
son buenas opciones.
15.
Podemos poner en una restriccin de recursin esttica, como se hizo en ES? En el
escritorio espec, slo se deshabilit la recursin dinmica, pero creo que es mejor deshabilitar
tambin la recursin esttica. Si nadie tiene el apoyo de recursin esttico hasta el momento,
podramos hacer esto.
SOLUCIN: Deshabilitar recursin esttica, al igual que se hizo en ES.
16.
Es necesario aadir transposicin? Debera ser un mtodo para transponer en el lugar,
o un mtodo que devuelve una transposicin funcional, o una funcin incorporada que devuelve
una transposicin funcional?
SOLUCIN: Aadir funciones incorporadas
mat2 transpose(in mat2)
mat3 transpose(in mat3)
mat4 transpose(in mat4)

69

mat2x3 transpose(in mat3x2)


mat3x2 transpose(in mat2x3)
mat2x4 transpose(in mat4x2)
mat4x2 transpose(in mat2x4)
mat3x4 transpose(in mat4x3)
mat4x3 transpose(in mat3x4)

Y reservar un .transpose() para su posible uso futuro.


17.
Puede la aplicacin consultar el valor inicial se establece un modelo uniforme de enlace
en el tiempo?
SOLUCIN: S, utilizando los actuales puntos de acceso para la consulta uniforme, de modo que
no sera necesario adoptar.
18.

Los centroide variables tienen derivadas?

SOLUCIN ALTERNATIVA: Las derivadas de centroides variables no estn definidas.


SOLUCIN: Digamos que se definen, pero menos precisas. Avise pblicamente para enviar a
cabo una actualizacin de la condicin 5 en la lista.
SOLUCIN ALTERNATIVA: Las derivadas son tan precisas como antes, probablemente
ejecutadas por un centroide no variable separado para su uso en derivadas. Podra ser difcil se
obtener para expresiones complejas en el argumento.
19.

What ES clarifications to we want to bring across?

19A.

Ningun otro main se permite adems de 'void main()' de punto de entrada estndar.

SOLUCIN: S, esto est claro.


19B. Cmo indefinido son los ndices de mala lectura y escritura en arrays? ES dice que podra
causar inestabilidad del sistema. Nos dice que el comportamiento es indefinido.
SOLUCIN: Deja spec. como es, diciendo que no se define.
19C. Una mejor organizacin de las clases de clasificadores:
uniform, varying, attribute, and const se convirtieron en 'clasificadores de almacenamiento'
in, out, inout se convirti en 'clasificadores de parametros'
Highp, mediump, lowp son ' clasificadores de precisin'
invariant es un 'clasificador de invariancia'
Donde, dejaramos fuera a los dos ltimos, que coinciden con las especificaciones para los dos
primeros, y es fcil ponerlos en los dems ms tarde.
SOLUCIN: S.
20.
Debemos exigir shaders que contengan #version 120 para utilizar caractersticas
especficas de 1,20? Esto reduce potencialmente la portabilidad, ya que la pueden utilizar los
cdigos de shaders que en realidad no necesitan caractersticas 120. Por otra parte, se abre la
puerta para los pequeos cambios hacia atrs no compatibles lo cual sera beneficioso, al igual
que no tener "__" delante de palabras clave nuevas.
SOLUCIN: S. Exigir #versin 120 para permitir el problema 20A.
20A.

Si se requiere la versin 120, entonces podremos soltar "__" en las nuevas palabras clave?

SOLUCIN: S. Las nuevas palabras clave para la versin 120 no necesita la "__".

70

20B. #Versin necesitan coincidir en todas las unidades de compilacin en un objeto de


programa? Parecera una opcin obvia, pero sera agradable que si las bibliotecas (o simplemente
el cdigo existente que no necesita ser actualizado) no tiene que ser actualizado slo porque una
unidad de compilacin quisiera una nueva caracterstica.
SOLUCIN: No. Mirando las caractersticas que se van aadiendo, parece que no hay necesidad
real para exigir la misma versin en cada unidad de compilacin. La mayora son de sintaxis,
conversiones, o de otro tipo de shaders locales. Los restantes son:
Arrays de objetos: estos tienen todava un tamao conocido en tiempo de compilacin, de
manera transversal unidad de sharing funciona como antes.
Las palabras clave sin "__": los shaders 120 no puede utilizarlos como nombres, as es que
compartirlas no es posible.
Inicializadores uniformes: trabajan, permitimos a algunos de los mdulos que no tienen el
inicializador.
Centroide: si pedimos que las definiciones (vert vs. frag) para hacer coincidan, luego el
usuario tiene que usar el 120 para ambos, de otro modo, podran utilizar 110 frag y 120 vert.
21.

Es necesario una versin de centroide gl_FragCoord?

SOLUCIN: No, por lo menos que quede claro que el actual gl_FragCoord no es un centroide.
Aadir un nuevo centroide frag-coord tiene sentido, pero hasta el momento parece ser de uso
marginal, de modo que todava no se tiene que hacer esto.
22.
Se puede declarar una funcion de variables ocultas del mismo nombre? El 1,10 espec.
especficamente dice que esto no debe suceder.
SOLUCIN ALTERNATIVA: No. Esto sera un cambio incompatible hacia atrs que puede romper
algunos shaders. Por ejemplo, un cdigo como
float sin = sin(expr);
float r = sin * sin;

Es til, y podra haber sido escrito.


SOLUCIN: S. El uso de la #versin 120 nos permite romper la compatibilidad de una manera
sutil. El cdigo todava puede declarar una variable a nivel local y usarla, a pesar de que el nombre
coincide con un nombre de la funcin. Simplemente no puede entonces proceder a llamar a la
funcin del mismo nombre en el mismo mbito de aplicacin. Sera un error de redeclaracin si
ambas funciones y variables son declaradas en el mismo mbito de aplicacin.
22A. Se puede declarar una variable oculta en una estructura del mismo nombre en el mismo
mbito, o es un error? Es decir, qu ocurrira en el siguiente supuesto?

{
struct S { ... };
S S;
S ... // S is not the type 'S'. The type is hidden by the variable 'S'
}

SOLUCIN: Esto es un error. C++ lo permite, pero no estoy seguro que a nosotros nos haga esto.
Tipos y variables comparten el espacio de nombres en un mbito, y se trata de una redefinicin de
un nombre en ese espacio de nombres. La implementacin de referencia de 3Dlabs lo deshabilit.
23.
Se puede declarar un tipo de estructura de nombre oculto tanto para las variables y para
todas las funciones del mismo nombre? (Redeclarando el mismo nombre de variable en el mismo
mbito de aplicacin es, por supuesto, un error de redeclaracin.) Esta fue la intencin de la
especificacin 1,10.

71

SOLUCIN: S. Esto es coherente con la especificacin actual, evita la confusin entre el


constructor y las nuevas funciones del mismo nombre, y se reserva un espacio de nombres para la
firma de los constructores suplentes en el futuro.
24.
Se puede declarar un nombre para una funcin oculta y un tipo de estructura y el
constructor de ella (con el mismo nombre), tanto en mbitos anidados y en el mismo mbito? Esta
fue la intencin de la especificacin 1,10.
SOLUCIN: Deshabilitar declaraciones de las funciones locales. En el mbito global, se trata de
un error de redefinicin porque tienen el mismo nombre una funcin y la estructura.
SOLUCIN ALTERNATIVA: S. Ocultando el constructor lo tiene que hacer. No tendra sentido
ocultar el constructor y no ocultar el tipo, por lo tanto tienen que ser ocultas.
25.
Se puede declarar una funcin, en un mbito anidado, mostrando la definicin de una
funcin que haba sido escondida en una declaracin de un tipo de estructura en un mbito
intermedio? Esto no fue dirigida por la especificacin 1,10, pero es coherente con sus normas de
alcance anidados.
SOLUCIN: Deshabilitar declaraciones de funciones locales.
SOLUCIN ALTERNATIVA: S. No hay casi ninguna otra interpretacin vlida para hacerlo, y que
sea til hacerlo. Es slo un caso de llegar a hacer lo que quiera en un mbito anidados, combinado
con un nico espacio global para todas las definiciones de funciones.
26.
Se puede declarar una funcin no oculta y la definicin de una funcin que haba sido
escondida en una declaracin de un tipo de estructura en el mismo mbito? Esto sin duda no fue
contemplado en la especificacin 1,10. C++ dice que esto es un error.
SOLUCIN: Deshabilitar las declaraciones de funciones locales.
SOLUCIN ALTERNATIVA: No. Haga declarar una funcin con el mismo nombre que un tipo de
estructura del mismo alcance que el error de redeclaracin. Esta es una cosa oscura que se est
haciendo. Tiene una pequea oportunidad de romper un shader existente, por ejemplo,
void foo(int) { ... }
void main()
{
struct foo { float f; }; // legal
void foo(int); // suggested to be illegal; this scope has a foo()
}

27.
Se puede declarar una funcin oculta a una variable con el mismo nombre? Esto sera
incompatible con la especificacin 1,10.
SOLUCIN: Se trata de un error de redeclaracin slo en alcance global. Para mbito local,
deshabilite la declaracin de funciones locales. No hay variables construidas que pueden ser
redeclararadas como un nombre de una funcin por el usuario, por lo que esto se convierte en un
problema inexistente.
SOLUCIN ALTERNATIVA: No. Es realmente asimtrico tener variables no cultas a funciones,
pero tienen variables ocultas a funciones. Tambin es compatible hacia atrs, aunque
probablemente rara vez se hace en shaders reales.
SOLUCIN ALTERNATIVA: S. Si seguimos permitiendo declaraciones locales, y si queremos
cambiar las cosas para las variables ocultas a funciones, para mantener todo simtrico. Sera un
error de redeclaracin en el mismo mbito de aplicacin.

72

28.
Se puede declarar una variable no oculta a una funcin que haba sido escondida por un
tipo de estructura que la declaracin de la variable oculta? Por ejemplo,
void foo(int) { ... }
void main()
{
struct foo { float f; }; // legal, hides 'void foo(int)'
{
bool foo; // legal, hides 'struct foo'
foo(2); // ?? is 'void foo(int)' visible again?
}
}

SOLUCIN: No.
22 - 28. Resumen de las soluciones propuestas a los problemas 22 al 28:
Deshabilite declaraciones de funciones locales.
Una declaracin de una variable o un tipo de estructura es un error de redeclaracin si ya
existe una funcin, una variable, o un tipo de estructura con el mismo nombre en el mismo mbito.
Una declaracin de una funcin es un error de redeclaracin si ya existe una variable o un
tipo de estructura con el mismo nombre en el mismo mbito.
Las funciones puede ser declaradas ms de una vez en el mismo mbito.
Una declaracin de una variable o un tipo de estructura oculta todas las variables,
funciones, estructura o tipos (y sus constructores) del mismo nombre sobre todos los mbitos
exteriores.
Las funciones ocultas permanecen ocultas.
Resumen de lo que es compatible hacia atrs desde esta lista:
No puede tener declaraciones de funcin locales.
No puede utilizar una funcin y una variable con el mismo nombre en el mismo mbito.
El compilador dar errores para estos casos, de modo que ninguno de estos cambios de
comportamiento ocurrir silenciosamente.
29.
Hay que aadir los puntos de entrada para encapsular la carga de los atributos una
matriz, por lo que el sistema puede realmente ocultar el orden interno en memoria de filas
principales frente a columnas principales?
SOLUCIN: No. Nos gustara, pero se requerira soporte de arrays con atributos vertex, qu hasta
ahora es slo extensible a cuatro componentes, de modo que todava no tienen la capacidad de
representar a toda una matriz. Tenga en cuenta la extensin de API que acompaa a esta
especificacin de lenguaje.
30.
Existe un mecanismo de la API para sugerencias a cerca de la fijacin del centroide?
"Lo ms rpido" que permite el centroide es estar situado en el centro de pxeles (fuera de la
primitiva)?
SOLUCIN: No especfica que un nuevo mecanismo deba ser aadido. Basta con utilizar el
mecanismo de sugerencia de derivadas existente.
31.
Necesidad de aclarar que gl_FragCoord es tambin una de las muestras del multisampling. La misma muestra, tal como se recogi para muestras variables.
SOLUCIN: S.
32.
Las funciones incorporadas y los nombres se comportan como si se encuentran en el
mbito global, o en un mbito ms' exterior 'que el mbito global?

73

POSIBLE SOLUCIN: No. Ponga las incorporadas en el mbito global. Esto significa que no se
puede definir una variable o estructura en el mbito global con el mismo nombre que una funcin
incorporada. Esto significa variables globales de shader contaminar el espacio de nombres de
funciones incorporadas (direccionables en el futuro mediante el uso de prefijo "gl", o un espacio de
nombres para el caso "gl", tienen que decidir si los usuarios pueden ofrecer las firmas de una
novela de un nombre gl). Al igual que en 1,10, redeclarando una funcin incorporada que no
ocultara otras funciones con el mismo nombre. Nosotros no solo permitiramos ofrecer un nuevo
cuerpo de una funcin incorporada, y todava esperan encontrar este tipo de cuerpos para
redeclarar funciones incorporadas.
SOLUCIN: S. Las incorporadas se encuentran en un mbito ms externo. Esto significa que se
puede definir una variable global con el mismo nombre que una incorporada, y que se esconden
todas las incorporadas con ese nombre. Redeclarando una funcin incorporada que ocultara las
incorporadas con ese nombre, que rompe la compatibilidad hacia atrs; todas esas firmas
utilizadas tendrn que tener un cuerpo condicionado a ello. Esto dara a un error de la mayora de
los casos en los que el codificador anula una firma, pero no otras, y todava llama una de las otras,
porque para la mayora de las incorporadas, nuestras reglas de conversin pueden no coincidir con
los argumentos de uno a otro prototipo. Las excepciones son lessThan(argumentos enteros) vs.
lessThan
(argumentos
flotantes),
y
similarmente
greaterThan,
lessThanEqual,
greaterThanEqual, equal, y notEqual.
33.

Qu nuevas palabras clave queremos reservar?

SOLUCIN: Podemos reservar nuevas palabras clave, ya que estn protegidos por la #version.
Estas incluyen lowp, mediump, highp, precision.
34.

Necesitamos soportar invarianza bsica.

SOLUCIN: Duplicar palabras clave de invarianza de OpenGL ES, pero slo permiten su uso en el
usuario varyings, una funcin de salida varyings desde el vertex shader, y las variables especiales
de gl_Position y gl_PointSize.
35.
Debemos permitir la invarianza en funcines de retorno de valores, de manera que una
funcin en otra unidad de compilacin puede ser usado en un clculo de invarianza?
SOLUCIN: Es aceptable. Este es un buen plan. Para la versin 1,2, el compilador slo puede
calcular fuera de la corriente y el control de flujo de datos si se encuentran en su totalidad en una
sola unidad de compilacin.
36.
Shaders de fragmentos varyings necesitan ser declarados como invariantes si estuvieran
en el lado del vrtice? Pueden ser opcionalmente?
SOLUCIN: La calificacin de invariant tiene que coincidir en todos los lados. La interpolacin de
computacin puede dividirse en partes, y ambas partes deben computar de un modo invariante. Es
un error si no coinciden. No informar de esto como un error, significa que alguien pueda hacer
innecesariamente clculos de invarianza silenciosamente en el lado del vrtice o no hacerlos
cuando se desea, silenciosamente.
37.
Qu sucede si diferentes unidades de compilacin tienen diferentes tamaos
implcitamente para el mismo array de tamao implicito?
SOLUCIN: Utilice el mximo, no provocar un error.
38.

Hay que eliminar las estructuras incorporadas para coincidir con ES?

74

SOLUCIN: S. Esto elimina un futuro posible problema de espacio de nombres donde con un
operador real de espacio de nombres (por ejemplo, "::") nombres de estructuras anidadas pueden
ser cuantificados dentro de la estructura del espacio de nombres, pero hoy tienen que ser
cuantificados haca un mismo alcan

75

You might also like