Гайд Чуть чуть шейдеров(разбор SDF) :)

Новичок
Статус
Оффлайн
Регистрация
22 Сен 2020
Сообщения
58
Реакции[?]
3
Поинты[?]
2K
Всем привет!

Не буду углубляться в то, как писать шейдеры и как они работают в целом, так как на ютубе уже есть много видео на эту тему. Вместо этого я объясню, как работает Signed Distance Field (SDF), возможно, кто-то сразу поймет, но мне на это потребовалось время, поэтому я распишу это подробнее, покажу примеры и прикреплю полный код.

SDF (Signed Distance Field) — это функция, которая возвращает расстояние до границы объекта с учетом знака. Это означает, что функция указывает, находится ли точка внутри объекта, снаружи или на границе. Если "-", точка внутри объекта; если "+" — снаружи; если ноль — на границе. Field (поле) означает, что это множество значений, например, магнитное поле, которое зависит от источника магнитного поля.

Для начала я бы хотел разобрать SDF circle, достаточно простой пример

Circle SDF:
float circleSDF(vec2 uv, vec2 pos, float radius) {
    return length(uv - pos) - radius;
}
Как видите, я использую length, возможно кто-то в первый раз видит это, это тоже самое что и sqrt(vec2.x^2 + vec2.y^2), то-есть эта функция расчитывает длину вектора, если представлять на координатной системе, если y - 4 а x - 3, то длина до координата от равна 5
Далее я отнимаю радиус от координат и получается так что рисуется круг, см. ниже.
Ну выходит так что если отнять от центра радиус, то мы получим SDF и сможем заполнить как бы всё поле

Возможно что вы не понимаете как всё таки нарисовать этот круг, вот как сделал это я:

void mainImage:
/* По логике тут должен быть метод для расчёта дистанции */
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord.xy / iResolution.xy * 2.0 - 1.0;

    // Нормализация координата x, т.к если не умножать на разницу будет овал
    uv.x *= iResolution.x / iResolution.y;

    vec2 center = vec2(0.0, 0.0);
    float radius = 0.5;

    float dist = circleSDF(uv, center, radius);

    // Антиалисинг
    float smoothDist = smoothstep(-0.003, 0.003, dist);

    vec3 color = vec3(1.0, 0.0, 0.0);

    fragColor = vec4(color * (1.0 - smoothDist), 1.0 - smoothDist);
}

Как видим, всё работает, SS см. ниже

Теперь, если же добавить abs(модуль числа) в получение дистанции, то мы получим SDF снаружи круга(т.к число всегда будет +) и сможем сделать так называемый обруч, вот как это должно выглядеть, см. ниже.
float dist = abs(circleSDF(uv, center, radius)) - .01;
Число которе мы отнимаем от полученной дистанции(в моём случае .01)можно назвать толщиной во все стороны, потому что центр смещается, теперь это центр обводки, а отнимаем мы так же как от центра круга, думаю это всё понятно, вот как будет выглядеть 'обруч', SS см. ниже.

По моему я достаточно сильно разжевал этот пример, если что-то не понятно, пишите.

Второй пример, rounded box SDF(закруглённый прямоугольник), код см. ниже.
roundedBoxSDF:
float roundedBoxSDF(vec2 CenterPosition, vec2 Size, float Radius) {
    return length(max(abs(CenterPosition)-Size+Radius,0.0))-Radius;
}
Взято с
Пожалуйста, авторизуйтесь для просмотра ссылки.
noad

Да да, я сам не писал, но объясню как оно работает, для начала мы получаем модуль вектора CenterPosition, то-есть 1/4 часть, потому что только 1/4 часть имеет положительные координаты, нужно это для того что-бы упростить вычисления, далее отнимаем Size и получаем дистанцию от текущей точки до границы и прибавляем Radius для нормализации, т.к потом будем отнимать, если не делать это, то размер будет зависеть от радиуса, далее получаем максимальное значение, то-есть если abs(CenterPosition)-Size+Radius меньше 0, то мы получим 0.0, далее получаем length, здесь аналогия с кругом, мы получаем уже как бы дистанцию и отнимаем радиус, теперь рисуем, на этом всё, вот как это сделано у меня, код см. ниже.
Rounded box ShaderToy:
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = fragCoord.xy / iResolution.xy * 2.0 - 1.0;

    // Нормализация координаты x, т.к если не умножать на разницу будут ломанные углы
    uv.x *= iResolution.x / iResolution.y;

    vec2 center = vec2(0.0, 0.0);
 
    float radius = 0.25;
    vec2 size = vec2(0.5, 0.5);

    float dist = roundedBoxSDF(uv, size, radius);

    // Антиалисинг
    float smoothDist = smoothstep(-0.003, 0.003, dist);

    vec3 color = vec3(1.0, 0.0, 0.0);
    fragColor = vec4(color * (1.0 - smoothDist), 1.0);
}
Тут всё легко, аналогия с прошлым SDF, так же можно добавить abs(модуль числа) и сделать его не заполненным, а обведённым.

Не страшно если вы чего-то не поняли, я не особо умею объяснять, но попытался, это моя первая тема, так что не судите строго.
Сегодня у меня нет уже времени, так что публикую так.
 
Последнее редактирование:
Начинающий
Статус
Оффлайн
Регистрация
28 Мар 2024
Сообщения
248
Реакции[?]
0
Поинты[?]
0
Всем привет!

Не буду углубляться в то, как писать шейдеры и как они работают в целом, так как на ютубе уже есть много видео на эту тему. Вместо этого я объясню, как работает Signed Distance Field (SDF), возможно, кто-то сразу поймет, но мне на это потребовалось время, поэтому я распишу это подробнее, покажу примеры и прикреплю полный код.

SDF (Signed Distance Field) — это функция, которая возвращает расстояние до границы объекта с учетом знака. Это означает, что функция указывает, находится ли точка внутри объекта, снаружи или на границе. Если "-", точка внутри объекта; если "+" — снаружи; если ноль — на границе. Field (поле) означает, что это множество значений, например, магнитное поле, которое зависит от источника магнитного поля.

Для начала я бы хотел разобрать SDF circle, достаточно простой пример

Circle SDF:
float circleSDF(vec2 uv, vec2 pos, float radius) {
    return length(uv - pos) - radius;
}
Как видите, я использую length, возможно кто-то в первый раз видит это, это тоже самое что и sqrt(vec2.x^2 + vec2.y^2), то-есть эта функция расчитывает длину вектора, если представлять на координатной системе, если y - 4 а x - 3, то длина до координата от равна 5
Далее я отнимаю радиус от координат и получается так что рисуется круг, см. ниже.
Ну выходит так что если отнять от центра радиус, то мы получим SDF и сможем заполнить как бы всё поле

Возможно что вы не понимаете как всё таки нарисовать этот круг, вот как сделал это я:

void mainImage:
/* По логике тут должен быть метод для расчёта дистанции */
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord.xy / iResolution.xy * 2.0 - 1.0;

    // Нормализация координата x, т.к если не умножать на разницу будет овал
    uv.x *= iResolution.x / iResolution.y;

    vec2 center = vec2(0.0, 0.0);
    float radius = 0.5;

    float dist = circleSDF(uv, center, radius);

    // Антиалисинг
    float smoothDist = smoothstep(-0.003, 0.003, dist);

    vec3 color = vec3(1.0, 0.0, 0.0);

    fragColor = vec4(color * (1.0 - smoothDist), 1.0 - smoothDist);
}

Как видим, всё работает, SS см. ниже

Теперь, если же добавить abs(модуль числа) в получение дистанции, то мы получим SDF снаружи круга(т.к число всегда будет +) и сможем сделать так называемый обруч, вот как это должно выглядеть, см. ниже.
float dist = abs(circleSDF(uv, center, radius)) - .01;
Число которе мы отнимаем от полученной дистанции(в моём случае .01)можно назвать толщиной во все стороны, потому что центр смещается, теперь это центр обводки, а отнимаем мы так же как от центра круга, думаю это всё понятно, вот как будет выглядеть 'обруч', SS см. ниже.

По моему я достаточно сильно разжевал этот пример, если что-то не понятно, пишите.

Второй пример, rounded box SDF(закруглённый прямоугольник), код см. ниже.
roundedBoxSDF:
float roundedBoxSDF(vec2 CenterPosition, vec2 Size, float Radius) {
    return length(max(abs(CenterPosition)-Size+Radius,0.0))-Radius;
}
Взято с
Пожалуйста, авторизуйтесь для просмотра ссылки.
noad

