Eh bien, vous pouvez facilement écrire un shader pour contourner ce problème. Fondamentalement, vous devez le pousser proportionnellement à la valeur w que vous générez. c'est-à-dire si le cylindre a une largeur de r. alors vous pouvez annuler la perspective en la poussant vers (r * w). De cette façon, lorsque la division w se produit, elle vous donnera TOUJOURS r. Un cylindre, cependant, pourrait être un peu excessif, vous pourriez obtenir un effet similaire en dessinant une ligne Billboarded et en appliquant une texture à elle.
J'ai écrit un shader dans DX8 il y a de nombreuses années pour le faire (attention c'est avec perspective). Fondamentalement, je défini les données de sommet de la manière suivante:
struct BillboardLineVertex
{
D3DXVECTOR3 position;
D3DXVECTOR3 otherPosition;
DWORD colour;
D3DXVECTOR2 UV;
};
En supposant que la ligne passe de A à B, puis position A et B est otherPosition pour les 2 premiers sommets. De plus, j'ai encodé dans le V (ou y) de l'UV soit -1 soit 1. Cela m'a indiqué si je pousserais hors de la ligne vers le haut ou le bas de l'écran. Finalement la 3ème coordonnée pour le triangle avait le A & B en position et l'autre Position l'inverse (je vais vous laisser imaginer comment construire l'autre triangle.) Notez que la coordonnée de texture U (ou x) était réglable pour permettre J'ai ensuite eu l'assemblage de shader suivant pour construire les lignes ... Cela a ajouté le bonus qu'il fallait exactement 2 triangles pour faire une ligne ... Je pouvais ensuite les emballer tous dans 1 grand tampon de sommet et de rendre plusieurs centaines dans un appel Draw.
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
};
une telle configuration serait facilement modifiable pour vous donner la même taille quelle que soit la distance de la caméra.
Brillant .. et amusant de voir le code asm! J'ai fait à peu près la même chose mais en utilisant Geometry Shaders. Il évite le coût de la duplication d'autresPosition. Également pris en charge la largeur de ligne arbitraire et les types de ligne ala 'glLineStipple'. – Stringer
@Stringer: J'ai écrit ce code en 2001-ish;) Je suis d'accord si vous pouvez cibler les shaders de géométrie DX10 sont votre ami :) – Goz