我在着色器程序中使用非2次方纹理。我正在尝试实现带有重复的滚动文本。滚动效果很好,但当我试图通过顶点着色器中的逻辑让纹理重复时,我突然得到了一个四边形,整个范围内只有一组拉伸的像素。我认为这是由于过滤算法造成的。
作为背景,我想在vertex程序中生成纹理坐标,因为我会在片段程序中对它们进行进一步的扭曲,并且如果片段程序的输入已经正确地考虑到滚动,那么管理起来就更容易了。请注意,我在相应的片段着色器中访问textureCoordinateVarying
这是可行的,尽管在文本滚动时没有重复的纹理:
attribute vec4 position;
attribute vec2 texcoord;
uniform mat3 matrixUniform;
uniform float horizontalTextureOffsetUniform;
varying vec2 textureCoordinateVarying;
void main() {
gl_Position = vec4((matrixUniform * vec3(position.x, position.y, 1)).xy, 0, 1);
textureCoordinateVarying = vec2(
//I get a nice scrolling animation by changing the offset here, but the texture doesn't repeat, since it is NPO2 and therefore doesn't have repeating enabled
texcoord.x + horizontalTextureOffsetUniform,
texcoord.y
);
}

另一方面,这给了我一个拉伸的图像,如您所见:
attribute vec4 position;
attribute vec2 texcoord;
uniform mat3 matrixUniform;
uniform float horizontalTextureOffsetUniform;
varying vec2 textureCoordinateVarying;
void main() {
gl_Position = vec4((matrixUniform * vec3(position.x, position.y, 1)).xy, 0, 1);
textureCoordinateVarying = vec2(
\\Note how I am using fract here, which should make the texture repeat at the 1.0 texture boundary, but instead renders a blurry stretched texture
fract(texcoord.x + horizontalTextureOffsetUniform),
texcoord.y
);
}

有什么办法可以解决这个问题吗?
谢谢!
发布于 2019-12-26 07:22:09
需要在碎片着色器而不是顶点着色器中执行重复数学运算。
const gl = document.querySelector('canvas').getContext('webgl');
const vs = `
void main() {
gl_Position = vec4(0,0,0,1);
gl_PointSize = 100.0;
}`;
const fs = `
precision highp float;
uniform sampler2D tex;
uniform vec2 offset;
void main() {
gl_FragColor = texture2D(tex, fract(gl_PointCoord.xy + offset));
}`;
// compile shaders, link program, look up locations
const programInfo = twgl.createProgramInfo(gl, [vs, fs]);
// calls gl.createTexture, gl.texImage2D, gl.texParameteri
const tex = twgl.createTexture(gl, {
src: 'https://i.imgur.com/v38pV.jpg'
});
function render(time) {
time *= 0.001;
gl.useProgram(programInfo.program);
// calls gl.activeTexture, gl.bindTexture, gl.uniform
twgl.setUniformsAndBindTextures(programInfo, {
tex,
offset: [time, time * 0.1],
});
gl.drawArrays(gl.POINTS, 0, 1);
requestAnimationFrame(render);
}
requestAnimationFrame(render);<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
<canvas></canvas>
https://stackoverflow.com/questions/59479953
复制相似问题