2015-07-21 4 views
8

Ist es möglich, das Drahtgitter des Objekts und die Farbe seiner Flächen auf demselben Objekt anzuzeigen? Ich habe einen Weg gefunden mit einem Klon des Objekts und verschiedene Materialien z. B.Anzeige Drahtmodell und Volltonfarbe

var geometry = new THREE.PlaneGeometry(plane.width, plane.height,width - 1, height - 1); 
var materialWireframe = new THREE.MeshPhongMaterial({color:"red",wireframe:true}); 
var materialSolid = new THREE.MeshPhongMaterial({color:"green",wireframe:false}); 
var plane = new THREE.Mesh(geometry, materialWireframe); 
var plane1 = plane.clone(); 
plane1.material = materialSolid ; 
plane1.material.needsUpdate = true; 

irgendwelche Gedanken?

+0

Vielleicht ein benutzerdefinierter Shader? – Shomz

+0

können Sie weiter erklären? Wie kann jemand Shadermaterial für diesen Zweck verwenden? – mrapsogos

+0

Sie können Ihre eigenen Shader definieren, also können Sie es versuchen: https://aerotwist.com/tutorials/an-introduction-to-shaders-part-1/ Wenn nicht, können Sie immer eine Drahtgitterstruktur mit einem Solid verwenden Hintergrund. – Shomz

Antwort

21

zu machen sowohl ein Modell und sein Drahtmodell, können Sie ein Muster wie diese verwenden:

// mesh 
var material = new THREE.MeshPhongMaterial({ 
    color: 0xff0000, 
    polygonOffset: true, 
    polygonOffsetFactor: 1, // positive value pushes polygon further away 
    polygonOffsetUnits: 1 
}); 
var mesh = new THREE.Mesh(geometry, material); 
scene.add(mesh) 

// wireframe 
var geo = new THREE.EdgesGeometry(mesh.geometry); // or WireframeGeometry 
var mat = new THREE.LineBasicMaterial({ color: 0xffffff, linewidth: 2 }); 
var wireframe = new THREE.LineSegments(geo, mat); 
mesh.add(wireframe); 

Die Verwendung von polygonOffset helfen z Bekämpfung zwischen dem Maschenmaterial und der Drahtgitterlinie verhindert. Folglich wird das Drahtmodell viel besser aussehen.

Geige: http://jsfiddle.net/tfjvggfu/24/

EDIT: aktualisiert r.82

+0

Linienbreite ändert nicht die Breite der Linien mit dem KantenHelper oder WireframeHelper – Marcs

+1

@Marcs Wenn Sie Windows ausführen, ist es wahrscheinlich eine Beschränkung ANGLE. – WestLangley

+0

Ja, gerade auf Linux getestet, und die Eigenschaft linewidth funktioniert. Irgendwie nervig. – Marcs

2

Three.js, das zu tun, ist eine Möglichkeit, ein GLSL Fragment-Shader zu verwenden, die das Fragment Farbe ändert, wenn das Fragment in der Nähe einer Kante des Dreiecks. Hier ist der GLSL-Shader, den ich verwende. Als Eingabe werden die baryzentrischen Koordinaten des Fragments im Dreieck und eine Kantenmaske verwendet, die für jede Kante auswählt, ob sie gezeichnet werden soll oder nicht. (Rem: Ich hatte es mit der Kompatibilität Profil aus Gründen der Abwärtskompatibilitätsgründen zu verwenden, wenn Sie das nicht tun wollen, kann es leicht angepasst werden):

const char* fshader_source = 
     "#version 150 compatibility           \n" 
     "flat in float diffuse;            \n" 
     "flat in float specular;           \n" 
     "flat in vec3 edge_mask;           \n" 
     "in vec2 bary;              \n" 
     "uniform float mesh_width = 1.0 ;         \n" 
     "uniform vec3 mesh_color = vec3(0.0, 0.0, 0.0) ;     \n" 
     "uniform bool lighting = true ;          \n" 
     "out vec4 frag_color ;            \n" 
     "float edge_factor(){            \n" 
     " vec3 bary3 = vec3(bary.x, bary.y, 1.0-bary.x-bary.y) ;   \n" 
     " vec3 d = fwidth(bary3);          \n" 
     " vec3 a3 = smoothstep(vec3(0.0,0.0,0.0), d*mesh_width, bary3); \n" 
     " a3 = vec3(1.0, 1.0, 1.0) - edge_mask + edge_mask*a3;   \n" 
     " return min(min(a3.x, a3.y), a3.z);        \n" 
     "}                 \n" 
     "void main() {              \n" 
     " float s = (lighting && gl_FrontFacing) ? 1.0 : -1.0 ;   \n" 
     " vec4 Kdiff = gl_FrontFacing ?         \n" 
     "   gl_FrontMaterial.diffuse : gl_BackMaterial.diffuse ;  \n" 
     " float sdiffuse = s * diffuse ;         \n" 
     " vec4 result = vec4(0.1, 0.1, 0.1, 1.0);      \n" 
     " if(sdiffuse > 0.0) {           \n" 
     "  result += sdiffuse*Kdiff +         \n" 
     "     specular*gl_FrontMaterial.specular;    \n" 
     " }                \n" 
     " frag_color = (mesh_width != 0.0) ?        \n" 
     "     mix(vec4(mesh_color,1.0),result,edge_factor()) : \n" 
     "     result ;           \n" 
     "}                 \n"; 
+1

Mit späteren TS-Versionen können Sie die this.fragmentSrc = '-Syntax verwenden, die mehrzeilige Strings erlaubt. – Sentinel

+0

Gibt es ein Online-Beispiel, das dies verwendet? – shinzou

+0

Dies bricht nur die Form ... – shinzou

0

Um zu vermeiden, mein Objekt Klonen verwendete ich ein Muster wie dass:

var mat_wireframe = new THREE.MeshBasicMaterial({color: 0x000000, wireframe: true}); 
var mat_lambert = new THREE.MeshLambertMaterial({color: 0xffffff, shading: THREE.FlatShading}); 
var meshmaterials = [ mat_wireframe, mat_lambert ]; 

und dann angewendet, dass es so meine Masche:

var myMesh = THREE.SceneUtils.createMultiMaterialObject(mesh_geometry, meshmaterials); 
scene.add(myMesh) ; 

ich hoffe, es könnte helfen ...

+0

'createMultiMaterialObject()' instanziiert ein separates 'Mesh' für jedes Material und vermeidet daher nicht das" Klonen ". – WestLangley

Verwandte Themen