ПрограммированиеФорумГрафика

рисовать линии на GLSL (2 стр)

Страницы: 1 2 3 Следующая »
#15
15:53, 1 ноя 2018

Геометрический шейдер?

#16
2:35, 19 ноя 2018

получил некоторые результаты, есть вопрос:

подскажите как сделать линии постоянной толщины через вершнинный шейдер, так возможно? кто подобное пробовал?
пока оба конца линии на экране - линия похоже что постоянной толщины
как только один из концов за экраном - становится заметно изменение толщины линии

делал так:
рисую двумя трианглами, для концов линии считаю толщину линии как зависимость расстояния до камеры
в вершинном шейдре к вершинам триангла прибавляю нормаль, посчитанную по вектору направления линии, умноженную на толщину (коэффициент зависящий от расстояния до камеры)

void main(){
   vec3 dir = normalize(position.xyz - second.xyz);
  float width = color.z;// коэффициент зависящий от расстояния до камеры
   vec3 n = normalize(cross(dir,position.xyz-cam_position));
   gl_Position = matrix * vec4(position.xyz+n*width,1.0f);
}

пологаю, что при пересечении линией экрана, нужно посчитать толщину в точке пересечения, но как?

#17
13:55, 19 ноя 2018

Нашёл!!! Помнил же, что был похожий вопрос.

#18
20:39, 21 ноя 2018

FordPerfect
спасибо за ссылку, но видимо я тупой и не нашёл полезного, там мало того что пользуют геометрический шейдер так часть ещё и фрагментном
>фрагментном шейдере считаются расстояния фрагмента до трех вершин. Т. е. часть работы из геометрического шейдера переносится во фрагментый
геометрический не пользую для линий из-за поддержки старого железа - всего то линии нарисовать, базовый функционал, это как атомной бомбой голубей шугать
нагуглить примитивные линии постоянной толщины не удалось, уже сомниваюсь что так можно
glBegin(GL_LINES) же както рисует - может месу поковырять?

#19
22:36, 21 ноя 2018

https://www.shadertoy.com/view/lsBSzc

#20
22:52, 21 ноя 2018

slax
> линии постоянной толщины
В screen-space?
Или в world-space?

#21
12:26, 22 ноя 2018

v1c
для каждого пикселя проходить по всем линиям - это перебор
FordPerfect
да, постоянной толшины на экране

#22
12:57, 22 ноя 2018


slax
> семь корней на каждый пиксель кажется жирновато чтобы рисовать линии
По-моему там нужно 0 корней:

#define resolution vec2(500.0, 500.0)
#define Thickness 0.03

float cross2d(vec2 a,vec2 b)
{
    return a.x*b.y-a.y*b.x;
}

float drawLine(vec2 p1, vec2 p2) {
  vec2 uv = gl_FragCoord.xy / resolution.xy;

  vec2 N=p2-p1;
  float N2=dot(N,N);
  float y=cross2d(uv-p1,N);
  float x=max(dot(p1-uv,N),0.0);
  x=max(dot(uv-p2,N),x);
  float d=x*x+y*y - Thickness*Thickness*N2;
  return d<0.0?1.0:0.0;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
  vec2 p1 = vec2(0.8 + sin(iTime)*0.5, 0.1);
  vec2 p2 = vec2(0.8 + cos(iTime)*0.5, 0.5);
  fragColor = vec4(drawLine(p1, p2));
}
#23
14:50, 22 ноя 2018

FordPerfect
т.к. пишешь в fragColor - значит линию рисуешь в фрагментном шейдере
а на какой примитив рисуешь как два триангла в экран 500x500?
если рисовать таким образом 1 000 000 линий это будет быстрее чем столькоже через glBegin(GL_LINES) ? на старых видяхах

и каждый из 500х500 пикселей будут считать расстояния до каждой из 1 000 000 линий .... всёравно кажется жирновато

видать я плохо объясняю задачу

#24
14:57, 22 ноя 2018

slax
Дак а зачем полный экран-то?
Рисовать OBB отрезка с таким шейдером.

#25
15:59, 22 ноя 2018

В смысле, если не нужен anti-aliasing, так можно и OBB сплошной заливкой + круги.
Но AA в шейдере может быть дешевле/качественнее.

#26
16:55, 22 ноя 2018

Ну что-то типа

#define AA 1 // Anti-aliasing
#define SCALE 4.0 // Size of a virtual pixel, to make AA more visible
#define Thickness 4.0 // In virtual pixels

float cross2d(vec2 a,vec2 b)
{
    return a.x*b.y-a.y*b.x;
}

float drawLine(vec2 p1, vec2 p2) {
  vec2 uv = gl_FragCoord.xy;
  uv=floor(uv/SCALE)*SCALE;
  float T=Thickness*SCALE;

  vec2 N=p2-p1;
  float N2=dot(N,N);
  float y=cross2d(uv-p1,N);
  float x=max(dot(p1-uv,N),0.0);
  x=max(dot(uv-p2,N),x);
  float d=x*x+y*y - T*T*N2;
#if AA
  // NOTE: this is an approximation.
  d=-d/(2.0*N2*T); // Distance (approximated) of sample point from edge.
  d/=float(SCALE);
  float k=abs(abs(N.x)-abs(N.y))/(abs(N.x)+abs(N.y)); // tan(slope), 0<=slope<=45 deg.
  k=mix(sqrt(0.5),1.0,k); // Or you can just approximate as k=1.
  d=clamp(0.5+k*d,0.0,1.0);
  return d;
#else
  return d<0.0?1.0:0.0;
#endif
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
  vec2 p1 = iResolution.xy*vec2(0.8 + sin(iTime)*0.5, 0.1);
  vec2 p2 = iResolution.xy*vec2(0.8 + cos(iTime)*0.5, 0.8);
  fragColor = vec4(drawLine(p1, p2));
}
#27
19:12, 22 ноя 2018

FordPerfect
Тут бесполезно что либо советовать. Человек слушает только себя.

#28
20:05, 22 ноя 2018

FordPerfect
>Рисовать OBB отрезка с таким шейдером.
так ооб отрезка будет иметь перспективу, для линии в скрин-спейс толщины это не хорошо, да филрейт будет ниже
>так можно и OBB сплошной заливкой + круги
вот - этот ооб построить в скринспейс у меня и не получается
получается только с перспективными искажениями а нужно без них

MrShoor
>Тут бесполезно что либо советовать. Человек слушает только себя.
я учёл твой совет про убийственный филлрейт,
и не только себя слушаю, а пытаюсь объяснить, что нужно без геометрического/фрагментного/ffp выводить 3d линии в скрин-спейс одной толщиной через вершинный шейдер, эффективно рисовать много линий
и при расчёте вершин, задающих толщину, у меня не получается сделать её одинаковой толщины по всей длинне линии на экране
на что получаю советы ... про другое и реализованное другими техниками, значит плохо объясняю -
как правильно сформулировать чтоб сразу всем понятно стало?

#29
20:12, 22 ноя 2018

slax
> а пытаюсь объяснить, что нужно без геометрического/фрагментного/ffp
Но почему без фрагментного то? Без геометрического - могу понять, но фрагментный шейдер он ведь есть на железе даже 15-ти летней давности. Почему без него то?

Страницы: 1 2 3 Следующая »
ПрограммированиеФорумГрафика

Тема в архиве.