Да да, я сам не писал, но объясню как оно работает, для начала мы получаем модуль вектора CenterPosition, то-есть 1/4 часть, потому что только 1/4 часть имеет положительные координаты, нужно это для того что-бы упростить вычисления, далее отнимаем Size и получаем дистанцию от текущей точки до границы и прибавляем Radius для нормализации, т.к потом будем отнимать, если не делать это, то размер будет зависеть от радиуса, далее получаем максимальное значение, то-есть если abs(CenterPosition)-Size+Radius меньше 0, то мы получим 0.0, далее получаем length, здесь аналогия с кругом, мы получаем уже как бы дистанцию и отнимаем радиус, теперь рисуем, на этом всё, вот как это сделано у меня, код см. ниже.
Rounded box ShaderToy:
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = fragCoord.xy / iResolution.xy * 2.0 - 1.0;

    // Нормализация координаты x, т.к если не умножать на разницу будут ломанные углы
    uv.x *= iResolution.x / iResolution.y;

    vec2 center = vec2(0.0, 0.0);

    float radius = 0.25;
    vec2 size = vec2(0.5, 0.5);

    float dist = roundedBoxSDF(uv, size, radius);

    // Антиалисинг
    float smoothDist = smoothstep(-0.003, 0.003, dist);

    vec3 color = vec3(1.0, 0.0, 0.0);
    fragColor = vec4(color * (1.0 - smoothDist), 1.0);
}
Тут всё легко, аналогия с прошлым SDF, так же можно добавить abs(модуль числа) и сделать его не заполненным, а обведённым.

Не страшно если вы чего-то не поняли, я не особо умею объяснять, но попытался, это моя первая тема, так что не судите строго.
Сегодня у меня нет уже времени, так что публикую так.
xot i baza,no molodes +rep :seemsgood:
 
Пользователь
Статус
Оффлайн
Регистрация
22 Авг 2022
Сообщения
298
Реакции[?]
44
Поинты[?]
34K
Всем привет!

Не буду углубляться в то, как писать шейдеры и как они работают в целом, так как на ютубе уже есть много видео на эту тему. Вместо этого я объясню, как работает Signed Distance Field (SDF), возможно, кто-то сразу поймет, но мне на это потребовалось время, поэтому я распишу это подробнее, покажу примеры и прикреплю полный код.

SDF (Signed Distance Field) — это функция, которая возвращает расстояние до границы объекта с учетом знака. Это означает, что функция указывает, находится ли точка внутри объекта, снаружи или на границе. Если "-", точка внутри объекта; если "+" — снаружи; если ноль — на границе. Field (поле) означает, что это множество значений, например, магнитное поле, которое зависит от источника магнитного поля.

Для начала я бы хотел разобрать SDF circle, достаточно простой пример

Circle SDF:
float circleSDF(vec2 uv, vec2 pos, float radius) {
    return length(uv - pos) - radius;
}
Как видите, я использую length, возможно кто-то в первый раз видит это, это тоже самое что и sqrt(vec2.x^2 + vec2.y^2), то-есть эта функция расчитывает длину вектора, если представлять на координатной системе, если y - 4 а x - 3, то длина до координата от равна 5
Далее я отнимаю радиус от координат и получается так что рисуется круг, см. ниже.
Ну выходит так что если отнять от центра радиус, то мы получим SDF и сможем заполнить как бы всё поле

Возможно что вы не понимаете как всё таки нарисовать этот круг, вот как сделал это я:

void mainImage:
/* По логике тут должен быть метод для расчёта дистанции */
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord.xy / iResolution.xy * 2.0 - 1.0;

    // Нормализация координата x, т.к если не умножать на разницу будет овал
    uv.x *= iResolution.x / iResolution.y;

    vec2 center = vec2(0.0, 0.0);
    float radius = 0.5;

    float dist = circleSDF(uv, center, radius);

    // Антиалисинг
    float smoothDist = smoothstep(-0.003, 0.003, dist);

    vec3 color = vec3(1.0, 0.0, 0.0);

    fragColor = vec4(color * (1.0 - smoothDist), 1.0 - smoothDist);
}

Как видим, всё работает, SS см. ниже

Теперь, если же добавить abs(модуль числа) в получение дистанции, то мы получим SDF снаружи круга(т.к число всегда будет +) и сможем сделать так называемый обруч, вот как это должно выглядеть, см. ниже.
float dist = abs(circleSDF(uv, center, radius)) - .01;
Число которе мы отнимаем от полученной дистанции(в моём случае .01)можно назвать толщиной во все стороны, потому что центр смещается, теперь это центр обводки, а отнимаем мы так же как от центра круга, думаю это всё понятно, вот как будет выглядеть 'обруч', SS см. ниже.

