多次重复纹理

问题描述 投票:0回答:1

我正在绘制填充有在着色器中重复的纹理的线条。如下图

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

© www.soinside.com 2019 - 2024. All rights reserved.