Возможно ли добавить толщину строки в шейдере фрагмента, учитывая, что я рисую линию с помощью GL_LINES? Большинство примеров, которые я видел, похоже, имеют доступ только к текселям внутри примитива в шейдере фрагмента, а шейдер линии толщины должен писать в тексели вне примитива линии, чтобы получить толщину. Однако, если это возможно, очень маленький, простой пример. Было бы здорово.
Можно ли нарисовать толщину линии в фрагментном шейдере?
Ответ 1
Довольно много возможно с помощью флеш-шейдеров. Просто посмотрите то, что делают некоторые парни. Я далек от этого уровня, но этот код может дать вам идею:
#define resolution vec2(500.0, 500.0)
#define Thickness 0.003
float drawLine(vec2 p1, vec2 p2) {
vec2 uv = gl_FragCoord.xy / resolution.xy;
float a = abs(distance(p1, uv));
float b = abs(distance(p2, uv));
float c = abs(distance(p1, p2));
if ( a >= c || b >= c ) return 0.0;
float p = (a + b + c) * 0.5;
// median to (p1, p2) vector
float h = 2 / c * sqrt( p * ( p - a) * ( p - b) * ( p - c));
return mix(1.0, 0.0, smoothstep(0.5 * Thickness, 1.5 * Thickness, h));
}
void main()
{
gl_FragColor = vec4(
max(
max(
drawLine(vec2(0.1, 0.1), vec2(0.1, 0.9)),
drawLine(vec2(0.1, 0.9), vec2(0.7, 0.5))),
drawLine(vec2(0.1, 0.1), vec2(0.7, 0.5))));
}
Другой альтернативой является проверка с помощью texture2D
для цвета соседнего пикселя - таким образом, вы можете сделать изображение сияющим или утолщенным (например, если какой-либо пиксель регулировки белого цвета - сделать текущий пиксель белым, если рядом с соседним пикселем белый - сделать текущий пиксель серым).
Ответ 2
Вот мой подход. Пусть p1 и p2 - две точки, определяющие прямую, и пусть точка - это точка, расстояние до которой вы хотите измерить. Точка, скорее всего, gl_FragCoord.xy/resolution;
Здесь функция.
float distanceToLine(vec2 p1, vec2 p2, vec2 point) {
float a = p1.y-p2.y;
float b = p2.x-p1.x;
return abs(a*point.x+b*point.y+p1.x*p2.y-p2.x*p1.y) / sqrt(a*a+b*b);
}
Затем используйте это в ваших функциях mix и smoothstep.
Также проверьте этот ответ: fooobar.com/questions/376784/...
Ответ 3
Нет, это невозможно в шейдере фрагмента. Тем не менее, вы можете использовать геометрический шейдер, чтобы расширить вашу линию до квадранта (или, фактически, двух треугольников), который может представлять собой толстую линию.
Вот приятное обсуждение этой темы (с образцами кода).
Ответ 4
Простой способ - просто добавить джиттер в вершинный шейдер: gl_Position + = vec4 (дельта, дельта, дельта, 0,0); где delta - размер пикселя, то есть 1,0/viewsize
Выполните прохождение рисования линии дважды, используя ноль, а затем дельту как джиттер (передайте как униформу).