Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.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中将顶点位置读取为像素_Three.js_Glsl_Fragment Shader_Vertex Shader - Fatal编程技术网

在Three.js中将顶点位置读取为像素

在Three.js中将顶点位置读取为像素,three.js,glsl,fragment-shader,vertex-shader,Three.js,Glsl,Fragment Shader,Vertex Shader,在顶点着色器中置换顶点的场景中,如何在WebGL/Three.js中检索其变换位置 此处建议将位置写入纹理,然后读取像素,但结果值似乎不正确 在下面的示例中,位置在不进行任何变换的情况下传递给片段着色器: // vertex shader varying vec4 vOut; void main() { gl_Position = vec4(position, 1.0); vOut = vec4(position, 1.0); } // fragment shader var

在顶点着色器中置换顶点的场景中,如何在WebGL/Three.js中检索其变换位置

此处建议将位置写入纹理,然后读取像素,但结果值似乎不正确

在下面的示例中,位置在不进行任何变换的情况下传递给片段着色器:

// vertex shader
varying vec4 vOut;

void main() {
    gl_Position = vec4(position, 1.0);
    vOut = vec4(position, 1.0);
}

// fragment shader
varying vec4 vOut;

void main() {
    gl_FragColor = vOut;
}
然后读取输出纹理,我希望
像素[0].r
位置[0].x
相同,但事实并非如此

下面是一个显示问题的JSFIDLE:


我错过了什么?

解决了。问题中提到的JSFIDLE有很多问题

  • width*height
    应等于顶点计数。带有4×4段的
    PlaneBufferGeometry
    会产生25个顶点。三乘三得十六。始终(w+1)*(h+1)
  • 顶点着色器中的位置需要轻推
    1.0/宽度
  • 顶点着色器需要了解
    宽度
    高度
    ,它们可以作为一致性传入
  • 每个顶点都需要一个属性及其索引,以便可以正确映射
  • 每个位置应该是结果纹理中的一个像素
  • 生成的纹理应绘制为
    gl.POINTS
    ,且
    gl\u PointSize=1.0

工作JSFIDLE:

您没有正确地写出顶点

首先剪切几何体,因此顶点实际上在视图外结束,并且可以看到四边形的中间没有任何顶点

可以使用
uv
属性在视图中渲染整个四边形

gl_Position = vec4( uv * 2. - 1. , 0. ,1.);
缓冲区中的所有内容都表示四边形上的某个点。看起来比较棘手的是,渲染时,像素将在顶点旁边采样。在小提琴中,我对世界空间应用了一个偏移量,它在像素空间中的偏移量是多少,但它并没有真正起作用

它似乎适用于点的原因是,这可能是错误的:)如果只想变换顶点,则需要将它们正确存储在纹理中。您可以使用点进行此操作,但理想情况下,它们之间的间距不会太大。在您的场景中,它们将填充纹理的前几行(因为它比可能的大得多)


当您尝试将此应用于
PlaneGeometry
以外的其他对象时,可能会遇到问题。在这种情况下,必须解决这个问题

你的期望是错误的。当光栅化
gl\u位置
结果时,将剪裁网格。缓冲区中的像素[0]表示与实际坐标相差甚远的其他内容。顶点总是在某个X,Y(宽度==4/X==-2)处。在屏幕上,您看到网格在-1,-1处插值,因此您的-2,-2已离开屏幕。如果这里的宽度和高度大于2,则该数组中的最后一个像素应始终为1,1。我有点困惑为什么左下角的数字不同,但我认为这取决于分辨率和设置方式view@pailhead你确定网格被剪裁了吗?我还尝试将位置乘以模型视图和投影矩阵(第32行
gl_position=modelViewMatrix*projectionMatrix*vec4(position,1.0);
),得到的结果介于-2和2之间,但仍处于关闭状态。好吧,这样想。制作尺寸为1.1的飞机<代码>gl_位置将得到-0.5,0.5范围,您应该看到一个平面仅填充屏幕的中心。如果将其设置为大于2,2的任何值,将得到剪辑空间之外的顶点。我认为这个奇怪的数字来自于第一个像素处的插值,但我对小提琴有点困惑。嗯,我不认为这是最好的答案。对不起,我现在想用小提琴。你可以在没有点的情况下完成这项工作,但它可能更复杂。如果你像这样隔开你的点,你将需要一个非常大的纹理,如果你开始对它们进行分组,你就必须写出更多的逻辑。我添加了另一个答案,以澄清我在评论中的意思。为什么在屏幕截图中它是0.75而不是1是因为插值(我没有在小提琴中解决这个问题),但为什么它是1而不是2是因为剪辑(在小提琴/答案中解决)生成的纹理只是数据,不需要渲染到屏幕上。基于这两个答案中描述的技术,我使用了gl.POINTS:和。由于小提琴在128x128的视口中渲染5x5纹理,因此这些点看起来“间隔开”。这没有错,它工作得很好。谢谢你的帮助。