> For the complete documentation index, see [llms.txt](https://docs.quickclient.cc/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.quickclient.cc/ui/shaders.md).

# Шейдеры

Свои GLSL-шейдеры для HUD и для мира.

Если обычных прямоугольников и градиентов не хватает, можно написать свой шейдер на GLSL: свечение, волны, шум и другие эффекты.

За это отвечает `shaders()`. Ему передаются исходники, Quick кладёт их в пак скриптов, откуда их читает игра, и сам перезагружает ресурсы. Шейдер собирается не сразу, а при первой отрисовке, и работает до перезагрузки скриптов.

```java
private static final String VERTEX = """
        #version 150
        in vec3 Position; in vec4 Color; in vec2 UV0;
        uniform mat4 ModelViewMat; uniform mat4 ProjMat;
        out vec4 vColor; out vec2 vUv;
        void main() {
            gl_Position = ProjMat * ModelViewMat * vec4(Position, 1.0);
            vColor = Color; vUv = UV0;
        }
        """;

private static final String FRAGMENT = """
        #version 150
        in vec4 vColor; in vec2 vUv; out vec4 fragColor;
        void main() {
            float d = distance(vUv, vec2(0.5));
            fragColor = vec4(vColor.rgb, vColor.a * smoothstep(0.5, 0.3, d));
        }
        """;

private final Shader glow = shaders().register("glow", VERTEX, FRAGMENT);

@Override
public void onRender2D(Render2D render) {
    if (glow.ready()) render.shader(glow, 8f, 8f, 160f, 40f, 0xFF41C4C8);
}
```

Как это работает:

* Вершинный шейдер передаёт дальше цвет и координату внутри прямоугольника.
* Фрагментный шейдер рисует пятно: чем дальше от центра, тем прозрачнее.
* Шейдер регистрируется прямо в поле, а рисуется только после того, как `ready()` вернул `true`.

## Shaders

| Метод                                          | Тип        | Описание                                                                                           |
| ---------------------------------------------- | ---------- | -------------------------------------------------------------------------------------------------- |
| `register(name, vertexSource, fragmentSource)` | `Shader`   | кладёт исходники в пак и возвращает хэндл; если исходники не поменялись, файлы не перезаписываются |
| `handle(name)`                                 | `Shader`   | хэндл шейдера, чьи файлы уже лежат в паке                                                          |
| `names()`                                      | `String[]` | список зарегистрированных шейдеров                                                                 |

В имени можно использовать буквы, цифры и подчёркивание. У `Shader` есть `name()`, `ready()` и `error()`. Пока `ready()` возвращает `false`, рисовать рано, а `error()` покажет причину, если что-то пошло не так.

## Что приходит в вершинный шейдер

| Атрибут     | Содержимое                                                                |
| ----------- | ------------------------------------------------------------------------- |
| `Position`  | позиция                                                                   |
| `Color`     | цвет вершины                                                              |
| `UV0`       | у `shader(...)` координата внутри прямоугольника от 0 до 1, у меша его UV |
| `UV1`       | `ivec2`: размер прямоугольника в пикселях, умноженный на 8                |
| `UV2`       | `ivec2`: два параметра из `shader(..., first, second)`                    |
| `LineWidth` | `float`: время в секундах, если туда не передано своё значение            |

Юниформы стандартные: `ModelViewMat` и `ProjMat`. Текстура, если она есть, находится в `Sampler0`.

## Где можно использовать

| Где                                                     | Вызов                                                                                                                                  |
| ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| прямоугольник на HUD                                    | `render.shader(shader, x, y, w, h, color[, first, second])`                                                                            |
| прямоугольник, у которого все атрибуты задаются вручную | `render.drawQuad(shader, [texture, [sampler,]] x, y, w, h, u, v, uWidth, vHeight, uv1x, uv1y, uv2x, uv2y, lineWidth, color…[, blend])` |
| меш на HUD                                              | `render.drawMesh(mesh, shader, x, y, scale, tint)` и варианты с текстурой                                                              |
| меш или билборд в мире                                  | `mesh(mesh, shader, texture, …)`, `billboard(mesh, shader, texture, …)` из [3D-рендера](/ui/render-3d.md)                              |

`drawQuad` рисует один прямоугольник: четыре цвета по углам и режим смешивания `Render2D.NORMAL`, `ADDITIVE` или `OVERWRITE`.

Если шейдер не скомпилировался, скрипт продолжит работать. `ready()` останется `false`, а текст ошибки будет в `error()` и в консоли.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.quickclient.cc/ui/shaders.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
