Shaders

Introducción

Los shaders son programas únicos que se ejecutan en la GPU. Se usan para especificar cómo tomar datos de la malla (posiciones de vértices, colores, normales, etc.) y dibujarlos en la pantalla. Los shaders no procesan la información de la misma manera que un programa normal porque están optimizados para ejecutarse en la GPU. Una consecuencia de esto es que los shaders no retienen sus datos después de ejecutarse; emiten un color final a la pantalla y luego siguen adelante. Por consiguiente, no hay forma de acceder a la salida de color de la última ejecución del shader.

Godot utiliza un lenguaje de shader muy similar al GLSL, pero con mayor funcionalidad y ligeramente menos flexibilidad. La razón para hacer esto es que Godot integra la funcionalidad incorporada para hacer la escritura de shaders complejos sustancialmente más fácil. Godot envuelve el código de sombreador escrito por el usuario en un código propio. De esta manera, Godot maneja muchas de las cosas de bajo nivel de las que el usuario no tiene que preocuparse, y es capaz de analizar su código de shader y utilizarlo para afectar la tubería de renderizado. Para shaders más avanzados, puedes desactivar esta funcionalidad usando un render_mode.

Este documento le proporciona alguna información sobre shaders, específica de Godot. Para una referencia detallada del lenguaje de shader en Godot ver la Godot shading language doc.

Tipos de Shaders

En lugar de ofrecer una configuración de propósito general (2D, 3D, partículas), los shaders de Godot deben especificar para qué serán usadas. Diferentes tipos soportan distintos modos de renderizado, variables integradas y funciones de procesamiento.

Todos los shaders deben especificar el tipo en la primera línea, en el siguiente formato:

shader_type spatial;

Los tipos válidos son:

Para obtener información detallada sobre cada tipo de shader, véase el documento de referencia correspondiente.

Modos de renderizado

Los distintos tipos de shaders soportan diferentes modos de renderizado. Son opcionales pero, si se especifican, debe hacerse después del shader_type. Estos modos son usados para alterar la forma en que la funcionalidad integrada es manejada. Por ejemplo, es común usar el modo unshaded para saltearse la función de procesamiento de iluminación (light).

Los modos de representación se especifican debajo del tipo shader:

shader_type spatial;
render_mode unshaded, cull_disabled;

Cada tipo de shader tiene una lista diferente de modos de representación disponibles. Consulta el documento de cada tipo shader para obtener una lista completa de los modos de renderización.

Funciones de procesamiento

Dependiendo del tipo de shader, distintas funciones de procesamiento estarán disponibles para sobreescribir. Para "spatial" y "canvas_item", es posible utilizar vertex, fragment y light. Para "particles" sólo está disponible vertex.

Procesador Vertex

La función de procesamiento vertex es llamada por cada vértice en shaders "spatial" y "canvas_item". Para "particles", es llamada por cada partícula.

La función vertex se utiliza para modificar la información por vértice que se pasará a la función de fragmentos. También se puede utilizar para establecer las variables que se enviarán a la función de fragmento mediante el uso de variaciones (véase otro documento).

Por defecto, Godot tomará la información de su vértice y la transformará para ser dibujada. Si esto no es deseable, puedes usar los modos de representación para transformar los datos tú mismo; ver el Spatial shader doc para un ejemplo de esto.

Procesador Fragment

El procesador fragment es usado para asignar parámetros de materiales por pixel. Este código es ejecutado por cada pixel visible que es dibujado en el objeto o primitiva. Sólo está disponible en shaders "spatial" y "canvas_item".

El uso estándar de la función fragment es establecer las propiedades materiales que se utilizarán para calcular la iluminación. Por ejemplo, se establecerían los valores de ROUGHNESS, RIM, o TRANSMISSION que le dirían a la función de la luz cómo las luces responden a ese fragmento. Esto hace posible controlar un complejo conducto shader sin que el usuario tenga que escribir mucho código. Si no necesitas esta funcionalidad incorporada, puedes ignorarla y escribir tu propia función de procesamiento de luz y Godot la optimizará. Por ejemplo, si no escribes un valor en RIM, Godot no calculará la iluminación del borde. Durante la compilación, Godot comprueba si RIM se utiliza, si no, corta todo el código correspondiente. Por lo tanto, no desperdiciará los cálculos en efectos que no utiliza.

Procesador Light

El procesador "light" se ejecuta también por pixel, pero además es ejecutado por cada luz que afecta el objeto (y no es ejecutada si no hay luces afectando el objeto). Existe como una función llamada dentro de fragment y típicamente opera sobre las propiedades de los materiales configuradas dentro de la función fragment.

El procesador light funciona de manera diferente en 2D que en 3D; para una descripción de cómo funciona en cada uno, ver su documentación, CanvasItem shaders y Shaders espaciales, respectivamente.