Display wireframe y color sólido

¿Es posible mostrar la estructura alámbrica del objeto y también el color sólido de sus caras en el mismo objeto? Encontré una manera de usar un clon del objeto y asignar diferentes materiales, por ejemplo

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; 

¿Alguna idea?

Para representar un modelo y su estructura alámbrica, puede usar un patrón como este:

 // 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 ); 

El uso de polygonOffset ayudará a evitar la lucha z entre el material de malla y la línea de estructura de alambre. En consecuencia, la estructura metálica se verá mucho mejor.

violín: http://jsfiddle.net/tfjvggfu/24/

EDITAR: actualizado a three.js r.82

Para hacer eso, una posibilidad es usar un sombreador de fragmentos GLSL que cambie el color del fragmento cuando el fragmento esté cerca de un borde del triángulo. Aquí está el sombreador GLSL que estoy usando. Como entrada, toma las coordenadas baricéntricas del fragmento en el triángulo, y una máscara de borde que selecciona para cada borde si se debe dibujar o no. (rem: tuve que usarlo con el perfil de compatibilidad por motivos de compatibilidad con versiones anteriores, si no quieres hacerlo, puede adaptarse fácilmente):

(fuente del fragmento)

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

Para evitar clonar mi objeto, utilicé un patrón como ese:

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

y luego lo apliqué a mi malla así:

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

Espero que pueda ayudar …

Intereting Posts