web-dev-qa-db-fra.com

Affichage filaire et couleur unie

Est-il possible d'afficher le filaire de l'objet ainsi que la couleur unie de ses faces sur le même objet? J'ai trouvé un moyen d'utiliser un clone de l'objet et d'attribuer différents matériaux, par exemple

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;

des pensées?

17
prieston

Pour rendre à la fois un modèle et son filaire, vous pouvez utiliser un motif 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 permettra d'éviter les combats z entre le matériau du maillage et la ligne filaire. Par conséquent, la structure filaire sera bien meilleure.

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

EDIT: mis à jour à three.js r.82

43
WestLangley

Cela peut également être réalisé avec WireframeGeometry: https://threejs.org/docs/#api/en/geometries/WireframeGeometry . (et donnez au plan et à la ligne la même position, vous pouvez aussi jouer avec l'opacité voir les docs).

let geometryWithFillAndWireFrame = () => {

    let geometry = new THREE.PlaneGeometry(250, 250, 10, 10);
    let material = new THREE.MeshBasicMaterial( { color: 0xd3d3d3} );
    let plane = new THREE.Mesh(geometry, material);

    scene.add(plane);

    let wireframe = new THREE.WireframeGeometry( geometry );

    let line = new THREE.LineSegments( wireframe );

    line.material.color.setHex(0x000000);

    scene.add(line);

};
2
Inbal Ben Itamar

Pour ce faire, une possibilité consiste à utiliser un ombrage 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. En entrée, il prend les coordonnées barycentriques du fragment dans le triangle et un masque Edge qui sélectionne pour chaque Edge s'il doit être dessiné ou non. (rem: je devais l'utiliser avec le profil de compatibilité pour des raisons de rétrocompatibilité, si vous ne le souhaitez pas, 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
BrunoLevy

Pour éviter de cloner mon objet, j'ai utilisé un modèle 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 ];

puis je l'ai appliqué à ma maille comme ça:

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

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

2
Julien_