我正在使用javascript和three.js框架进行WebGL项目。为此,我正在使用GLSL编写自定义着色器,其中必须加载多个查找表。意味着我需要使用某些纹理的单个RGBA值进行一些计算,而不是显示它们。
这在我测试过的所有设备上都可以正常工作。但是,在iOS设备(如iPad)上,当其Alpha通道为0时,纹理的RGB值会自动设置为0。我不认为这是由于GLSL的texture2D函数引起的,而是与三个函数有关。 js在iOS上加载纹理。我为此使用了内置的TextureLoader:
var textureLoader = new THREE.TextureLoader();
var lutMap = textureLoader.load('path/to/lookup/table/img.png');
lutMap.minFilter = THREE.NearestFilter;
lutMap.magFilter = THREE.NearestFilter;
lutMap.generateMipmaps = false;
lutMap.type = THREE.UnsignedByteType;
lutMap.format = THREE.RGBAFormat;
出于测试目的,我创建了一个测试图像,该图像具有恒定的RGB值(255,0,0),并且alpha值从右上角到左下角不断减小,并且某些像素的alpha值为0:
加载纹理后,我检查了零阿尔法像素,并将其R值确实设置为0。我使用以下代码读取图像的数据:
function getImageData( image ) {
var canvas = document.createElement( 'canvas' );
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext( '2d' );
context.drawImage( image, 0, 0 );
return context.getImageData( 0, 0, image.width, image.height );
}
奇怪的是,我的Windows PC上也是如此,但着色器可以正常工作。因此,也许这仅仅是由于画布,与实际问题无关。但是,在iOS设备上,GLSL代码中的texture2D(...)查找确实针对这些像素实际上返回了(0,0,0,0)。 (请注意,我来自Java / C ++,并且对javascript还不是很熟悉!:)) 我还尝试在WebGLRenderer实例中以及在THREE.ShaderMaterial对象本身中将premultipliedAlpha标志设置为0。可悲的是,它没有解决问题。
有人遇到过类似的问题,并且知道如何解决这种不良行为吗?
答案 0 :(得分:2)
iOS上的低级PNG读取代码将通过CoreGraphics,并将每个RGB值乘以每个像素的A分量,因此,如果A = 0,则每个RGB值将为零。您可以做的是加载24 BPP图像,以使Alpha始终为0xFF(即255),但是在处理32 BPP图像时,无法在iOS下禁用此预乘步骤。