2010-09-29 149 views
1

我在我的3D世界中添加线条,就像我们在3D studio max中看到的一样。为了绘制线条,我使用圆筒网格,并简单地拉伸/旋转它。这一切工作正常,但我的问题是规模。由于3D立体几何呈现的透视效果,它的大小会随着距离的变化而变小,从而变得不可见,最后变得非常大。在3D(DirectX)中绘制线条?

我想使它的线几何尺寸保持不变。我尝试着用正射投影四处游荡,但什么也没有。有任何想法吗?

回答

1

那么你可以很容易地写一个着色器来解决这个问题。基本上你需要按照你生成的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)中,-1或1。这告诉我,我是否会从屏幕向上或向下推出。最后,三角形的第三个坐标的位置是A & B,另一个位置是另一个位置(我会让你找出如何建立另一个三角形。注意,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 
}; 

这样的设置是很容易修改给你相同的大小,无论距离的相机。

+0

Brillant ..和乐趣看到il asm代码!我做了同样的事情,但使用几何着色器。它避免了重复其他位置的成本。还支持任意线宽和线型ala'glLineStipple'。 – Stringer 2010-09-29 13:40:42

+0

@Stringer:我在2001年写了这个代码-ISH;)我同意你是否可以定位DX10几何着色器是你的朋友:) – Goz 2010-09-29 13:45:43