love.graphics.newShader
Доступно начиная с LÖVE 0.9.0
Было переименовано из love.graphics.newPixelEffect.
Эта функция может быть медленной, если вызывается многократно, например, из love.update или love.draw. Если вам нужно часто использовать определённый ресурс, создайте его один раз и сохраните для повторного использования!
Создаёт новый объект Shader для ускоренной обработкой вершин и пикселей на аппаратном уровне. Объект Shader содержит код вершинного или пиксельного шейдера, или оба.
Шейдеры — это небольшие программы, выполняемые на графическом процессоре при отрисовке. Вершинные шейдеры выполняются один раз для каждой вершины (например, у изображения есть 4 вершины — по одной в каждом углу. У Mesh может быть гораздо больше.) Пиксельные шейдеры выполняются один раз для каждого пикселя на экране, который касается отрисовываемого объекта. Код пиксельного шейдера выполняется после обработки всех вершин объекта вершинным шейдером.
Функция
Синопсис
shader = love.graphics.newShader( code )
Аргументы
string code- Код пиксельного или вершинного шейдера, или имя файла, указывающее на файл с кодом.
Возвращает
Shader shader- Объект Shader для использования в операциях отрисовки.
Функция
Синопсис
shader = love.graphics.newShader( pixelcode, vertexcode )
Аргументы
string pixelcode- Код пиксельного шейдера или имя файла, указывающее на файл с кодом.
string vertexcode- Код вершинного шейдера или имя файла, указывающее на файл с кодом.
Возвращает
Shader shader- Объект Shader для использования в операциях отрисовки.
Примечания
Аргументы pixelcode и vertexcode могут быть в любом порядке.
Язык шейдеров
Шейдеры программируются не на Lua, а с помощью специального языка шейдеров — GLSL, с несколькими псевдонимами и разным точкой входа для удобства. Синтаксис GLSL очень похож на C. Ни один из псевдонимов, предоставленных LÖVE, не является обязательным, но использование Texel вместо texture2D рекомендуется, поскольку Texel работает во всех версиях GLSL, в то время как texture2D не работает в GLSL 3.
| GLSL | Язык шейдеров LÖVE |
|---|---|
| sampler2D | Image |
| sampler2DArray | ArrayImage |
| samplerCube | CubeImage |
| sampler3D | VolumeImage |
| texture2D(tex, uv) (в GLSL 1) | Texel(tex, uv) |
| texture(tex, uv) (в GLSL 3) | Texel(tex, uv) |
| float | число (устарело) |
| uniform | extern (устарело) |
Версия GLSL зависит от того, добавлена ли строка #pragma language glsl3 в начало файла шейдера, а также от того, работает ли LÖVE на настольном компьютере или мобильном устройстве:
| Язык шейдеров LÖVE | Версия GLSL для настольных ПК | Версия GLSL для мобильных устройств |
|---|---|---|
| glsl1 (по умолчанию) | GLSL 1.20 | GLSL ES 1.00 |
| glsl3 | GLSL 3.30 | GLSL ES 3.00 |
GLSL 3 не поддерживается на некоторых старых системах. Используйте love.graphics.getSupported, чтобы проверить во время выполнения.
Код вершинного шейдера должен содержать по крайней мере одну функцию с именем position, которая будет генерировать преобразованные координаты вершин отрисовываемых объектов в пространстве экрана.
Код пиксельного шейдера должен содержать по крайней мере одну функцию с именем effect, которая будет генерировать цвет, который будет накладываться на экран для каждого пикселя, с которым соприкасается отрисовываемый объект.
LÖVE по умолчанию предоставляет несколько полезных переменных шейдера. Кроме того, LÖVE предоставляет функцию VideoTexel(uv), которая возвращает значение цвета текущего видео в указанной позиции. Так как видео отрисовывается как данные YUV в нескольких текстурах, а затем преобразуется в шейдере, функция Texel использовать нельзя.
Функция пиксельного шейдера
При отрисовке объекта функция пиксельного шейдера effect вызывается сотни или тысячи раз: один раз для каждого пикселя на экране, который касается объекта. Пиксельный шейдер выполняется после вершинного шейдера, если таковой имеется.
Синопсис
vec4 effect( vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords )
Аргументы
vec4 color- Цвет отрисовки, заданный с помощью love.graphics.setColor или цвет вершины Mesh.
Image tex- Текстура изображения или холста, который отрисовывается.
vec2 texture_coords- Положение внутри текстуры для получения данных пикселя. Координаты текстуры обычно нормализованы в диапазоне от (0, 0) до (1, 1), где верхний левый угол — (0, 0).
vec2 screen_coords- Координаты пикселя на экране. Координаты пикселей не нормализованы (в отличие от координат текстуры). (0.5, 0.5) представляет верхний левый угол экрана (в левом нижнем углу в версиях LÖVE до 0.10.0).
Возвращает
vec4 output_color- Цвет пикселя.
Примечания
На мобильных устройствах переменные в пиксельных шейдерах по умолчанию используют точность mediump (16-битный float) вместо 32-битного float по причинам производительности. Это может привести к неустойчивости чисел или визуальным артефактам для больших чисел. Используйте квалификатор highp при объявлении переменной (например, highp float pos;), чтобы она всегда использовала 32-битную плавающую запятую. Кроме того, точность highp не поддерживается на всех устройствах, особенно на устройствах с GLES2. Используйте love.graphics.getSupported для проверки!
Если пиксельный шейдер не используется, LÖVE использует по умолчанию. Вот его код:
vec4 effect(vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords)
{
vec4 texturecolor = Texel(tex, texture_coords);
return texturecolor * color;
} Или для Видео
vec4 effect(vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords)
{
vec4 texturecolor = VideoTexel(texture_coords);
return texturecolor * color;
} Если несколько холстов одновременно отображаются (передавая несколько параметров Canvas в love.graphics.setCanvas), вы можете использовать функцию пустого эффекта (без аргументов!) вместо vec4 effect, чтобы вывести отдельный цвет на каждый холст. У неё следующий прототип:
void effect()
{
// love_Canvases is a writable array of vec4 colors. Each index corresponds to a Canvas.
// IMPORTANT: If you don't assign a value to all active canvases, bad things will happen.
love_Canvases[0] = color;
love_Canvases[1] = color + vec4(0.5);
// etc.
} Если вы хотите получить аргументы, которые передаются в версию для одного холста (vec4 effect), см. встроенные переменные шейдера. color будет в VaryingColor, texture_coords будет в VaryingTexCoord, а screen_coords — в love_PixelCoord. И если вы хотите получить доступ к текстуре, используемой в процессе отрисовки, вы можете сделать это, определив унифицированную текстуру (подходящего типа) с именем MainTex или отправив её самостоятельно через Shader:send.
Функция вершинного шейдера
Синопсис
vec4 position( mat4 transform_projection, vec4 vertex_position )
Аргументы
mat4 transform_projection- Матрица преобразования, формируемая с помощью love.graphics.translate и аналогичных функций в сочетании с ортогональной матрицей проекции.
vec4 vertex_position- Исходное, непространственное положение текущей вершины.
Возвращает
vec4 output_pos- Конечное преобразованное положение текущей вершины.
Примечания
Если код вершинного шейдера не используется, LÖVE использует по умолчанию. Вот его код:
vec4 position(mat4 transform_projection, vec4 vertex_position)
{
// The order of operations matters when doing matrix multiplication.
return transform_projection * vertex_position;
} Примечания
Код вершинного шейдера выполняется для каждой вершины, отрисовываемой на экране (например, love.graphics.rectangle создаст 4 вершины), и используется для преобразования положения вершин из исходных координат в экранное пространство, а также для передачи информации, такой как цвет вершины и координаты текстуры, в пиксельный шейдер.
Код пиксельного шейдера выполняется для каждого пикселя на экране, который касается отрисовываемого объекта, и используется для создания цвета, который будет накладываться на экран в этом пикселе, часто считывая данные из изображения. Пиксельные шейдеры иногда называют фрагментными шейдерами.
Ключевое слово varying может использоваться для установки значения в вершинном шейдере и его интерполяции между вершинами, а затем передать его в пиксельный шейдер.
Код вершинного и пиксельного шейдеров может быть объединён в один файл или строку, если вы обернёте код, относящийся к вершинам, в #ifdef VERTEX .. #endif, а относящийся к пикселям — в #ifdef PIXEL .. #endif.
Встроенные переменные
LÖVE предоставляет несколько встроенных переменных для пиксельных и вершинных шейдеров. Полный список можно найти здесь: Переменные шейдеров.
Примеры
Создание шейдера с использованием кода вершинного и пиксельного шейдера, который ведёт себя так, как если бы шейдер не был установлен.
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)
-- draw things
love.graphics.setShader()
-- draw more things
end Доступ к преобразованному положению вершины в пиксельном шейдере с помощью ключевого слова varying.
Код вершинного шейдера
varying vec4 vpos;
vec4 position( mat4 transform_projection, vec4 vertex_position )
{
vpos = vertex_position;
return transform_projection * vertex_position;
} Код пиксельного шейдера
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;
} Объединение вышеприведенного примера в одну строку или файл с помощью #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 См. также
© 2006–2020 LÖVE Development Team
Licensed under the GNU Free Documentation License, Version 1.3.
https://love2d.org/wiki/love.graphics.newShader