По моему я достаточно сильно разжевал этот пример, если что-то не понятно, пишите.

Второй пример, rounded box SDF(закруглённый прямоугольник), код см. ниже.
roundedBoxSDF:
float roundedBoxSDF(vec2 CenterPosition, vec2 Size, float Radius) {
    return length(max(abs(CenterPosition)-Size+Radius,0.0))-Radius;
}
Взято с
Пожалуйста, авторизуйтесь для просмотра ссылки.
noad

Да да, я сам не писал, но объясню как оно работает, для начала мы получаем модуль вектора CenterPosition, то-есть 1/4 часть, потому что только 1/4 часть имеет положительные координаты, нужно это для того что-бы упростить вычисления, далее отнимаем Size и получаем дистанцию от текущей точки до границы и прибавляем Radius для нормализации, т.к потом будем отнимать, если не делать это, то размер будет зависеть от радиуса, далее получаем максимальное значение, то-есть если abs(CenterPosition)-Size+Radius меньше 0, то мы получим 0.0, далее получаем length, здесь аналогия с кругом, мы получаем уже как бы дистанцию и отнимаем радиус, теперь рисуем, на этом всё, вот как это сделано у меня, код см. ниже.
Rounded box ShaderToy:
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = fragCoord.xy / iResolution.xy * 2.0 - 1.0;

    // Нормализация координаты x, т.к если не умножать на разницу будут ломанные углы
    uv.x *= iResolution.x / iResolution.y;

    vec2 center = vec2(0.0, 0.0);

    float radius = 0.25;
    vec2 size = vec2(0.5, 0.5);

    float dist = roundedBoxSDF(uv, size, radius);

    // Антиалисинг
    float smoothDist = smoothstep(-0.003, 0.003, dist);

    vec3 color = vec3(1.0, 0.0, 0.0);
    fragColor = vec4(color * (1.0 - smoothDist), 1.0);
}
Тут всё легко, аналогия с прошлым SDF, так же можно добавить abs(модуль числа) и сделать его не заполненным, а обведённым.

Не страшно если вы чего-то не поняли, я не особо умею объяснять, но попытался, это моя первая тема, так что не судите строго.
Сегодня у меня нет уже времени, так что публикую так.
неплохо
 
Начинающий
Статус
Оффлайн
Регистрация
20 Апр 2021
Сообщения
795
Реакции[?]
12
Поинты[?]
17K
Всем привет!

Не буду углубляться в то, как писать шейдеры и как они работают в целом, так как на ютубе уже есть много видео на эту тему. Вместо этого я объясню, как работает Signed Distance Field (SDF), возможно, кто-то сразу поймет, но мне на это потребовалось время, поэтому я распишу это подробнее, покажу примеры и прикреплю полный код.

SDF (Signed Distance Field) — это функция, которая возвращает расстояние до границы объекта с учетом знака. Это означает, что функция указывает, находится ли точка внутри объекта, снаружи или на границе. Если "-", точка внутри объекта; если "+" — снаружи; если ноль — на границе. Field (поле) означает, что это множество значений, например, магнитное поле, которое зависит от источника магнитного поля.

Для начала я бы хотел разобрать SDF circle, достаточно простой пример

Circle SDF:
float circleSDF(vec2 uv, vec2 pos, float radius) {
    return length(uv - pos) - radius;
}
Как видите, я использую length, возможно кто-то в первый раз видит это, это тоже самое что и sqrt(vec2.x^2 + vec2.y^2), то-есть эта функция расчитывает длину вектора, если представлять на координатной системе, если y - 4 а x - 3, то длина до координата от равна 5
Далее я отнимаю радиус от координат и получается так что рисуется круг, см. ниже.
Ну выходит так что если отнять от центра радиус, то мы получим SDF и сможем заполнить как бы всё поле

Возможно что вы не понимаете как всё таки нарисовать этот круг, вот как сделал это я:

void mainImage:
/* По логике тут должен быть метод для расчёта дистанции */
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord.xy / iResolution.xy * 2.0 - 1.0;

    // Нормализация координата x, т.к если не умножать на разницу будет овал
    uv.x *= iResolution.x / iResolution.y;

    vec2 center = vec2(0.0, 0.0);
    float radius = 0.5;

    float dist = circleSDF(uv, center, radius);

    // Антиалисинг
    float smoothDist = smoothstep(-0.003, 0.003, dist);

    vec3 color = vec3(1.0, 0.0, 0.0);

    fragColor = vec4(color * (1.0 - smoothDist), 1.0 - smoothDist);
}

