Новичок
-
Автор темы
- #1
Перед прочтением основного контента ниже, пожалуйста, обратите внимание на обновление внутри секции Майна на нашем форуме. У нас появились:
- бесплатные читы для Майнкрафт — любое использование на свой страх и риск;
- маркетплейс Майнкрафт — абсолютно любая коммерция, связанная с игрой, за исключением продажи читов (аккаунты, предоставления услуг, поиск кодеров читов и так далее);
- приватные читы для Minecraft — в этом разделе только платные хаки для игры, покупайте группу "Продавец" и выставляйте на продажу свой софт;
- обсуждения и гайды — всё тот же раздел с вопросами, но теперь модернизированный: поиск нужных хаков, пати с игроками-читерами и другая полезная информация.
Спасибо!
Всем привет!
Не буду углубляться в то, как писать шейдеры и как они работают в целом, так как на ютубе уже есть много видео на эту тему. Вместо этого я объясню, как работает Signed Distance Field (SDF), возможно, кто-то сразу поймет, но мне на это потребовалось время, поэтому я распишу это подробнее, покажу примеры и прикреплю полный код.
SDF (Signed Distance Field) — это функция, которая возвращает расстояние до границы объекта с учетом знака. Это означает, что функция указывает, находится ли точка внутри объекта, снаружи или на границе. Если "-", точка внутри объекта; если "+" — снаружи; если ноль — на границе. Field (поле) означает, что это множество значений, например, магнитное поле, которое зависит от источника магнитного поля.
Для начала я бы хотел разобрать SDF circle, достаточно простой пример
Как видите, я использую length, возможно кто-то в первый раз видит это, это тоже самое что и sqrt(vec2.x^2 + vec2.y^2), то-есть эта функция расчитывает длину вектора, если представлять на координатной системе, если y - 4 а x - 3, то длина до координата от равна 5
Далее я отнимаю радиус от координат и получается так что рисуется круг, см. ниже.
Ну выходит так что если отнять от центра радиус, то мы получим SDF и сможем заполнить как бы всё поле
Возможно что вы не понимаете как всё таки нарисовать этот круг, вот как сделал это я:
Как видим, всё работает, SS см. ниже
Теперь, если же добавить abs(модуль числа) в получение дистанции, то мы получим SDF снаружи круга(т.к число всегда будет +) и сможем сделать так называемый обруч, вот как это должно выглядеть, см. ниже.
Число которе мы отнимаем от полученной дистанции(в моём случае .01)можно назвать толщиной во все стороны, потому что центр смещается, теперь это центр обводки, а отнимаем мы так же как от центра круга, думаю это всё понятно, вот как будет выглядеть 'обруч', SS см. ниже.
По моему я достаточно сильно разжевал этот пример, если что-то не понятно, пишите.
Второй пример, rounded box SDF(закруглённый прямоугольник), код см. ниже.
Взято с
Да да, я сам не писал, но объясню как оно работает, для начала мы получаем модуль вектора CenterPosition, то-есть 1/4 часть, потому что только 1/4 часть имеет положительные координаты, нужно это для того что-бы упростить вычисления, далее отнимаем Size и получаем дистанцию от текущей точки до границы и прибавляем Radius для нормализации, т.к потом будем отнимать, если не делать это, то размер будет зависеть от радиуса, далее получаем максимальное значение, то-есть если abs(CenterPosition)-Size+Radius меньше 0, то мы получим 0.0, далее получаем length, здесь аналогия с кругом, мы получаем уже как бы дистанцию и отнимаем радиус, теперь рисуем, на этом всё, вот как это сделано у меня, код см. ниже.
Тут всё легко, аналогия с прошлым SDF, так же можно добавить abs(модуль числа) и сделать его не заполненным, а обведённым.
Не страшно если вы чего-то не поняли, я не особо умею объяснять, но попытался, это моя первая тема, так что не судите строго.
Сегодня у меня нет уже времени, так что публикую так.
Не буду углубляться в то, как писать шейдеры и как они работают в целом, так как на ютубе уже есть много видео на эту тему. Вместо этого я объясню, как работает 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;
}
Возможно что вы не понимаете как всё таки нарисовать этот круг, вот как сделал это я:
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;
По моему я достаточно сильно разжевал этот пример, если что-то не понятно, пишите.
Второй пример, 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);
}
Не страшно если вы чего-то не поняли, я не особо умею объяснять, но попытался, это моя первая тема, так что не судите строго.
Сегодня у меня нет уже времени, так что публикую так.
Последнее редактирование: