WebGL Shader precision on MacBook Pro vs iPhone

Screenshot 2021-03-01 at 14.39.19.png

Photo by David Monje on Unsplash

I learned something new today. When developing in WebGL, you are required to set a default precision for the fragment shader. Here are the options:

precision lowp float;
precision mediump float;
precision highp float;

I read somewhere that lower precision calculations are faster, so if the result is the same you should attempt to use lowp if possible. I switched shademap.app to use lowp precision and everything looked good UNTIL I checked it on the iPad and my iPhone. It was broken.

Both were using lowp, how could this be? Well, it turns out that the precision is not identical across hardware. (I suspect the reason is that the iPhone uses an Apple chip while the MacBook uses an Intel chip). The lack of precision was causing my shade calculations to lose accuracy and the final result was incorrect.

Here is what lowp, mediump, highp correspond to on each device:

MacBook Pro (2018)iPhone SE
lowp precision: 23
rangeMin: 127
rangeMax: 127
precision: 10
rangeMin: 15
rangeMax: 15
mediumpprecision: 23
rangeMin: 127
rangeMax: 127
precision: 10
rangeMin: 15
rangeMax: 15
highpprecision: 23
rangeMin: 127
rangeMax: 127
precision: 23
rangeMin: 127
rangeMax: 127

As you can see, if you want the iPhone/iPad and MacBook Pro to use the same precision and range, you will need to set your fragment shader to highp.

Using another device? You can check its precision settings here or use the following code:

const canvas = document.createElement('canvas');
const div = document.createElement('div');
document.body.append(div);
const gl = canvas.getContext('webgl');

const types = {
  lowp: gl.LOW_FLOAT,
  mediump: gl.MEDIUM_FLOAT,
  highp: gl.HIGH_FLOAT,
};

let output = '';
for (x in types) {
  const { precision, rangeMax, rangeMin } = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, types[x])
  output += x + ': ' + JSON.stringify({precision: precision, rangeMin: rangeMin, rangeMax: rangeMax}, null, 2) + '\n';
}
div.innerText = output;
 
2
Kudos
 
2
Kudos

Now read this

Argonaut and Sherpa, Part 1

Sunset on Argonaut A wise man once said, “Good plans are all alike, each bad plan is bad in its own way”. Cassondra suggested (for the record) that we try Argonaut and Sherpa over Labor Day weekend. I love being enveloped in 30 mph winds... Continue →