The OpenGL Shading Language
The OpenGL Shading Language
The OpenGL Shading Language
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
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.
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
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:
-
#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.
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
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
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
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
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
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
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
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
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.
24
Cualificadores de Parmetros
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.
Nmero de seccin reservado para los cualificadores de precisin (reservado para usarlo
posteriormente).
4.6.
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
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
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.
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.
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
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
Operaciones de 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.
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
30
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
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
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
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
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;
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;
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
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
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;
//
// 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
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
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
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:
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
Descripcin
Convierte grados a radianes
Funcin seno
Funcin coseno
Funcin tangente
50
8.2
8.3
Funciones exponenciales
Sintaxis
Descripcion
Devuelve x
El resultado es indefinido si x < 0
Devuelve 1 / x
El resultado es indefinido si x <= 0
Funciones comunes
Syntax
Description
51
Sintaxis
Descripcin
Devuelve x floor(x)
genType
clamp (genType x,
genType minVal,
genType maxVal)
genType clamp (genType x,
float minVal,
float maxVal)
genType step (genType edge, genType x) Devuelve 0.0 si x < edge, sino devuelve 1.0
genType step (float edge, genType x)
genType
genType
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
Devuelve el producto de x e y
x[0] y[0] + x[1] y[1] +
vec4 ftransform()
genType faceforward(genType N,
genType
I,
genType Nref)
53
Sintaxis
Descripcin
Descripcin
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)
Descripcin
bool any(bvec x)
bool all(bvec x)
bvec not(bvec x)
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
56
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
58
Sintaxis
Descripcin
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
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.
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
19A.
Ningun otro main se permite adems de 'void main()' de punto de entrada estndar.
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
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;
{
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
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.
SOLUCIN: Podemos reservar nuevas palabras clave, ya que estn protegidos por la #version.
Estas incluyen lowp, mediump, highp, precision.
34.
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