web-dev-qa-db-fra.com

Épaisseur des lignes utilisant THREE.LineBasicMaterial

J'utilise le code ci-dessous pour créer des centaines de lignes dans ma scène three.js

edgeGeometry[i] = new THREE.Geometry();
edgeGeometry[i].vertices[0] = v(x1,y1,z1);
edgeGeometry[i].vertices[1] = v(x2,y2,z2);
edgesMat[i] = new THREE.LineBasicMaterial({
    color: 0x6699FF, linewidth: 1, fog:true});
Edge[i] = new THREE.Line(edgeGeometry[i], edgesMat[i]);
Edge[i].type = THREE.Lines;
scene2.add(Edge[i]);

Cela fonctionne très bien, mais quand je change la valeur de "linewidth" en une valeur plus grande OR plus petite, je ne vois AUCUNE différence dans la scène.
Comment changer l'épaisseur des lignes? Des idées?
Merci, Dimitris

31
Dimitris

Utilisez-vous Windows?
Je me souviens que cela ne fonctionnait pas sous Windows car il n'a pas été implémenté dans ANGLE .

18
mrdoob

1) Utilisez OpenGL natif

Vous pouvez obtenir un rendu des épaisseurs de ligne avec une solution de contournement en configurant votre navigateur pour utiliser OpenGL natif au lieu d'ANGLE. Vous pouvez lire ici comment faire cela sur Chrome . Gardez à l'esprit que vous constaterez des différences de performances si vous passez à OpenGL natif.

MODIFIER:

Le maître MrDoob lui-même affiché ici comment faire cela pour les deux Chrome et Firefox .

Remarque: Cette première option n'est plus une solution valide car les dernières versions d'OpenGL ne prennent plus en charge l'épaisseur de ligne non plus. Vérifiez également @gman sa réponse . Cela signifie que si vous souhaitez utiliser l'épaisseur de ligne, la deuxième option est la voie à suivre.


2) Utilisez la classe THREE.MeshLine

Il existe également une autre solution; cette classe THREE.MeshLine sur github est une solution de contournement intéressante. Il est livré avec un THREE.MeshLineMaterial Spécial. Selon les documents, c'est aussi simple que:

  • Créer et remplir une géométrie
  • Créez un THREE.MeshLine Et attribuez la géométrie
  • Créez un THREE.MeshLineMaterial
  • Utilisez THREE.MeshLine Et THREE.MeshLineMaterial Pour créer un THREE.Mesh
22
Wilt

Cela se produit dans Windows Chrome et Firefox, tous deux utilisant ANGLE (WebGL à wrapper DirectX).

Le problème n'est toujours pas résolu par le projet ANGLE. Vous pouvez suivre le problème ici pour obtenir une priorité plus élevée et recevoir une notification s'il va être mis en œuvre:

https://code.google.com/p/angleproject/issues/detail?id=119

12
user2090712

Ce n'est plus un problème uniquement dans ANGLE, c'est un problème sur toutes les plateformes. Les navigateurs nécessaires pour basculer vers le profil principal OpenGL 4+ pour prendre en charge WebGL2 et le profil principal OpenGL 4+ ne prennent pas en charge les largeurs de ligne supérieures à 1. Dans la spécification OpenGL 4.0+, section E.2.1

E.2.1 Fonctions obsolètes mais toujours prises en charge

Les fonctionnalités suivantes sont déconseillées, mais toujours présentes dans le profil principal. Ils peuvent être supprimés d'une future version d'OpenGL et sont supprimés dans un contexte de compatibilité ascendante mettant en œuvre le profil principal.

  • Lignes larges - Les valeurs LineWidth supérieures à 1.0 génèrent une erreur INVALID_VALUE.

Pour dessiner des lignes plus épaisses, vous devez générer une géométrie. Pour three.js, il y a cette bibliothèque (soulignée également par Wilt)

https://github.com/spite/THREE.MeshLine

4
gman

Vous pouvez utiliser CanvasRenderer au lieu de Webglrenderer. Consultez la documentation officielle ici où chaque forme a une bordure de largeur de ligne = 10;

1
raulsi

Vous pouvez obtenir le même effet en utilisant extrude-polyline pour générer un complexe simplicial pour la ligne (poly) épaissie et three-simplicial-complex pour le convertir en un maillage three.js:

const THREE = require('three');
const extrudePolyline = require('extrude-polyline');
const Complex = require('three-simplicial-complex')(THREE);

function thickPolyline(points, lineWidth) {
  const simplicialComplex = extrudePolyline({
    // Adjust to taste!
    thickness: lineWidth,
    cap: 'square',  // or 'butt'
    join: 'bevel',  // or 'miter',
    miterLimit: 10,
  }).build(points);

  // Add a z-coordinate.
  for (const position of simplicialComplex.positions) {
    position[2] = 0;
  }

  return Complex(simplicialComplex);
}

const vertices = [[0, 0], [10, 0], [10, 10], [20, 10], [30, 00]];
const geometry = thickPolyline(vertices, 10);

const material = new THREE.MeshBasicMaterial({
  color: 0x009900,
  side: THREE.DoubleSide
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

Voici un exemple complet avec le source . (Il y a actuellement un problème sur requirebin qui l'empêche de rendre l'exemple source).

Si vous voulez texturer la polyligne, les choses deviennent un peu plus compliquées.

1
danvk

J'utilise TubeGeometry pour créer une ligne épaisse entre deux points:

Voir les lignes vertes à Helix

enter image description here

// line material
var lineMaterial = new THREE.LineBasicMaterial({ color: 0x00ff00 });


let startVector = new THREE.Vector3(
    RADI * Math.cos(t),
    RADI * Math.sin(t),
    3 * t
  );
  let endVector = new THREE.Vector3(
    RADI * Math.cos(t + 10),
    RADI * Math.sin(t + 10),
    3 * t
  );

  let linePoints = [];
  linePoints.Push(startVector, endVector);

  // Create Tube Geometry
  var tubeGeometry = new THREE.TubeGeometry(
    new THREE.CatmullRomCurve3(linePoints),
    512,// path segments
    0.5,// THICKNESS
    8, //Roundness of Tube
    false //closed
  );

  //add buffer geometry
  let tubeBufferGeomtry = new THREE.BufferGeometry().fromGeometry(
    tubeGeometry
  );

  let line = new THREE.Line(tubeGeometry, lineMaterial);
  scene.add(line);
1
Hitesh Sahu