Как видим, всё работает, SS см. ниже

Теперь, если же добавить abs(модуль числа) в получение дистанции, то мы получим SDF снаружи круга(т.к число всегда будет +) и сможем сделать так называемый обруч, вот как это должно выглядеть, см. ниже.
float dist = abs(circleSDF(uv, center, radius)) - .01;
Число которе мы отнимаем от полученной дистанции(в моём случае .01)можно назвать толщиной во все стороны, потому что центр смещается, теперь это центр обводки, а отнимаем мы так же как от центра круга, думаю это всё понятно, вот как будет выглядеть 'обруч', SS см. ниже.

По моему я достаточно сильно разжевал этот пример, если что-то не понятно, пишите.

Второй пример, rounded box SDF(закруглённый прямоугольник), код см. ниже.
roundedBoxSDF:
float roundedBoxSDF(vec2 CenterPosition, vec2 Size, float Radius) {
    return length(max(abs(CenterPosition)-Size+Radius,0.0))-Radius;
}
Взято с
Пожалуйста, авторизуйтесь для просмотра ссылки.
noad

Да да, я сам не писал, но объясню как оно работает, для начала мы получаем модуль вектора CenterPosition, то-есть 1/4 часть, потому что только 1/4 часть имеет положительные координаты, нужно это для того что-бы упростить вычисления, далее отнимаем Size и получаем дистанцию от текущей точки до границы и прибавляем Radius для нормализации, т.к потом будем отнимать, если не делать это, то размер будет зависеть от радиуса, далее получаем максимальное значение, то-есть если abs(CenterPosition)-Size+Radius меньше 0, то мы получим 0.0, далее получаем length, здесь аналогия с кругом, мы получаем уже как бы дистанцию и отнимаем радиус, теперь рисуем, на этом всё, вот как это сделано у меня, код см. ниже.
Rounded box ShaderToy:
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = fragCoord.xy / iResolution.xy * 2.0 - 1.0;

    // Нормализация координаты x, т.к если не умножать на разницу будут ломанные углы
    uv.x *= iResolution.x / iResolution.y;

    vec2 center = vec2(0.0, 0.0);

    float radius = 0.25;
    vec2 size = vec2(0.5, 0.5);

    float dist = roundedBoxSDF(uv, size, radius);

    // Антиалисинг
    float smoothDist = smoothstep(-0.003, 0.003, dist);

    vec3 color = vec3(1.0, 0.0, 0.0);
    fragColor = vec4(color * (1.0 - smoothDist), 1.0);
}
Тут всё легко, аналогия с прошлым SDF, так же можно добавить abs(модуль числа) и сделать его не заполненным, а обведённым.

Не страшно если вы чего-то не поняли, я не особо умею объяснять, но попытался, это моя первая тема, так что не судите строго.
Сегодня у меня нет уже времени, так что публикую так.
рисунки хорошие)
 
Начинающий
Статус
Оффлайн
Регистрация
8 Май 2023
Сообщения
407
Реакции[?]
5
Поинты[?]
6K
Всем привет!

Не буду углубляться в то, как писать шейдеры и как они работают в целом, так как на ютубе уже есть много видео на эту тему. Вместо этого я объясню, как работает Signed Distance Field (SDF), возможно, кто-то сразу поймет, но мне на это потребовалось время, поэтому я распишу это подробнее, покажу примеры и прикреплю полный код.

SDF (Signed Distance Field) — это функция, которая возвращает расстояние до границы объекта с учетом знака. Это означает, что функция указывает, находится ли точка внутри объекта, снаружи или на границе. Если "-", точка внутри объекта; если "+" — снаружи; если ноль — на границе. Field (поле) означает, что это множество значений, например, магнитное поле, которое зависит от источника магнитного поля.

Для начала я бы хотел разобрать SDF circle, достаточно простой пример

Circle SDF:
float circleSDF(vec2 uv, vec2 pos, float radius) {
    return length(uv - pos) - radius;
}
Как видите, я использую length, возможно кто-то в первый раз видит это, это тоже самое что и sqrt(vec2.x^2 + vec2.y^2), то-есть эта функция расчитывает длину вектора, если представлять на координатной системе, если y - 4 а x - 3, то длина до координата от равна 5
Далее я отнимаю радиус от координат и получается так что рисуется круг, см. ниже.
Ну выходит так что если отнять от центра радиус, то мы получим SDF и сможем заполнить как бы всё поле

