Javascript WebGL纹理调整意外输出的大小

Javascript WebGL纹理调整意外输出的大小,javascript,opengl-es,textures,webgl,texture-mapping,Javascript,Opengl Es,Textures,Webgl,Texture Mapping,在WebGL中使用纹理时,有时我需要使它们比原来更大。当我这样做时,它会使纹理看起来不同,尤其是在较浅的背景上 我有以下图像(256 x 256): 在WebGL中渲染时,它略大于原始图像。以下是图像在两种不同背景上的显示方式: 如您所见,图像正确地显示在深色背景上,但在浅色背景上时,具有白色轮廓 我的设置代码: gl.clearColor(0x22 / 0xFF, 0x22 / 0xFF, 0x22 / 0xFF, 1); // set background color gl.enable

在WebGL中使用纹理时,有时我需要使它们比原来更大。当我这样做时,它会使纹理看起来不同,尤其是在较浅的背景上

我有以下图像(256 x 256):

在WebGL中渲染时,它略大于原始图像。以下是图像在两种不同背景上的显示方式:

如您所见,图像正确地显示在深色背景上,但在浅色背景上时,具有白色轮廓

我的设置代码:

gl.clearColor(0x22 / 0xFF, 0x22 / 0xFF, 0x22 / 0xFF, 1); // set background color
gl.enable(gl.BLEND); // enable transparency
gl.disable(gl.DEPTH_TEST); // disable depth test (causes problems with alpha if enabled)
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); //set up blending
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); //clear the gl canvas
gl.viewport(0, 0, canvas.width, canvas.height); //set the viewport
这是每次加载纹理时调用的代码:

function handleTextureLoaded(image, texture) {
  gl.bindTexture(gl.TEXTURE_2D, texture);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
  gl.generateMipmap(gl.TEXTURE_2D);
  gl.bindTexture(gl.TEXTURE_2D, null);
  loadCount++;
}
是什么导致大纲出现,如何修复它

注意:当我将原始图像放在这两个相同的背景上时,即使调整图像大小,也不会出现此问题

我尝试在WebGL上下文中禁用alpha(如@zfedoran所述):

此时,图像周围会出现一个小的空白边框,如下图所示(放大):


您是否尝试过在WebGL上下文中禁用alpha

var gl = this.canvas.getContext('webgl', {antialias: false, alpha: false }) 
      || this.canvas.getContext('experimental-webgl', {antialias: false, alpha: false });

在@zfedoran提到的画布的alpha顶部,如何制作原始图像

我认为问题如下

假设您有这样的抗锯齿边。这个像素是什么颜色的

假设主颜色(右下角像素的颜色)为1,0,0(纯红色)。理想情况下,箭头指向的像素为(1,0,0.5)。换句话说,纯红色的alpha值为0.5。但是,根据创建图像以生成抗锯齿像素的方式,它可能已与旁边的纯透明像素混合,因此不再是纯红色。那些纯透明像素很可能是(0,0,0,0)透明的黑色

即使您的绘图程序正确地处理了此问题,GL也可能不会。当你绘制一个纹理过滤打开的图像时(
gl.LINEAR
等),gl将平均彼此相邻的像素,其中一些像素是透明的黑色的。黑与红的混合产生深红色。因此,你得到了一个黑暗的边界

“严格使用”;
函数main(){
var平面顶点=[
-1, -1,
1, -1,
-1,  1,
1,  1,
];
变量texcoords=[
0, 1,
1, 1,
0, 0,
1, 0,
];
风险值指数=[
0, 1, 2,
2, 1, 3,
];
var canvas=document.getElementById(“c”);
var gl=canvas.getContext(“webgl”,{alpha:false});
var程序={}
programs.normalProgram=twgl.createprogrammfromscripts(
gl、[“2d顶点着色器”、“2d片段着色器”]、[“a_位置”、“a_纹理坐标”];
programs.preMultiplyAlphaProgram=twgl.createprogrammfromscripts(
gl、[“2d顶点着色器”、“pre-2d-fragment-shader”]、[“a_位置”、“a_texcoord”];
var positionLoc=0;//在createProgramsFromScripts中分配
var texcoordLoc=1;//在createProgramsFromScripts中分配
var buffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY\u BUFFER,BUFFER);
缓冲数据(
gl.ARRAY\u缓冲区,
新Float32Array(平面顶点),
gl.静态(U形图);
gl.EnableVertexAttributeArray(positionLoc);
总账VertexAttribute指针(位置LOC,2,总账浮点,false,0,0);
var buffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY\u BUFFER,BUFFER);
缓冲数据(
gl.ARRAY\u缓冲区,
新Float32Array(texcoords),
gl.静态(U形图);
gl.EnableVertexAttributeArray(texcoordLoc);
gl.VertexAttributePointer(texcoordLoc,2,gl.FLOAT,false,0,0);
var buffer=gl.createBuffer();
gl.bindBuffer(gl.ELEMENT\u ARRAY\u BUFFER,BUFFER);
缓冲数据(
gl.ELEMENT\u数组\u缓冲区,
新UINT16阵列(索引),
gl.静态(U形图);
var img=新图像();
img.onload=创建纹理;
img.src=document.getElementById(“i”).text;
函数createTexture(){
var tex=gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D,tex);
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,img);
gl.generateMipmap(gl.TEXTURE_2D);//假设为2的幂
返回tex;
}
var={};
函数createTextures(){
像素库(gl.UNPACK\u PREMULTIPLY\u ALPHA\u WEBGL,false);
textures.UnpremultipleDalphaTexture=createTexture();
gl.pixelStorei(gl.UNPACK\u PREMULTIPLY\u ALPHA\u WEBGL,真);
textures.premultipledalphatexture=createTexture();
document.body.appendChild(document.createElement(“hr”));
插入(“原始图像”);
文件.正文.附件(img);
render();
}
函数插入(文本){
var pre=document.createElement(“pre”);
pre.appendChild(document.createTextNode(text));
文件.正文.附件(pre);
};
函数grabImage(prg、blend、texName){
document.body.appendChild(document.createElement(“hr”));
插入(
“总账使用程序(“+prg+”)\n”+
“gl.blendFunc(gl.“+blend.src+”,gl.“+blend.dst+”)\n”+
“gl.bindTexture(gl.TEXTURE2D,“+texName+”)”;
var img=新图像();
img.src=gl.canvas.toDataURL();
文件.正文.附件(img);
};
函数render(){
总账启用(总账混合);
对象。键(程序)。forEach(函数(p,pndx){
总账使用程序(程序[p]);
[
{src:“src_ALPHA”,dst:“一减去src_ALPHA”},
{src:“一”,dst:“一减去”src:“阿尔法”},
].forEach(函数(b,bndx){
德国劳埃德金融公司(德国劳埃德[b.src],德国劳埃德金融公司[b.dst]);
Object.keys(纹理).forEach(函数(texName,tndx){
gl.bindTexture(gl.TEXTURE_2D,纹理[texName]);
gl.clearColor(0x3D/0xFF,0x87/0xFF,0xEA/0xFF,1);
总账清除(总账颜色缓冲位);
总帐付款人(总帐三角形,6,总帐无符号_短,0);
grabImage(p、b、texName);
});
});
});
}
}
main()
<代码
var gl = this.canvas.getContext('webgl', {antialias: false, alpha: false }) 
      || this.canvas.getContext('experimental-webgl', {antialias: false, alpha: false });