javascript - 当 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 对象本身中。可悲的是,它没有解决问题。
有没有人遇到过类似的问题并且知道如何解决这种不需要的行为?
解决方案
iOS 上的低级 PNG 读取代码将通过 CoreGraphics 并将每个 RGB 值与每个像素的 A 分量预乘,因此如果 A = 0,则每个 RGB 值将为零。您可以做的是加载 24 BPP 图像,因此 alpha 始终为 0xFF(也称为 255),但在处理 32 BPP 图像时,您不能在 iOS 下禁用此预乘步骤。
推荐阅读
- html - 如何使用 btn 调用我的 ajax 函数/获取
- javascript - 为什么这个导航中的 ul 不在前一个 div 之后?
- angular - mat sort 工作一次然后给出错误
- vue.js - Vue子组件未从父组件接收道具
- c++ - 使用 dart::ffi 从 Dart 包中调试 C++ 代码
- mysql - 从涉及条件的两列计算百分比
- c# - 我可以通过单击第一个孩子的按钮在同一个 MDI 窗口中显示第二个孩子吗?
- java - 通过 Exchange 使用 Javamail 发送电子邮件
- flutter - 如何在PDF中显示阿拉伯语
- javascript - 有没有办法简化 if 语句?