Working on a WebGL project utilizing javascript and the three.js framework, I am in the process of crafting a custom shader with GLSL. In this shader, I must load various lookup tables to utilize individual RGBA values for calculations rather than rendering them.
While the shader functions properly on all tested devices, an issue arises when using iOS devices (such as an iPad), where the RGB values of a texture are automatically set to 0 when the alpha channel is 0. This behavior does not seem to stem from GLSL's texture2D function but rather how three.js handles texture loading on iOS. The built-in TextureLoader is used for this purpose:
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;
A test image was created for experimentation, featuring constant RGB values (255,0,0) and a linear decrease in alpha value from top-right to bottom-left corners, with some pixels having an alpha value of 0:
https://i.sstatic.net/b0c3j.png
After loading the texture, inspection revealed that the R values of zero-alpha pixels were indeed 0. The following code snippet was utilized to read the image data:
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 );
}
An interesting observation was made regarding Windows PC behavior, where similar results were obtained, yet the shader continued to function correctly. This inconsistency between platforms suggests that the issue may be related to the canvas itself rather than the root problem. On iOS devices, however, the texture2D(...) lookup within the GLSL code consistently returned (0,0,0,0) for those specific pixels. (Note: My background lies in Java/C++ and my familiarity with javascript is still developing! :) ) Attempts to resolve the issue by setting the premultipliedAlpha flag to 0 in both the WebGLRenderer instance and the THREE.ShaderMaterial object proved unsuccessful.
If anyone has encountered similar challenges or knows how to rectify this unexpected behavior, your insights would be greatly appreciated!