首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在WGSL着色器中重复纹理?

如何在WGSL着色器中重复纹理?
EN

Stack Overflow用户
提问于 2019-12-26 00:01:27
回答 1查看 1.3K关注 0票数 0

我在着色器程序中使用非2次方纹理。我正在尝试实现带有重复的滚动文本。滚动效果很好,但当我试图通过顶点着色器中的逻辑让纹理重复时,我突然得到了一个四边形,整个范围内只有一组拉伸的像素。我认为这是由于过滤算法造成的。

作为背景,我想在vertex程序中生成纹理坐标,因为我会在片段程序中对它们进行进一步的扭曲,并且如果片段程序的输入已经正确地考虑到滚动,那么管理起来就更容易了。请注意,我在相应的片段着色器中访问textureCoordinateVarying

这是可行的,尽管在文本滚动时没有重复的纹理:

代码语言:javascript
复制
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
    );
}

另一方面,这给了我一个拉伸的图像,如您所见:

代码语言:javascript
复制
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
    );

}

有什么办法可以解决这个问题吗?

谢谢!

EN

回答 1

Stack Overflow用户

发布于 2019-12-26 07:22:09

需要在碎片着色器而不是顶点着色器中执行重复数学运算。

代码语言:javascript
复制
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);
代码语言:javascript
复制
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
<canvas></canvas>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59479953

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档