显示线框和纯色
Display wireframe and solid color
是否可以在同一个物体上同时显示物体的线框和其表面的纯色?我找到了一种使用对象的克隆并分配不同材料的方法,例如
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;
有什么想法吗?
要渲染模型及其线框,您可以使用像这样的模式:
// 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 } );
var wireframe = new THREE.LineSegments( geo, mat );
mesh.add( wireframe );
polygonOffset
的使用将有助于防止网格 material 和线框线之间的 z 冲突。因此,线框看起来会好很多。
three.js r.126
为此,一种可能是使用 GLSL 片段着色器,当片段靠近三角形的一个边时,它会更改片段颜色。这是我正在使用的 GLSL 着色器。作为输入,它采用三角形中片段的重心坐标,以及为每条边选择是否应绘制的边掩码。 (rem:出于向后兼容性的原因,我不得不将它与兼容性配置文件一起使用,如果你不想这样做,它可以很容易地进行调整):
(片段来源)
#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;
}
为了避免克隆我的对象,我使用了这样的模式:
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 ];
然后将它应用到我的网格上:
var myMesh = THREE.SceneUtils.createMultiMaterialObject( mesh_geometry, meshmaterials );
scene.add( myMesh ) ;
希望对您有所帮助...
这也可以通过 WireframeGeometry 实现:
https://threejs.org/docs/#api/en/geometries/WireframeGeometry。
(并给平面和线相同的位置,你也可以玩不透明度见文档)。
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);
};
是否可以在同一个物体上同时显示物体的线框和其表面的纯色?我找到了一种使用对象的克隆并分配不同材料的方法,例如
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;
有什么想法吗?
要渲染模型及其线框,您可以使用像这样的模式:
// 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 } );
var wireframe = new THREE.LineSegments( geo, mat );
mesh.add( wireframe );
polygonOffset
的使用将有助于防止网格 material 和线框线之间的 z 冲突。因此,线框看起来会好很多。
three.js r.126
为此,一种可能是使用 GLSL 片段着色器,当片段靠近三角形的一个边时,它会更改片段颜色。这是我正在使用的 GLSL 着色器。作为输入,它采用三角形中片段的重心坐标,以及为每条边选择是否应绘制的边掩码。 (rem:出于向后兼容性的原因,我不得不将它与兼容性配置文件一起使用,如果你不想这样做,它可以很容易地进行调整):
(片段来源)
#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;
}
为了避免克隆我的对象,我使用了这样的模式:
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 ];
然后将它应用到我的网格上:
var myMesh = THREE.SceneUtils.createMultiMaterialObject( mesh_geometry, meshmaterials );
scene.add( myMesh ) ;
希望对您有所帮助...
这也可以通过 WireframeGeometry 实现: https://threejs.org/docs/#api/en/geometries/WireframeGeometry。 (并给平面和线相同的位置,你也可以玩不透明度见文档)。
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);
};