首页 > 解决方案 > 当 IOS 上的 ALPHA 为零时,Three.js 将纹理 RGB 值设置为零

问题描述

我正在使用 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:

测试图像

加载纹理后,我检查了零 alpha 像素,它们的 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 实例中将 premultipliedAlpha 标志设置为 0,但也在 THREE.ShaderMaterial 对象本身中。可悲的是,它没有解决问题。

有没有人遇到过类似的问题并且知道如何解决这种不需要的行为?

标签: javascriptiosthree.jsglslwebgl

解决方案


iOS 上的低级 PNG 读取代码将通过 CoreGraphics 并将每个 RGB 值与每个像素的 A 分量预乘,因此如果 A = 0,则每个 RGB 值将为零。您可以做的是加载 24 BPP 图像,因此 alpha 始终为 0xFF(也称为 255),但在处理 32 BPP 图像时,您不能在 iOS 下禁用此预乘步骤。


推荐阅读