我画的线条充满了我在着色器中重复的纹理。如下所示
这条线是单点 - 每个顶点都在我的顶点着色器中展开,并且无论我们有什么缩放,都会有一些相同的像素宽度计算。
比我创建我的三角形并在它们上面我在X轴上重复绘制纹理。所以线条的宽度始终是图像高度。
用户可以根据需要放大,随着变焦的变化,形状会变得越来越大。虽然纹理保存了它的大小,但意味着有更多的重复。
当用户非常放大时,我开始得到奇怪的结果,我想由于浮动溢出。
缩放:1
缩放2
我的着色器:
顶点着色器
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;
答案 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位于该框中,然后将纹理设置为与屏幕重复次数匹配的屏幕重复次数。这意味着它不需要百万分之一的精度。