Affichage en fil de fer et couleur unie

Est-il possible d'afficher le maillage de l'objet et aussi la couleur solide de ses faces sur le même objet? J'ai trouvé un moyen d'utiliser un clone de l'objet et d'assigner différents matériaux E. g

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;

une idée?

8
demandé sur Iman Mahmoudinasab 2015-07-21 15:31:50

3 réponses

pour rendre à la fois un modèle et son wireframe, vous pouvez utiliser un modèle comme celui-ci:

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

l'utilisation de polygonOffset aidera à prévenir le combat z entre le matériau de maille et la ligne de fil de fer. Par conséquent, le fil de fer aura l'air beaucoup mieux.

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

EDIT: mis à jour à trois.JSR.82

28
répondu WestLangley 2017-07-04 14:48:47

pour ce faire, une possibilité est d'utiliser un shader de fragment GLSL qui change la couleur du fragment lorsque le fragment est près d'un bord du triangle. Voici le shader GLSL que j'utilise. Comme entrée, il prend les coordonnées barycentriques du fragment dans le triangle, et un masque de bord qui sélectionne pour chaque bord si elle doit être dessinée ou non. (rem: j'ai dû l'utiliser avec la compatibilité de profil pour des raisons de compatibilité descendante, si vous ne voulez pas le faire, il peut facilement être adapté):

(source du fragment)

#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;
}
2
répondu BrunoLevy 2018-06-19 14:49:11

pour éviter de cloner mon objet, j'ai utilisé un motif comme celui-ci :

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

et je l'ai appliqué sur ma maille comme ça:

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

j'espère que ça pourrait aider...

1
répondu Julien_ 2017-11-07 18:35:09