Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Three.js 如何获取三个.js线段以仅渲染可见线_Three.js - Fatal编程技术网

Three.js 如何获取三个.js线段以仅渲染可见线

Three.js 如何获取三个.js线段以仅渲染可见线,three.js,Three.js,我正试图让Three.js只渲染几何体的正面轮廓。我想要实现的是尽可能接近这一点: 使用boxgeometry我接近了我想要的,但是在圆柱体上使用线段几何体会产生垂直线,这是有意义的。你能想出一种方法,我只能画出“可见”的轮廓吗 以下是我迄今为止所做的尝试: let coloredMaterial = new THREE.MeshBasicMaterial({ color: 0xFFD033, polygonOffset: true, polygonOffsetFactor: 1

我正试图让Three.js只渲染几何体的
正面
轮廓。我想要实现的是尽可能接近这一点:

使用
boxgeometry
我接近了我想要的,但是在
圆柱体上使用
线段
几何体
会产生垂直线,这是有意义的。你能想出一种方法,我只能画出“可见”的轮廓吗

以下是我迄今为止所做的尝试:

let coloredMaterial = new THREE.MeshBasicMaterial({
  color: 0xFFD033,
  polygonOffset: true,
  polygonOffsetFactor: 1,
  polygonOffsetUnits: 1
});

let brick = new THREE.Mesh(geometry, coloredMaterial);

let edges = new THREE.EdgesGeometry(brick.geometry);
var outline = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({
  color: 0x1B3740,
  linewidth: 1.5
}));

let knobGeometry = new THREE.CylinderGeometry(7, 7, 7, 20);
let knob = new THREE.Mesh(knobGeometry, coloredMaterial);

let knobOutline = new THREE.LineSegments(
  new THREE.EdgesGeometry(knob.geometry),
  new THREE.LineBasicMaterial({
    color: 0x1B3740,
    linewidth: 1.5
  })
);

看起来您可能可以复制

它不仅使用
MeshToonMaterial
作为纯色,还使用
/jsm/effects/OutlineEffect.js
中的
OutlineEffect
。你可以看到,相关的要点是:

import { OutlineEffect } from './jsm/effects/OutlineEffect.js';

// Pass renderer to effect constructor
renderer = new THREE.WebGLRenderer();
effect = new OutlineEffect( renderer );

// In the render loop:
effect.render( scene, camera );


这个答案基于@WestLangley对注释的建议,特别是
LDrawLoader
在条件行上使用的模型


控制点模型 条件线背后的思想是使用控制点来确定应该绘制哪些线

如果两个控制点位于通过将直线外推到无穷远而创建的剪裁平面的同一侧,则绘制该直线。否则就被丢弃了

让我们考虑2行<强>(e,b)< /强>和<强>(f,c)< /强>:

对于(E,B),让我们使用(A)(C)作为控制点。我们可以清楚地看到,两个控制点位于由(E,B)创建的平面的同一侧。因此,这条线被画出来了

对于(F,C),让我们使用(B)(D)作为控制点。现在,两个控制点位于飞机的不同侧面。因此,这一行被丢弃


由于这个模型的实现可能相当长,我已经建立了一个可以作为参考的模型。它并不完美,但我相信它应该足够有用

我们不能使用
CylinderBufferGeometry
作为边几何体的基础,因为它使用索引缓冲区几何体。由于控制点由每条线决定,而不是由顶点决定,所以我们不使用索引

对于没有条件的边,我们可以对两个控件使用相同的点,例如顶部和底部圆

需要注意的一件重要事情是,使用此模型,我们无法确定一条线是否会被几何体(您所描述的“正面”)遮挡。所以,我用实际的旋钮挡住了后面的线条


边缘轮廓
正文{边距:0;位置:固定;}
画布{宽度:100%;高度:100%;显示:块;}
var conditionalLineVertShader=/*glsl*/`
属性vec3-control0;
属性向量3控制1;
属性向量3方向;
可变浮标;
#包括
#包括
#包括
#包括
#包括
void main(){
#包括
vec4 mvPosition=modelViewMatrix*vec4(位置,1.0);
gl_位置=投影矩阵*mvPosition;
//将线段端点和控制点变换为摄影机片段空间
vec4 c0=投影矩阵*modelViewMatrix*vec4(control0,1.0);
vec4 c1=投影矩阵*模型视图矩阵*vec4(控制1,1.0);
vec4 p0=投影矩阵*模型视图矩阵*vec4(位置,1.0);
vec4 p1=投影矩阵*modelViewMatrix*vec4(位置+方向,1.0);
c0.xy/=c0.w;
c1.xy/=c1.w;
p0.xy/=p0.w;
p1.xy/=p1.w;
//获取线段的方向和正交向量
vec2-dir=p1.xy-p0.xy;
vec2 norm=vec2(-dir.y,dir.x);
//从直线获取控制点方向
vec2 c0dir=c0.xy-p1.xy;
vec2 c1dir=c1.xy-p1.xy;
//如果指向控制点的向量指向不同的方向
//从线段开始,则不应绘制直线。
浮点d0=点(标准化(norm),标准化(c0dir));
浮点d1=点(标准化(norm),标准化(c1dir));
丢弃标志=浮动(符号(d0)!=符号(d1));
#包括
#包括
#包括
}
`;
var conditionalLineFragShader=/*glsl*/`
均匀vec3扩散;
可变浮标;
#包括
#包括
#包括
#包括
#包括
void main(){
如果(丢弃标志>0.5)丢弃;
#包括
vec3-outgoingLight=vec3(0.0);
vec4漫反射颜色=vec4(漫反射,1.0);
#包括
#包括
outgoingLight=diffuseColor.rgb;//简单着色器
gl_FragColor=vec4(向外发光,漫反射色.a);
#包括
#包括
#包括
#包括
}
`;
var renderer=new THREE.WebGLRenderer({antialas:true});
renderer.setSize(window.innerWidth、window.innerHeight);
document.body.appendChild(renderer.doElement);
var scene=new THREE.scene();
scene.background=新的三种颜色(0xffffff);
var摄像机=新的三透视摄像机(75,window.innerWidth/window.innerHeight,0.11000);
var controls=新的三个.OrbitControls(camera、renderer.doElement);
摄像机。位置。设置(10,13,10);
controls.target.set(0,0,0);
//立方体
var cubeGeometry=新的三点几何结构(10,5,10);
var cubeMaterial=新的三个网格基本材质({
颜色:0xFFD033,
多克隆补偿:对,
多克隆偏移因子:1,
多边形偏移单位:1
} );
var cube=新的三网格(立方计量法、立方材料);
场景.添加(立方体);
var edgesGeometry=新的三边几何(立方几何);
var edgesCube=新的三个.LineSegments(边几何体,新的三个.LineBasicMaterial({颜色:0x1B3740,线宽:1.5}));
边缘立方位置y+=0.6;
场景。添加(EdgeCube);
//旋钮
var knobGeometry=新的三圆柱几何(1.4,1.4,0.8,30);
var旋钮=新的三网格(旋钮几何、立方材料);
旋钮位置设置(-2.5,2.9,-2.5);
场景。添加(旋钮);
var旋钮=新的三网格(旋钮几何、立方材料);
旋钮位置设置(2.5,2.9,2.5);
场景。添加(旋钮);
var旋钮=新的三网格(knobGeo