On IOS, Three.js ensures that the RGB values of a texture are set to zero whenever the ALPHA value

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!

Answer №1

When working with PNG files on iOS, the CoreGraphics library automatically multiplies each RGB value by the alpha component for every pixel in the image. This means that if the alpha value is 0, all RGB values will also be set to zero. To work around this issue, consider loading a 24 BPP image where the alpha is always 255 (0xFF). Unfortunately, it is not possible to disable this premultiply step when processing a 32 BPP image on iOS.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Firefox 44 experiencing issue with HTML 5 Video playing sounds unexpectedly

There has been an unusual observation of Firefox playing the sounds of all embedded videos on a page, even when the elements themselves are not actively playing. Clicking play on the video controls triggers new sound and video playback to start. All video ...

suggestions for organizing data in an AJAX/jQuery page

Welcome to my JavaScript/Ajax webpage that also utilizes jQuery. I am facing a challenge with displaying a nested structure. Once a top level element is displayed, users should be able to click on it and reveal the levels below (which are dynamically gene ...

Having trouble getting CSS animations to work in Safari when triggered by JavaScript

By utilizing a basic CSS animation, I've managed to create a fade-in effect that relies on opacity. To kickstart the animation, I use JavaScript to ensure it waits until the browser finishes loading. While this method works seamlessly on Firefox and C ...

Filtering a string array in Angular based on an object's value

I am facing a challenge with two arrays in my code. The first array, $scope.termini, contains strings, and the other one, $scope.reserved, contains objects. Each object in the second array has a variable called vrijemeTermina. My goal is to filter $scope.t ...

Restrict Vue Router access to specific pages only

Once a user has logged in for the first time, they are directed to the CreateProfile page where they can enter their profile information. I want to restrict access to this page so that if the user manually types the URL into their browser (e.g. www.myproje ...

AngularJS experiencing issues with deleting function implementation

Here is my JavaScript code: camListApp.controller("Hello", function($scope, $http, $uibModal){ $scope.del=function(data){ var result=confirm('are you sure?'); if(result==true){ var index=getSelectedIndex(data); ...

Strategies for passing a JavaScript variable to a JSP function

I'm dealing with a JavaScript code that has a value stored in its variable that I need to pass to my JSP function. However, I'm facing trouble passing it along. Take a look at the following code snippets: Javascript: $('button').on(& ...

How to conditionally prevent event propagation to children in VueJs

This Vue component is called ColorButtonGroup, and it serves as a group of checkbox/toggle buttons. It has a maximum limit of 4 colors that can be selected. The component utilizes another component called ToggleButton, which is a simple toggle selection w ...

What is the most effective way to extract the output from a JSONP request and utilize it beyond the

I have a function that is working well. I had to use JSONP to handle cross-domain issues, and I also wrote an HTTP module to change the content-type. However, I did not include a callback name in the URL. function AddSecurityCode(securityCode, token) { va ...

jQuery smooth scrolling problem causing a one-second page "blinking" issue

Currently, I have implemented a smooth scrolling effect on my website using the following jQuery code: jQuery('html,body').animate({scrollTop:scrollTarget}, 1000, "swing"); Although the effect works well in general, I have noticed that when mul ...

What is the most effective method for accurately tallying the number of matches in a Datalist using the Input value as a reference

I have set up a datalist element with an associated input element for autocompletion in modern browsers: HTML code <input type="search" id="search" list="autocomplete" /> <datalist id="autocomplete"> <option value="c++" /> < ...

gulp - synchronized gulp.pipe(gulp.dest) execution

Here's my challenge: I have two tasks, where Task B depends on Task A. In Task A, one of the requirements is to loop through an array and then use gulp.dest, but it seems like Task B will be executed before Task A is completed. The main goal of Task ...

The issue with mocking collections using JSON files in Backbone is that it is not properly triggering the success callbacks in

For my project, I am exploring the use of .json files to mock GET requests in a backbone collection. Here is an example of my sample file: [ { "id": '11111', "name": "Abdominal Discomfort", "favori ...

What is preventing me from translating JS Canvas Image?

I've been struggling with using ctx.translate() to translate images on a canvas. No matter what I do, it just won't work. I've spent a good amount of time trying to troubleshoot the issue. Here's the snippet of code I'm working wit ...

The Google API is experiencing issues when using input that has been added on

Situation: In my attempt to integrate a Google address search feature into an online shopping website, I encountered a challenge. I don't have direct access to the website's HTML code, but I can insert code snippets in the header, footer, and in ...

Math operations limited by boundaries: adding and subtracting

What is the proper way to implement this logic in JavaScript: Row-=21; if (Row < 1) { Row = 1; } ...

What is the process for making an Ajax request in Rails?

I'm attempting to send a variable through jQuery using the POST method, saving it in a controller, and then utilizing that same variable in Rails HTML to query a table. It seems like the variable isn't being passed to the controller. jQuery: v ...

What is the best way to adjust the size of a Google Map container based on the radius of a circle?

I have successfully integrated Google Maps v3 into my website. However, I am faced with the challenge of resizing the map according to the radius of a circle. I want the map to be covered by the circle. Currently, my container's dimensions are heigh ...

Recreating elements in ng-repeat using ng-click conditionally

I am attempting to swap an anchor tag with an image when clicked by the user. The code snippet I'm using looks like this: <div ng-repeat="postpart in currentPost.parts "> <div ng-if = "!postpart.isclicked"> <img ng-src= ...

The anchor tag seems to be malfunctioning within the div container

<style type="text/css> .xyz { position: absolute; top: 120px; left: 160px; z-index: -1; } #container { position: relative; overflow: visible; opacity: .3; } </style> <body> <div> <video i ...