开发者

drawing lines in 3D (DirectX)?

开发者 https://www.devze.com 2023-01-18 04:20 出处:网络
I\'m adding lines to my 3D world like we see in 3D studio max. To draw lines I\'m using a cylinder mesh and simply stretching/rotating it appropriately. That\'s all working fine but my problem is scal

I'm adding lines to my 3D world like we see in 3D studio max. To draw lines I'm using a cylinder mesh and simply stretching/rotating it appropriately. That's all working fine but my problem is scale. Since it's 3D geometry rendering in perspective its size changes, from a distance it's small to invisible, up close it's h开发者_如何学编程uge.

I want to make it so the size of the line geometry stays the same. I tried toying around with orthographic projection but came up with nothing. Any ideas?


Well you could easily write a shader to get round that problem. Basically you need to push it out proportionally to the w value you generate. ie if the cylinder has a width of r. then you can cancel out the perspective by pushing it out to (r * w). This way when the w divide occurs it will ALWAYS give you r.

A cylinder, though, could be a tad excessive you could get a similar effect by drawing a billboarded line and applying a texture to it.

I wrote a shader in DX8 many years ago to do this (mind this is with perspective). Basically I defined the vertex data as follows:

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

Assuming the line goes from A to B then position is A and otherPosition is B for the first 2 vertices. Furthermore I encoded into the V (or y) of the UV either a -1 or 1. This told me whether I would push out from the line up or down the screen. Finally the 3rd coordinate for the triangle had the A & B in position and otherPosition the other way round (I'll leave you to figure out how to build the other triangle. Note that the U texture coord (or x) was settable to allow for texture repeating along the line.

I then had the following bit of shader assembly to build the lines ... This had the added bonus that it took exactly 2 triangles to do one line... I could then pack them all into 1 big vertex buffer and render several hundred in one Draw call.

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
};

Such a setup would be easily modifiable to give you the same size regardless of distance from the camera.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号