Рисование линии с использованием матрицы OpenGL - PullRequest
0 голосов
/ 10 ноября 2018

Я работаю над шейдерами, которые я модифицировал но я хочу просто нарисовать линию вместо этого эффекта размытия / цветения Я понял, что это Float d, который используется в качестве модификатора, но как получить эту простую строку вместо

Я основал свое исследование на этом шейдере

Буду признателен за любую помощь

Золтан

#ifdef GL_ES
precision mediump float;
#endif

mat4 mat  = mat4 (
        vec4 ( Scale * SizeTpDwn , 0.0 , 0.0 , 0.0 ),
        vec4 ( 0.0 , Scale * SizeLftRght , 0.0 , 0.0 ),
        vec4 ( 0.0 , 0.0 , Scale , 0.0 ),
        vec4 ( 0.0 , 0.0 , 0.0 , Scale ) );

vec2 pos;
vec4 linecol = vec4 (0.5 , 0.5 , 0.7 , 0.5);

vec4 col = vec4 ( 0.0, 0.0, 0.0, 1.0 );

void Line4 ( vec4 a, vec4 b );
void Line2 ( vec2 a, vec2 b );

void main( void ) {

    pos = gl_FragCoord.xy / RENDERSIZE.xy;
    pos -= .5;

    //Line
    Line4 ( vec4 ( LengthTX, MoveTX, .2 ,-.2), vec4 (LengthTX2, MoveTX2, .2, -.2 ) );
    //Line4 ( vec4 ( MoveRX, LengthRY, .2 ,-.2 ),vec4 ( MoveRX2,LengthRY2, .2, -.2 ) );
    //Line4 ( vec4 (MoveLX, LengthLY, .2 ,-.2 ),vec4 (MoveLX2,LengthLY2, .2, -.2 ) );
    //Line4 ( vec4 ( LengthDX,MoveDX, .2 ,-.2), vec4 (LengthDX2,MoveDX2, .2, -.2 ) );

    gl_FragColor = vec4( col.xyz, 1.0 );
}

void Line4 ( vec4 a, vec4 b )
{
    a = mat * a;
    //a.xyz /= 1.5 + a.w * 2.;
    b = mat * b;
    //b.xyz /= 1.5 + b.w * 2.;
    Line2 ( a.xy , b.xy );
}

void Line2 ( vec2 a, vec2 b )
{
    float dtc = (distance ( pos , a ) + distance ( pos , b ) - distance ( a , b )); //+ 1e-5);

    //linecol = vec4 (0.5 , 0.5 , 0.7 , 0.5);
    col += max ( 1. - pow ( dtc * 14. , 0.10 ) , -.10 );
}

1 Ответ

0 голосов
/ 10 ноября 2018

Что вам нужно сделать, это найти ближайшее расстояние текущего фрагмента к линии. Если это расстояние меньше толщины половины линии, то фрагмент находится на линии.
Чтобы создать линию с острыми краями, я рекомендую использовать функцию step, которая возвращает 0.0, если значение меньше контрольного значения, и 1.0 в противном случае.
Чтобы нарисовать линию, которая не является бесконечной, вы должны проверить, находится ли точка на бесконечной линии, которая ближе всего к текущей позиции, между началом и концом линии:

void Line2 (vec2 L1, vec2 L2)
{
    vec2  P   = pos;
    vec2  O   = L1;         
    vec2  D   = normalize(L2-L1);
    float d   = dot(P-O, D);
    vec2  X   = L1 + D * d;

    float dtc;
    if (d < 0.0)
        dtc = distance(L1, P); // d < 0.0 -> X is "before" L1
    else if (d > distance(L1, L2))
        dtc = distance(L2, P); // d > distance(L1, L2) -> X is "after" L2
    else
        dtc = distance(pos, X);

    col += 1.0 - step(0.01, dtc);
}

Preview

line


Пояснение:

Предположим, что линия определена Точкой O, а Единичный вектор D с указывает направление линии. Обратите внимание, что длина единичного вектора равна 1.

Далее у вас есть точка P, и вы хотите найти ближайшую точку X на линии (O, D) до P.

Сначала вычислите вектор V от O до P:

V = P - O;

Расстояние d от O до точки пересечения X может быть рассчитано с помощью Dot product .
Обратите внимание, поскольку D является единичным вектором, точка prduct из V и D равен косинусу угла между линией (O, D) и вектором V, умноженным на величину (длину) V:

d = dot(V, D);

Точка пересечения X может быть рассчитана путем смещения точки O вдоль линии (D) на расстояние d:

X = O + D * d;    

Итак, формула для точки пересечения:

O ... any point on the line
D ... unit vector which points in the direction of the line
P ... the "Point"

X = O + D * dot(P-O, D); 


Обратите внимание, что если линия определяется 2 точками, L1 и L2, тогда единичный вектор D может быть рассчитан следующим образом:

D = normalize(L2-L1);
...