рисование линий в 3D (DirectX)? - PullRequest
       42

рисование линий в 3D (DirectX)?

1 голос
/ 29 сентября 2010

Я добавляю линии в свой 3D мир, как мы видим в 3D studio max. Для рисования линий я использую цилиндрическую сетку и просто растягиваю / поворачиваю ее соответствующим образом. Это все работает нормально, но моя проблема в масштабе. Так как это 3D-геометрия в перспективе, его размер изменяется, от расстояния оно маленькое до невидимого, близко оно огромно.

Я хочу сделать так, чтобы размер геометрии линии оставался неизменным. Я пытался играть с орфографической проекцией, но ничего не придумал. Есть идеи?

1 Ответ

1 голос
/ 29 сентября 2010

Ну, вы могли бы легко написать шейдер, чтобы обойти эту проблему. По сути, вам нужно вытолкнуть его пропорционально генерируемому вами значению w. т.е. если цилиндр имеет ширину r. затем вы можете отменить перспективу, выдвинув ее к (r * w). Таким образом, когда происходит деление w, оно ВСЕГДА даст вам r.

Цилиндр, тем не менее, может быть немного чрезмерным, вы можете получить аналогичный эффект, нарисовав линию щита и применив к нему текстуру.

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

struct BillboardLineVertex
{
    D3DXVECTOR3  position;
    D3DXVECTOR3  otherPosition;
    DWORD        colour;
    D3DXVECTOR2  UV;
};

Если предположить, что линия идет от A к B, то позиция - это A, а otherPosition - это B для первых 2 вершин. Кроме того, я закодировал в V (или y) UV либо -1, либо 1. Это сказало мне, буду ли я выталкивать из линии вверх или вниз по экрану. Наконец, 3-я координата для треугольника имела A & B в положении и otherPosition в обратном направлении (я оставлю вас, чтобы выяснить, как построить другой треугольник. Обратите внимание, что координата текстуры U (или x) была установлена, чтобы позволить для текстуры, повторяющейся вдоль линии.

Затем у меня был следующий фрагмент сборки шейдеров для построения линий ... Это было дополнительным бонусом, что для выполнения одной линии потребовалось ровно 2 треугольника ... Затем я мог упаковать их все в 1 большой буфер вершин и визуализировать несколько сотен в одном розыгрыше.

asm
{
    vs.1.1

// Create line vector.
    mov r1, v0
    sub r3, r1, v4

// Get eye to line vector
    sub r6, v0, c20

// Get Tangent to line vector lieing on screen plane.
    mul r5, r6.yzxw, r3.zxyw
    mad r5, -r3.yzxw, r6.zxyw, r5

// Normalise tangent
    dp3 r4.w, r5.xyz, r5.xyz
    rsq r4.w, r4.w
    mul r5.xyz, r5.xyz, r4.w

// Multiply by 1 or -1 (y part of UV)
    mul r5.xyz, r5.xyz, -v9.y

// Push tangent out by "thickness"
    mul r5.xyz, r5.xyz, c16.x
    add r1.xyz, r1.xyz, r5.xyz

// Transform position
    m4x4 oPos, r1, c0

// Work out UV (c16.y is assumed to contain 0.5, c16.z is assumed to contain 1)
    mov r2.xy, v9.xy
    mul r2.y, v9.y, v9.x
    add r2.xy, r2.xy, c16.z
    mul oT0.xy, r2.xy, c16.y

// Move colour into diffuse output channel.
    mov oD0, v3
};

Такая настройка легко модифицируется, чтобы получить одинаковый размер независимо от расстояния до камеры.

...