Возможно что вы не понимаете как всё таки нарисовать этот круг, вот как сделал это я:

void mainImage:
/* По логике тут должен быть метод для расчёта дистанции */
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord.xy / iResolution.xy * 2.0 - 1.0;

    // Нормализация координата x, т.к если не умножать на разницу будет овал
    uv.x *= iResolution.x / iResolution.y;

    vec2 center = vec2(0.0, 0.0);
    float radius = 0.5;

    float dist = circleSDF(uv, center, radius);

    // Антиалисинг
    float smoothDist = smoothstep(-0.003, 0.003, dist);

    vec3 color = vec3(1.0, 0.0, 0.0);

    fragColor = vec4(color * (1.0 - smoothDist), 1.0 - smoothDist);
}

Как видим, всё работает, SS см. ниже

Теперь, если же добавить abs(модуль числа) в получение дистанции, то мы получим SDF снаружи круга(т.к число всегда будет +) и сможем сделать так называемый обруч, вот как это должно выглядеть, см. ниже.
float dist = abs(circleSDF(uv, center, radius)) - .01;
Число которе мы отнимаем от полученной дистанции(в моём случае .01)можно назвать толщиной во все стороны, потому что центр смещается, теперь это центр обводки, а отнимаем мы так же как от центра круга, думаю это всё понятно, вот как будет выглядеть 'обруч', SS см. ниже.

По моему я достаточно сильно разжевал этот пример, если что-то не понятно, пишите.

Второй пример, rounded box SDF(закруглённый прямоугольник), код см. ниже.
roundedBoxSDF:
float roundedBoxSDF(vec2 CenterPosition, vec2 Size, float Radius) {
    return length(max(abs(CenterPosition)-Size+Radius,0.0))-Radius;
}
Взято с
Пожалуйста, авторизуйтесь для просмотра ссылки.
noad

Да да, я сам не писал, но объясню как оно работает, для начала мы получаем модуль вектора CenterPosition, то-есть 1/4 часть, потому что только 1/4 часть имеет положительные координаты, нужно это для того что-бы упростить вычисления, далее отнимаем Size и получаем дистанцию от текущей точки до границы и прибавляем Radius для нормализации, т.к потом будем отнимать, если не делать это, то размер будет зависеть от радиуса, далее получаем максимальное значение, то-есть если abs(CenterPosition)-Size+Radius меньше 0, то мы получим 0.0, далее получаем length, здесь аналогия с кругом, мы получаем уже как бы дистанцию и отнимаем радиус, теперь рисуем, на этом всё, вот как это сделано у меня, код см. ниже.
Rounded box ShaderToy:
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = fragCoord.xy / iResolution.xy * 2.0 - 1.0;

    // Нормализация координаты x, т.к если не умножать на разницу будут ломанные углы
    uv.x *= iResolution.x / iResolution.y;

    vec2 center = vec2(0.0, 0.0);
 
    float radius = 0.25;
    vec2 size = vec2(0.5, 0.5);

    float dist = roundedBoxSDF(uv, size, radius);

    // Антиалисинг
    float smoothDist = smoothstep(-0.003, 0.003, dist);

    vec3 color = vec3(1.0, 0.0, 0.0);
    fragColor = vec4(color * (1.0 - smoothDist), 1.0);
}
Тут всё легко, аналогия с прошлым SDF, так же можно добавить abs(модуль числа) и сделать его не заполненным, а обведённым.

Не страшно если вы чего-то не поняли, я не особо умею объяснять, но попытался, это моя первая тема, так что не судите строго.
Сегодня у меня нет уже времени, так что публикую так.
Типо vanilla renderutil?
 
Новичок
Статус
Оффлайн
Регистрация
22 Сен 2020
Сообщения
58
Реакции[?]
3
Поинты[?]
2K
Начинающий
Статус
Оффлайн
Регистрация
25 Фев 2024
Сообщения
165
Реакции[?]
4
Поинты[?]
1K
Немного не по теме, тут я объяснял работу SDF, может быть будет тема про шейдеры когда дела закончу
ну я понял просто в любом случае чел не знает что такое SDF и где юзается и я просто сказал что типо это шейдера
 
Сверху Снизу