在3D中绘制线条(DirectX)?

时间:2010-09-29 02:10:45

标签: math matrix directx projection

我正在为我的3D世界添加线条,就像我们在3D studio max中看到的那样。要绘制线条,我正在使用圆柱网格,只需适当地拉伸/旋转它。这一切都很好,但我的问题是规模。由于它的三维几何渲染在透视中它的大小会发生变化,从一个小到一个不可见的距离,近距离它是巨大的。

我想这样做,因此线几何的大小保持不变。我尝试用正交投影来解决这个问题,但却没有想到什么。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

嗯,你可以轻松编写一个着色器来解决这个问题。基本上你需要按照你生成的w值按比例推出它。即,如果圆柱体的宽度为r。那么你可以通过将它推出到(r * w)来取消透视。这样当w除法发生时,它总是会给你r。

但是,一个圆柱体可能有点过分,你可以通过绘制一条广告牌并对其应用纹理来获得类似的效果。

多年前我在DX8中写了一个着色器来做这个(请注意这是透视)。基本上我定义了顶点数据如下:

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

假设线从A到B,则位置为A,其他位置为前2个顶点的B。此外,我编码到UV的V(或y)a -1或1.这告诉我是否会从屏幕上方向上或向下推出。最后,三角形的第三个坐标是A& B在位置和其他位置反过来(我将让你弄清楚如何构建另一个三角形。请注意,U纹理坐标(或x)可以设置为允许纹理沿着线重复。

然后我有了下面的着色器组件来构建线......这有额外的好处,它只需要2个三角形来做一行......然后我可以将它们全部打包成一个大的顶点缓冲区并渲染几百个抽奖电话。

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

无论与相机的距离如何,这样的设置都可以轻松修改,以提供相同的尺寸。