Opengl es 重复纹理像点画

Opengl es 重复纹理像点画,opengl-es,textures,webgl,Opengl Es,Textures,Webgl,我用的是正交投影 我有两个三角形创建一个长四边形。 在这个四边形上,我放置了一个纹理,一路上重复他自己 世界缩放始终由用户更改,并相应地使四边形长度变短或变长。在着色器中计算高度,因此其大小始终相同(以像素为单位) 我的问题是,我希望纹理根据真实(像素大小)和四边形的长度重复。换句话说,纹理的大小(像素)将始终相同,并且它将通过或多或少地重复来填充四边形,这取决于四边形的长度 旋转很重要 比如说 我的质地很好 我已经添加到我的顶点-纹理坐标,以便现在将其复制20次 正如你在下面看到的 因为它被放

我用的是正交投影

我有两个三角形创建一个长四边形。 在这个四边形上,我放置了一个纹理,一路上重复他自己

世界缩放始终由用户更改,并相应地使四边形长度变短或变长。在着色器中计算高度,因此其大小始终相同(以像素为单位)

我的问题是,我希望纹理根据真实(像素大小)和四边形的长度重复。换句话说,纹理的大小(像素)将始终相同,并且它将通过或多或少地重复来填充四边形,这取决于四边形的长度

旋转很重要

比如说 我的质地很好

我已经添加到我的顶点-纹理坐标,以便现在将其复制20次 正如你在下面看到的 因为它被放大了太多,我们看到纹理被挤压了

现在我正在放大,纹理被拉伸。它总是重复20次。

我确信我必须在frag着色器中使用纹理坐标,但看不到解决方案。或许有更好的办法来解决我的问题

----加成----

解决方法是: 计算当前缩放中的重复S值(我正在添加顶点),并将贴图宽度(世界值)作为属性发送。每次画图时,我都会发送当前地图宽度作为计算比例的统一值


但是我对这个解决方案不满意。

一般的解决方案是包含纹理矩阵。因此,顶点着色器可能看起来像

attribute vec4 a_position;
attribute vec2 a_texcoord;

varying vec2 v_texcoord;

uniform mat4 u_matrix;
uniform mat4 u_texMatrix;

void main() {
  gl_Position = u_matrix * a_position;
  v_texcoord = (u_texMatrix * v_texcoord).xy;
}
现在,您可以设置纹理矩阵以根据需要缩放纹理坐标。如果整个纹理的纹理坐标从0到1,并且图案的宽度为16像素,那么如果要绘制100像素长的线,则需要100/16作为X比例

var pixelsLong = 100;
var pixelsTall = 8;
var textureWidth = 16;
var textureHeight = 16;

var xScale = pixelsLong / textureWidth;
var yScale = pixelsTall / textureHeight;

var texMatrix = [
  xScale, 0, 0, 0,
  0, yScale, 0, 0,
  0, 0, 1, 0,
  0, 0, 0, 1,
];

gl.uniformMatrix4fv(texMatrixLocation, false, texMatrix);

这似乎是可行的。因为使用的是矩阵,所以也可以轻松偏移或旋转纹理。请参见

确定,找到了在着色器中使用最小属性和最小代码的方法

做一次:

  • 计算每行的重复计数,因为我的世界和我的屏幕是1:1-我的世界是1像素<代码>线宽(单位为世界单位)/picWidth(单位为屏幕单位)
  • 保存为属性
每次抽签:

  • 计算比例-世界到屏幕-
    WorldWidth/ScreenWidth
  • 统一设置
  • 绘制缓冲区
在frag着色器中

  • 只需将此比例与“重复”属性相乘即可

效果很好,看起来也不错。也支持调整窗口大小。

问题是我有许多不同大小的线条和许多不同大小的纹理,都填充在一个缓冲区和一个纹理图集中。所以对我来说,使用制服不是最好的解决方案。我现在所做的是为每个顶点添加世界宽度和均匀的当前世界宽度,然后计算比例。但在我看来,一定有更好的办法。是否有类似于告诉OpenGL保存纹理原始大小之类的事情?您可以将纹理的大小作为统一大小传递。至于使用纹理图集,您仍然可以使用
fract
mod
重复。假设您添加了一个带有tx,ty,tw,th的vec4属性,其中tx,ty是纹理图集中图像左下像素的texcoord,tw,th是该图像的宽度和高度。在这种情况下,您可以将实际的texcoords作为单位坐标,并在片段着色器中展开它们,例如
vec2 uv=fract(v_texcoords*repeatAmount)*v_imageinfo.zw+v_imageinfo.xy
或类似的内容。我想我实际上必须实现它来看看它是否有效。问题是我不知道着色器中的
repeatAmount
,因为它与线的长度和世界的比例有关。好吧,我想我会坚持使用“一次计算重复量并设置为属性与世界宽度相结合,以便以后进行缩放”的解决方案,因为所有给定的解决方案都涉及添加更多属性,这是我试图避免的。另一个想法是使用
gl_FragCoord
和一些数学作为您的texcoord。如果你只使用
gl_FragCoord
和一些刻度,你会得到重复,但它会在屏幕空间中,不会随着线条移动。您可以添加一些线的起始位置和方向。我怀疑这会导致你想要的解决方案,只是把它扔出去。