多次重复纹理

时间:2015-01-13 11:02:15

标签: opengl textures webgl texture-mapping

我画的线条充满了我在着色器中重复的纹理。如下所示

enter image description here

这条线是单点 - 每个顶点都在我的顶点着色器中展开,并且无论我们有什么缩放,都会有一些相同的像素宽度计算。

enter image description here

比我创建我的三角形并在它们上面我在X轴上重复绘制纹理。所以线条的宽度始终是图像高度。

用户可以根据需要放大,随着变焦的变化,形状会变得越来越大。虽然纹理保存了它的大小,但意味着有更多的重复。

当用户非常放大时,我开始得到奇怪的结果,我想由于浮动溢出。

缩放:1

enter image description here

缩放2

enter image description here

我的着色器:

顶点着色器

uniform float factor;
attribute vec2 texCoords;
varying vec2 vTexCoords;
attribute vec4 texAtlas;
varying vec4 vTexAtlas;
uniform vec4 uPixelWolrdScale;
attribute vec2 outlineOffset;
 
void main() {
   vTexCoords = texCoords;
   vTexAtlas = texAtlas;
   gl_Position = LIGHTGLgl_ModelViewProjectionMatrix * (LIGHTGLgl_Vertex + uWorldOffset) + vec4((outlineOffset.xy) * uPixelWolrdScale.zw, 0,0);
}

uPixelWolrdScale是vec4,xy = worldScale.xy / ScreenSize.xy,zw = 2 / ScreenSize.xy。

我使用zw来取消行的宽度 以及用于在片段着色器中重复纹理的xy

precision highp float;
uniform float factor;
uniform vec4 color;
varying vec2 vTexCoords;
uniform vec4 uPixelWolrdScale;
uniform sampler2D sampler;
varying vec4 vTexAtlas;

void main() {

   // Here is the problem i guess
   vec2 vexelPos = fract(vec2((vTexCoords.s) / (uPixelWolrdScale.x * factor), vTexCoords.t));
   vexelPos = vTexAtlas.xy + vexelPos * vTexAtlas.zw;
   gl_FragColor = texture2D(sampler, vexelPos);
   gl_FragColor *= color;

}

vTexCoords.s是世界和屏幕相同单位时的重复次数。没有缩放。

(vTexCoords.s) / (uPixelWolrdScale.x * factor)溢出时,有没有其他方法可以重复纹理?

-----编辑------

尝试使用mod()代替fract()来改变我的方法,以实现重复。

在几轮之后,我设法做到这一点,作为我的问题的解决方案,但它仍然在一些变焦开始变得怪异。

基本思想是使用均匀值来重复纹理,并通过额外的计算变化 - 借助于纹理大小和模数。

在我的顶点着色器中

我添加了属性和变化

attribute vec4 startVertex;
varying float vVertex;
...
// Same calculation i did to the gl_Vertex I do here to the attribute
vec4 coordToRemove = LIGHTGLgl_ModelViewProjectionMatrix * (startVertex + uWorldOffset) + vec4((outlineOffset.xy) * uPixelWolrdScale.zw, 0,0);
vVertex = gl_Position.x - coordToRemove.x;

我希望我的变化从0开始并一直插入到第二个同质位置。所以我已将第一个顶点值添加为两个顶点的属性 - coordForVar - 所以当第一个顶点到达此处vVertex将为0.而第二个vVertex将是不同的。

在我的片段着色器中

varying float vVertex;
...
float hmgSize = 1. / 32.; // Getting the size in homogeneous - For now 32px, later uniform/attribute
vec2 vexelPos = vec2(mod(vVertex, hmgSize) / hmgSize, vTexCoords.t);
vexelPos = vTexAtlas.xy + vexelPos * vTexAtlas.zw;

1 个答案:

答案 0 :(得分:0)

在纹理坐标中使用fract和mod可以通过mipmapping做一些奇怪的事情,确保你的纹理使用最近过滤的min和mag过滤器并从那里开始


编辑:

无论纹理的内容是什么,texture2D只是在0和1之间查找纹理坐标。整数部分用于重复,但使用它会降低查找的精度。使用fract或mod来执行重复而不是整数部分可能会导致mipmap查找中的1px不连续;但如果你正在等待,那么无论如何你都会遇到这个问题。

所以你对纹章的查找你的纹理坐标应该是一个0的部分范围.1

例如,如果您有16x16图像,则范围为0.0625。例如X中的第三个纹理是0.125到0.1875。

您想要处理纹理坐标外的重复,然后将值转换为该范围。


编辑:

当放大而不是使你的几何形状长达百万单位,但只显示百万分之一;这只是导致精确打斗,使你的几何屏幕大小;那么你应该具备所需的所有精度。

例如,在对几何体x进行透视计算后,y坐标将位于屏幕空间中,并且仅显示在框-1,-1到1,1中的位置。此时,您可以交叉并修剪(或丢弃/忽略)几何体,使x,y位于该框中,然后将纹理设置为与屏幕重复次数匹配的屏幕重复次数。这意味着它不需要百万分之一的精度。