在Three.js中使用FBO/RenderTarget的GLSL uv查找和精度
我的应用程序是用Javascript+Three.js/WebGL+GLSL编写的。我有200条曲线,每一条由85个点组成。要设置曲线的动画,我添加一个新点并删除最后一个点。 因此,我制作了一个在Three.js中使用FBO/RenderTarget的GLSL uv查找和精度,three.js,glsl,webgl,shader,gpgpu,Three.js,Glsl,Webgl,Shader,Gpgpu,我的应用程序是用Javascript+Three.js/WebGL+GLSL编写的。我有200条曲线,每一条由85个点组成。要设置曲线的动画,我添加一个新点并删除最后一个点。 因此,我制作了一个positions着色器,用于将新位置存储到纹理(1)上,并制作了lines着色器,用于将所有曲线的位置写入另一个纹理(2)。 目标是使用纹理作为数组:我知道一行的第一个和最后一个索引,因此我需要将这些索引转换为uv坐标。 我用来调试FBO 1) 此1D纹理包含每条曲线的新点(总共200个):positi
positions
着色器,用于将新位置存储到纹理(1)上,并制作了lines
着色器,用于将所有曲线的位置写入另一个纹理(2)。
目标是使用纹理作为数组:我知道一行的第一个和最后一个索引,因此我需要将这些索引转换为uv
坐标。
我用来调试FBO
1) 此1D纹理包含每条曲线的新点(总共200个):positionTexture
2) 这些是200条曲线,以及它们的所有点,一个接一个:linesTexture
黑色部分是这里的错误。那些织物不应该是黑色的。
工作原理:在每一帧,着色器在positionTexture
中查找每一行的新点,并相应地更新linesTextures
,使用for
循环,如下所示:
#define LINES_COUNT = 200
#define LINE_POINTS = 85 // with 100 it works!!!
// Then in main()
vec2 uv = gl_FragCoord.xy / resolution.xy;
for (float i = 0.0; i < LINES_COUNT; i += 1.0) {
float startIdx = i * LINE_POINTS; // line start index
float endIdx = beginIdx + LINE_POINTS - 1.0; // line end index
vec2 lastCell = getUVfromIndex(endIdx); // last uv coordinate reserved for current line
if (match(lastCell, uv)) {
pos = texture2D( positionTexture, vec2((i / LINES_COUNT) + minFloat, 0.0)).xyz;
} else if (index >= startIdx && index < endIdx) {
pos = texture2D( lineTexture, getNextUV(uv) ).xyz;
}
}
但它比这更复杂。例如match()
:
有人能解释一下通过从
索引值获取uv
坐标来查找纹理中的值的最有效方法是什么吗?纹理坐标从像素的边缘开始,而不是从中心开始,因此计算uv坐标的公式需要
u = (xPixelCoord + .5) / widthOfTextureInPixels;
v = (yPixelCoord + .5) / heightOfTextureInPixels;
所以我猜您希望getUVfromIndex
成为
uniform vec2 sizeOfTexture; // allow texture to be any size
vec2 getUVfromIndex(float index) {
float widthOfTexture = sizeOfTexture.x;
float col = mod(index, widthOfTexture);
float row = floor(index / widthOfTexture);
return (vec2(col, row) + .5) / sizeOfTexture;
}
或者,您可能需要伪造索引
uniform vec2 sizeOfTexture; // allow texture to be any size
vec2 getUVfromIndex(float index) {
float fudgedIndex = index + 0.1;
float widthOfTexture = sizeOfTexture.x;
float col = mod(fudgedIndex, widthOfTexture);
float row = floor(fudgedIndex / widthOfTexture);
return (vec2(col, row) + .5) / sizeOfTexture;
}
如果您在WebGL2中,可以使用texelFetch
,它采用整数像素坐标从纹理中获取值纹理坐标从像素的边缘开始,而不是从中心开始,因此计算UV坐标的公式需要
u = (xPixelCoord + .5) / widthOfTextureInPixels;
v = (yPixelCoord + .5) / heightOfTextureInPixels;
所以我猜您希望getUVfromIndex
成为
uniform vec2 sizeOfTexture; // allow texture to be any size
vec2 getUVfromIndex(float index) {
float widthOfTexture = sizeOfTexture.x;
float col = mod(index, widthOfTexture);
float row = floor(index / widthOfTexture);
return (vec2(col, row) + .5) / sizeOfTexture;
}
或者,您可能需要伪造索引
uniform vec2 sizeOfTexture; // allow texture to be any size
vec2 getUVfromIndex(float index) {
float fudgedIndex = index + 0.1;
float widthOfTexture = sizeOfTexture.x;
float col = mod(fudgedIndex, widthOfTexture);
float row = floor(fudgedIndex / widthOfTexture);
return (vec2(col, row) + .5) / sizeOfTexture;
}
如果您在WebGL2中,您可以使用texelFetch
,它采用整数像素坐标从纹理中获取值代码>不应该是mod(索引、文本宽度)代码>?非常感谢您的回答,它立即解决了问题!我将进行更多测试,看看其他查找函数是否正常。你认为我在问题中发布的match()
函数有意义吗?因为unit
是1/sizeOfTexture.x
:所以它检查uv.x
是否在texel的开始和结束之间,但我认为这很糟糕。如何测试给定uv坐标(来自索引值)与当前uv的“匹配”?假设您使用getUVfromIndex
函数来获取uv坐标,您将x和uv混淆了。我们需要测试的是uv
(当前片段)是否在这两个值之间。它起作用了。也许反过来更清楚:uv.x>=x&&uv.x
。但都是一样的。我想知道是否有更好的方法,但你似乎没有发现方法是错误的。就像我提到的,大脑放屁。由于某种原因,我的大脑将符号+单位
保留在模的另一边(索引%widthOfTexture)代码>不应该是mod(索引、文本宽度)代码>?非常感谢您的回答,它立即解决了问题!我将进行更多测试,看看其他查找函数是否正常。你认为我在问题中发布的match()
函数有意义吗?因为unit
是1/sizeOfTexture.x
:所以它检查uv.x
是否在texel的开始和结束之间,但我认为这很糟糕。如何测试给定uv坐标(来自索引值)与当前uv的“匹配”?假设您使用getUVfromIndex
函数来获取uv坐标,您将x和uv混淆了。我们需要测试的是uv
(当前片段)是否在这两个值之间。它起作用了。也许反过来更清楚:uv.x>=x&&uv.x
。但都是一样的。我想知道是否有更好的方法,但你似乎没有发现方法是错误的。就像我提到的,大脑放屁。由于某种原因,我的大脑在另一边保留着符号+单位