首页 文章

多次重复纹理

提问于
浏览
2

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

enter image description here

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

enter image description here

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

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

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

变焦:1

enter image description here

缩放2

enter image description here

我的着色器:

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 回答

  • 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位于该框中,然后将纹理设置为与屏幕重复次数匹配的屏幕重复次数 . 这意味着它不需要百万分之一的精度 .

相关问题