love.graphics.newShader (Français)

Disponible depuis LÖVE 0.9.0
It has been renamed from love.graphics.newPixelEffect.


O.png Cette fonction peut être lente si elle est appelée de façon répétée, comme depuis love.update ou love.draw. Si vous devez utiliser souvent une ressource spécifique, créez la une seule fois, et conservez la quelque part, elle peut être réutilisée !  



Crée un nouvel objet Shader (ombreur) pour des effets de vecteurs et de pixel accélérés par le matériel. Un Shader contient soit du code d'ombrage de vecteur (vertex shader), soit du code d'ombrage de pixel (pixel shader), soit les deux.

Les Shaders sont des courts programmes qui peuvent fonctionner sur les processeurs graphiques lors de leur tracés. Les ombrages de vecteurs sont exécutées une unique fois pour chaque vecteur (par exemple, une image comporte 4 vecteurs — un à chaque angle. Un mesh (maillage) peut en avoir d'avantage.) Les ombrages de pixels sont exécutés une fois pour chaque pixel à l'écran que l'objet tracé touche. Le code d'ombrage de pixel est exécuté après que tous les vecteurs de l'objet aient étés traités par l'ombrage de vecteur.

Attention, en GLSL, les matrices, contrairement à leur utilisation en mathématiques, sont représentées avec une colonne par ligne, et la multiplication se fait avec une matrice homogène à gauche du vecteur à tranformer, suivant cet ordre:

(x', y', z', w') = [matrice homogène (échelle+rotation+déformation+translation] × (x, y, z, w)

Fonction

Synopsis

shader = love.graphics.newShader( code )

Arguments

string (Français) code
Code d'ombrage de pixel ou d'ombrage de vecteur, ou bien un nom de fichier pointant sur un fichier contenant le code.

Retourne

Shader (Français) shader
Un objet Shader à utiliser dans les opérations de tracé.

Fonction

Synopsis

shader = love.graphics.newShader( pixelcode, vertexcode )

Arguments

string (Français) pixelcode
Code d'ombrage de pixel, ou bien un nom de fichier pointant sur un fichier contenant le code.
string (Français) vertexcode
Code d'ombrage de vecteur, ou bien un nom de fichier pointant sur un fichier contenant le code.

Retourne

Shader (Français) shader
Un objet Shader à utiliser dans les opérations de tracé.

Notes

Les arguments pixelcode et vertexcode peuvent être placé dans n'importe quel ordre.

Langage d'ombrage

Les Shaders ne sont pas programmés en Lua, mais en utilisant un langage spécial pour l'ombrage – GLSL, avec quelques aliases et un point d'entrée différent pour la convéniance – à la place. GLSL utilise une syntaxe très similaire à celle du langage C. Aucun des alias que LÖVE ne fournit ne sont indispensables, mais l'utilisation de Texel plutôt que texture2D est recommandé puisque Texel fonctionne dans toutes les versions de GLSL, tandisque texture2D ne fonctionne pas avec GLSL 3.

GLSL Langage d'ombrage de LÖVE
sampler2D Image
sampler2DArray ArrayImage
samplerCube CubeImage
sampler3D VolumeImage
texture2D(tex, UV) (in GLSL 1) Texel(tex, UV)
texture(tex, UV) (in GLSL 3) Texel(tex, UV)
float number (déprécié)
uniform extern (déprécié)


La version de GLSL utilisée dépend de la présence de la ligne #pragma language glsl3 en début du fichier d'ombrage, ainsi que si LÖVE fonctionne sur un ordinateur de bureau ou un périphérique mobile :

Langage d'ombrage de LÖVE GLSL en version bureau GLSL en version mobile
glsl1 (défaut) GLSL 1.20 GLSL ES 1.00
glsl3 GLSL 3.30 GLSL ES 3.00

GLSL 3 n'est pas supporté sur certains anciens systèmes. Utilisez love.graphics.getSupported pour vérifier pendant l'exécution.

Le code d'ombrage de vecteur doit contenir au moins une fonction, appelée position, qui est la fonction qui produira les positions de vecteurs transformés des objets tracés dans l'espace écran.

Le code d'ombrage de pixel doit contenir au moins une fonction, appelée effect (effet), qui est la fonction qui produira la couleur qui sera mélangée à l'écran pour chaque pixel touchant un objet tracé.

LÖVE fournit différents variables d'ombrage utiles par défaut. De plus, LÖVE expose une fonction VideoTexel(uv) qui yields la valeur de couleur de la vidéo actuellement tracée à cette position. Comme les vidéos sont tracées comme des données YUV dans des textures multiples, puis converties dans l'ombrage, la fonction Texel ne peut pas être utilisée.

Fonction d'ombrage de pixel

Lorsqu'un objet est tracé, la fonction effect (effet) de l'ombrage de pixelest appelé des centaines ou milliers de fois : Une fois pour chaque pixel à l'écran que l'objet touche. l'ombrage de pixel est exécuté après l'ombrage de vecteur, si il y en existe un.

Synopsis

vec4 effect( vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords )

Arguments

vec4 (Français) color
Couleur de tracé définiée à l'aide de love.graphics.setColor ou bien couleur par vecteur du Mesh (maillage).
Image (Français) tex
Texture de l'image ou du canvas qui sera tracé.
vec2 (Français) texture_coords
Position à l'intérieur de la texture à laquelle les pixels doivent être pris. Les coordonnées de Texture sont habituellement normalisés dans l'étendue (0, 0) à (1, 1), avec l'angle haut-gauche étant à (0, 0).
vec2 (Français) screen_coords
Coordonnées du pixel à l'écran. Les coordonnées de pixel ne sont pâs normalisés (contrairement aux coordonnées de texture). (0.5, 0.5) représente le coin haut et gauche de l'écran (en bas à gauche dans les versions de LÖVE antérieures à 0.10.0).

Retourne

vec4 (Français) output_color
Couleur du pixel.

Notes

O.png Sur les périphériques mobiles, les variables des ombrages de pixel utilisent mediump (nombre flottant de précision 16 bits) par défaut au lieu de flottants 32 bits, pour des raisons de performances. Cela pourrait causer des instabilités numériques ou des défauts visuels pour des valeurs importantes. Utiliser le qualifieur highp lorsque vous déclarez une variable (par exemple highp float pos;) pour lui faire toujours utiliser des nombres flottants de précision 32 bits. Il faut également savoir que la précision highp, n'est pas supportée sur tous les périphériques, en particulier les périphériques GLES2. Utilisez love.graphics.getSupported pour vérifier !  


Si aucun ombrage de pixel n'est utilisé, LÖVE en utilise un en interne un défaut. Voici son code:

vec4 effect(vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords)
{
    vec4 texturecolor = Texel(tex, texture_coords);
    return texturecolor * color;
}

Ou pour Video

vec4 effect(vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords)
{
    vec4 texturecolor = VideoTexel(texture_coords);
    return texturecolor * color;
}

Si plusieurs canvases y sont rendus simultanément (en donnant plusieurs paramètres de Canvas à love.graphics.setCanvas), vous pouvez utiliser la fonction void effect (effet vide) (pas d'arguments !) à la place et vec4 effect (effet vec4) dans l'ordre afin de sortir une couleur différente pour chaque Canvas. Elle à le prototype suiant :

void effect()
{
    // Les Canvas de LÖVE sont des tableaux pouvant être écrits, de couleurs sous la forme de vec4. Chaque indexe correspond à un Canvas.
    // IMPORTANT : SI voud n'assignez pas une valeur à tous les canvas actifs, des mauvais résultats pourrait survenir.
    love_Canvases[0] = color;
    love_Canvases[1] = color + vec4(0.5);
    // etc.
}

Si vous désirez obtenir les arguments qui sont passés à une version simple-canvas (vec4 effect), voir les variables d'ombrage incluses. color (couleur) sera en VaryingColor (couleur variante), texture_coords (coordonnées de texture) sera en VaryingTexCoord (coordonnées de texture variante) et screen_coords (coordonnées à l'écran est en love_PixelCoord (coordonnées de pixel LÖVE). Et si vous souhaitez accéder à la texture utilisée par les opérations de tracé, vous pouvez le faire en définissant une texture uniforme (du type approprié) nommé MainTex (texture principale) ou en l'envoyant par vous-même via Shader:send.

Fonction d'ombrage de vecteur

Synopsis

vec4 position( mat4 transform_projection, vec4 vertex_position )

Arguments

mat4 (Français) transform_projection
Matrice de transformation affectée par love.graphics.translate et amies combiné avec la matrice de projection orthographique.
vec4 (Français) vertex_position
Position brute non-transformée su vecteur actuel.

Retourne

vec4 (Français) output_pos
Position finale transformée du vecteur actuel.

Notes

Si aucun code d'ombrage de vecteur n'est utilisé, LÖVE en utilise un par défaut. Voici son code :

vec4 position(mat4 transform_projection, vec4 vertex_position)
{
    //  L'ordre des opérations compte lorsque l'on fait des multiplications de matrices.
    return transform_projection * vertex_position;
}

Notes

Le code d'ombrage de vecteur est exécuté pour chaque vecteur tracé à l'écran (par exemple, love.graphics.rectangle produira 4 vecteurs) et est utilisé pour transformer les position de vecteur des coordonnées originales vers l'espace de l'écran, ainsi que pour envoyer des informations telles que les couleurs par vecteur et les valeurs de coordonnées de texture à l'ombrage de pixel.

Le code de l'ombrage de pixel est exécuté pour chaque pixel à l'écran qu'un objet tracé touche, et est utilisé pour produire la couleur qui sera mixé à l'écran pour ce pixel, souvent en lisant depuis une image. Les ombrages de pixel sont parfois appelés ombrages de fragment (fragment shaders).

Le mot-clé varying peut être utilisé pour régler une valeur dans l'ombrage de vecteur et pour qu'il soit interpolé entre les vecteurs puis fourni à l'ombrage de pixel.

Le code des ombrages de vecteur et de pixel peuvent être combinés en un seul fichier ou chaîne de caractère si vous entourés le code spécifique aux vecteurs par #ifdef VERTEX .. #endif et le code spécifique aux pixels dans #ifdef PIXEL .. #endif.

Variables incluses

LÖVE fournit plusieurs variables incluses pour à la fois les ombrages de pixel et de vecteur. La liste complète est située ici : Shader Variables.

Exemples

Crée un ombrage utilisant du code d'ombrage de vecteur et de pixel se comportant comme si aucun ombrage n'était définit.

local pixelcode = [[
    vec4 effect( vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords )
    {
        vec4 texcolor = Texel(tex, texture_coords);
        return texcolor * color;
    }
]]

local vertexcode = [[
    vec4 position( mat4 transform_projection, vec4 vertex_position )
    {
        return transform_projection * vertex_position;
    }
]]

shader = love.graphics.newShader(pixelcode, vertexcode)

function love.draw()
    love.graphics.setShader(shader)
    -- Trace des choses
    love.graphics.setShader()
    -- Trace d'avantage de choses
end

Accéder à la position de vecteur pré-transformée dans l'ombrage de pixel avec le mot-clé varying.

Code d'ombrage de vecteur

varying vec4 vpos;

vec4 position( mat4 transform_projection, vec4 vertex_position )
{
    vpos = vertex_position;
    return transform_projection * vertex_position;
}

Code d'ombrage de pixel

varying vec4 vpos;

vec4 effect( vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords )
{
    texture_coords += vec2(cos(vpos.x), sin(vpos.y));
    vec4 texcolor = Texel(tex, texture_coords);
    return texcolor * color;
}

Combiner l'exemple du dessus en une seule chaîne de caractères ou un fichier à l'aide de #ifdef.

varying vec4 vpos;

#ifdef VERTEX
vec4 position( mat4 transform_projection, vec4 vertex_position )
{
    vpos = vertex_position;
    return transform_projection * vertex_position;
}
#endif

#ifdef PIXEL
vec4 effect( vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords )
{
    texture_coords += vec2(cos(vpos.x), sin(vpos.y));
    vec4 texcolor = Texel(tex, texture_coords);
    return texcolor * color;
}
#endif

Voir également



Autres langues