javascript - 由于相邻 Sprite ,使用 ATLAS 通过 WebGL 在三 Angular 形上绘制 Sprite 会给出不正确的结果

标签 javascript opengl webgl shader

我有一个 2048x2048 的大图像,有 4096 个 32x32 Sprite 。也就是说,一个 64x64 的 32x32 图像表。我正在使用三 Angular 形来绘制它们。每个触发器都必须切割正确的纹理部分。它工作正常,除了在面部的边界,引擎正在访问表单上相邻 Sprite 的像素,从而导致噪音。注意兽人下方的像素:

notice the noise pixels below the character

它们来自工作表上它下方的 Sprite 。我正在使用以下计算来切割区域:

顶点着色器:

// position of each pixel of this face on texture
varying vec2 pix_pos;

// pos_in_sheet holds the position of the sprite on the sheet
// considering it is a 64x64 sheet, it is on the range vec2(0..63, 0..63)
vec2 pos_in_sheet = vec2(floor(mod(sprid,texture_cols)), floor(sprid/texture_cols));

// `vec2 vertex` indicates which of the 4 vertex in the quad this is:
// vec2(-1.0,-1.0)|vec2(-1.0,1.0)|vec2(1.0,-1.0)|vec2(1.0,1.0)

// inside main() I calculate the bounding quad that contains the sprite
pix_pos = vec3(
    ((pos_in_sheet.x+(vertex.x+1.0)/2.0)/64.0), //64 = rows in texture 
    ((pos_in_sheet.y+(-vertex.y+1.0)/2.0)/64.0));

这是片段着色器:

varying vec3 pix_pos;
uniform sampler2D sampler;
void main(void){
    vec4 col = texture2D(sampler,vec2(pix_pos.x,pix_pos.y));
    gl_FragColor = vec4(col.x,col.y,col.z,1.0);
}

我检查了我的计算结果,似乎没问题。那么是什么导致片段着色器访问其自身切割区域之外的 Sprite ?

最佳答案

这可能是由于线性插值而发生的,因为每个 texture2D() 都可以从纹理中获取 4 个像素,并根据这 4 个像素和一些权重返回结果。很难通过数学代码解决这个问题,因为浮点运算很难处理。

另一个可能产生此问题的是纹理 mipmap(如果您使用它们)。通常,较低的 mipmap 级别是使用某种过滤技术创建的,该技术会将 4 个像素混合为一个。具有高对比度的相邻像素会产生此类伪像。

解决方案是在 Sprite 之间添加一个填充。通常 2 到 4 个像素的空白空间(通常是黑色 rgba<0,0,0,0> )应该可以解决问题。所以每个 Sprite 都有 32x32 像素,而在图集中将占用 34x34 像素。 Sprite 周围的 2 像素边框必须是 Sprite 中最近像素的颜色(在您的情况下是透明的)。这减少了您可以放入图集中的 Sprite 数量

关于javascript - 由于相邻 Sprite ,使用 ATLAS 通过 WebGL 在三 Angular 形上绘制 Sprite 会给出不正确的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22240200/

相关文章:

javascript - 迭代无限嵌套的 json 结构

javascript - GatsbyJS + Netlify 表单不接收提交

javascript - 为分组条形图设置域时出错

c++ - Unicode 字符 "GREEK CAPITAL LETTER DELTA"在 C++ 和 GLStudio 中呈现为 "White vertical rectangle"

c++ - 什么是 Regal OpenGL?

javascript - JSON 文件的 WebGl 渲染非常慢,是因为 JSON 文件的大小吗?

html - 未初始化的 WebGL Canvas 的替代方案

html - 如何在 Sublime 中为 webgl/glsl 内联脚本标签获得语法高亮

Javascript 播放器不适用于 Opera/Chrome

c++ - # include <GL/glut.h> 在 Xcode 中找不到文件