Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/397.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
Javascript 相对于相机的3.js均匀虚线_Javascript_Three.js_Glsl_Shader_Line - Fatal编程技术网

Javascript 相对于相机的3.js均匀虚线

Javascript 相对于相机的3.js均匀虚线,javascript,three.js,glsl,shader,line,Javascript,Three.js,Glsl,Shader,Line,我正在使用three.js在3D中显示几何图形 当您(手动)将隐藏线绘制为虚线时,“虚线”对所有隐藏线都是规则的。这意味着平行于摄影机平面的线或(几乎)垂直于摄影机平面的线应该具有相同的长度和间隙 但这似乎不适用于LineDashedMaterial 对于附带的示例,我使用以下(非常)基本的代码: var scene=new THREE.scene(); var摄像机=新的三透视摄像机(75,window.innerWidth/window.innerHeight,0.11000); var

我正在使用three.js在3D中显示几何图形

当您(手动)将隐藏线绘制为虚线时,“虚线”对所有隐藏线都是规则的。这意味着平行于摄影机平面的线或(几乎)垂直于摄影机平面的线应该具有相同的长度和间隙

但这似乎不适用于LineDashedMaterial

对于附带的示例,我使用以下(非常)基本的代码:

var scene=new THREE.scene();
var摄像机=新的三透视摄像机(75,window.innerWidth/window.innerHeight,0.11000);
var renderer=new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth、window.innerHeight);
document.body.appendChild(renderer.doElement);
var geometry=新的3.BoxGeometry(2,2,2);
var LINES\u虚线=新的三条线段(
新三边几何(几何),
新的三线制材料({
线宽:2,
颜色:0x000000,
dashSize:0.2,
虚张声势:0.1,
深度测试:假,
polygonOffset:true,polygonOffsetFactor:1,polygonOffsetUnits:1
})
);
虚线。计算线距离();
场景。添加(虚线);
scene.background=新的三种颜色(0xffffff);
摄像机位置z=5;
var animate=函数(){
请求动画帧(动画);
虚线旋转x+=0.01;
虚线_.旋转.y+=0.01;
渲染器。渲染(场景、摄影机);
};
制作动画()
body{margin:0;}
画布{宽度:100%;高度:100%}

这是一项艰巨的任务。似乎不支持这一点。
但是可以编写着色器并使用

诀窍是知道片段着色器中直线的起点。通常,通过使用插值限定符,这很容易实现。
遗憾的是,他不支持这一点。因此,我们必须使用/
在OpenGL ES中存在扩展。不幸的是,似乎没有相应的WebGL扩展。(见附件)

因此,让我们用WebGL2上下文创建一个cerate。见:

var canvas=document.createElement('canvas');
var context=canvas.getContext('webgl2');
var renderer=new THREE.WebGLRenderer({canvas:canvas,context:context});
顶点着色器必须将规格化设备坐标传递给片段着色器。一次使用默认插值,一次不使用(
flat
)插值。这导致在片段阴影中,第一个输入参数包含直线上实际位置的NDC坐标,然后是直线起点的NDC坐标

flat out vec3 startPos;
输出vec3垂直位;
void main(){
vec4 pos=投影矩阵*modelViewMatrix*vec4(位置,1.0);
gl_位置=位置;
垂直位置=位置xyz/位置w;
startPos=vertPos;
}
此外,对于不同的输入,片段着色器具有统一的变量<代码>u_分辨率
包含视口的宽度和高度
u_dashSize
包含行的长度和
u_gapSize
像素间距的长度

因此,可以计算从起点到实际碎片的直线长度:

vec2 dir=(vertPos.xy startPos.xy)*u_分辨率/2.0;
浮动距离=长度(方向);
gab上的碎片可以通过命令丢弃

if(fract(dist/(u_dashSize+u_gapSize))>u_dashSize/(u_dashSize+u_gapSize))
丢弃;
片段着色器:

高精度浮点;
vec3 startPos中的平面;
在vec3垂直位;
均匀的vec3u_颜色;
均匀vec2u_分辨率;
均匀浮动u_尺寸;
均匀浮球;
void main(){
vec2 dir=(顶点xy起始点xy)*u_分辨率/2.0;
浮动距离=长度(方向);
if(分形(dist/(u_dashSize+u_gapSize))>u_dashSize/(u_dashSize+u_gapSize))
丢弃;
gl_FragColor=vec4(u_color.rgb,1.0);
}
设置服装和制服:

var={
u_分辨率:{type:'v2',值:{x:vpSize[0],y:vpSize[1]},
u_dashSize:{type:'f',value:10.0},
u_gapSize:{type:'f',value:5.0},
u_颜色:{type:'v3',值:{x:0.0,y:0.0,z:0.0}
};
var material=new THREE.ShaderMaterial({
制服:制服,
vertexShader:document.getElementById('vertex-shader').textContent,
fragmentShader:document.getElementById('fragment-shader').textContent
});
var LINES\u虚线=新的三条线段(
新三边几何(几何),
材料);
注意,如果画布的分辨率发生变化,则必须设置
u\u分辨率
的值:

e、 g

LINES\u虚线.material.uniforms.u分辨率.value.x=window.innerWidth;
虚线。材质。制服。分辨率。值。y=窗口。内部高度;
我将这些建议应用于您的原始代码。请参见预览和示例:

var scene=new THREE.scene();
var摄像机=新的三透视摄像机(60,window.innerWidth/window.innerHeight,0.11000);
var canvas=document.createElement('canvas');
var context=canvas.getContext('webgl2');
var renderer=new THREE.WebGLRenderer({canvas:canvas,context:context});
var vpSize=[window.innerWidth,window.innerHeight];
renderer.setSize(window.innerWidth、window.innerHeight);
document.body.appendChild(renderer.doElement);
var geometry=新的3.BoxGeometry(2,2,2);
变量={
u_分辨率:{type:'v2',值:{x:vpSize[0],y:vpSize[1]},
u_dashSize:{type:'f',value:10.0},
u_gapSize:{type:'f',value:5.0},
u_颜色:{type:'v3',值:{x:0.0,y:0.0,z:0.0}
};
var material=new THREE.ShaderMaterial({
制服:制服,
vertexShader:document.getElementById('vertex-shader').textContent,
fragmentShader:document.getElementById('fragment-shader').textContent
});
var LINES\u虚线=新的三条线段(
新三边几何(geome)