我画的线条充满了我在着色器中重复的纹理 . 如下图所示
这条线是单点 - 每个顶点我在我的顶点着色器中展开,并且无论我们是什么缩放,一些计算始终都是相同的像素宽度 .
比我正在创建我的三角形,在我们正在X轴上重复绘制我的纹理 . 所以线条的宽度始终是图像高度 .
用户可以根据需要放大,随着变焦的变化,形状变得越来越大 . 虽然纹理节省了它的大小,但意味着有更多的重复 .
当用户非常放大我开始得到奇怪的结果时,我想由于浮动溢出 .
变焦:1
缩放2
我的着色器:
Vertex Shader
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)
溢出时,还有另一种重复纹理的方法吗?
-----EDITED ------
试图通过使用 mod()
而不是 fract()
来改变我的方法来实现重复 .
经过几轮我已经设法做到这一点,作为我的问题的解决方案,但它仍然在一些变焦开始变得怪异 .
基本思想是使用均匀值来重复纹理,并通过额外的计算变化 - 借助于纹理大小和模数 .
In my vertex shader
我添加了属性和变化
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
将是差异 .
In my fragment shader
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 回答
在纹理坐标中使用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位于该框中,然后将纹理设置为与屏幕重复次数匹配的屏幕重复次数 . 这意味着它不需要百万分之一的精度 .