【发布时间】:2019-08-22 03:16:52
【问题描述】:
我正在开发一个使用 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 对象本身中设置。遗憾的是,它并没有解决问题。
有没有人遇到过类似的问题并且知道如何解决这种不受欢迎的行为?
【问题讨论】:
-
在 imgur 上发布您的问题图片?
-
我已经更新了主帖并添加了测试图片。
-
删除了我的答案,但简而言之,您不能使用
getImageData检查纹理的内容,因为画布使用预乘 alpha,因此通过画布 2D 复制纹理是有损的。至于您指出的实际问题,有一个 2 年前的错误 bugs.webkit.org/show_bug.cgi?id=165297,我指出 iOS 未能通过与此问题相关的 WebGL 一致性测试 khronos.org/registry/webgl/sdk/tests/conformance/textures/misc/…
标签: javascript ios three.js glsl webgl