The original

Float and double

  • The default number in CPP is double. For float,3.14f can do this
  • The precision of the Number type in JavaScript is double, while the precision of the floating point Number in the graphics interface API of general GPU (such as OpengL and DirectX) is float. Therefore, the accuracy of the data will be lost when the CPU passes it into THE GPU for rendering, which leads to the flash problem in rendering.
  • Float is a single-precision floating point number and double is a double-precision floating point number
  • Half – precision significant digit
    • 16-bit floating point number 1+8+7
    • Two significant digits
The sign bit Index a Mantissa part
1 8 7
  • The specific bit description of the float type:
    • 32-bit floating point number 1+8+23
    • Exponent: 2 to the seventh power is -127 to 128
    • Mantissa: 2^23 = 8388608
    • That is, float is accurate to 6 to 7 significant digits
The sign bit Index a Mantissa part
1 8 23
  • The exact number of digits of type double:
    • 64-bit floating point number 1+11+52
    • Exponent: 2 to the 10th power is -1023~1024
    • Mantissa: 2^52 = 4503599627370496
    • The precision of float is 15 to 16 significant digits
The sign bit Index a Mantissa part
1 11 52
  • Floating-point numbers. The decimal point of a floating-point number is floating, and the number of decimal places after the decimal point is not fixed

Shader precision

  • Vertex shader default precision
precision highp float;
precision highp int;
precision lowp sampler2D;
precision lowp samplerCube;
Copy the code
  • Chip shader default precision
precision mediump int;
precision lowp sampler2D;
precision lowp samplerCube;
Copy the code

Problem reproduction

var vertices = [
5000000.5.0.5.0.5.5000000.5.0.5, -0.5.5000000.5, -0.5.0.5.5000000.5, -0.5, -0.5.4999999.5.0.5, -0.5.4999999.5.0.5.0.5.4999999.5, -0.5, -0.5.4999999.5, -0.5.0.5.4999999.5.0.5, -0.5.5000000.5.0.5, -0.5.4999999.5.0.5.0.5.5000000.5.0.5.0.5.4999999.5, -0.5.0.5.5000000.5, -0.5.0.5.4999999.5, -0.5, -0.5.5000000.5, -0.5, -0.5.4999999.5.0.5.0.5.5000000.5.0.5.0.5.4999999.5, -0.5.0.5.5000000.5, -0.5.0.5.5000000.5.0.5, -0.5.4999999.5.0.5, -0.5.5000000.5, -0.5, -0.5.4999999.5, -0.5, -0.5]
Copy the code
  • A float contains up to seven significant digits, but there are eight significant digits, resulting in a loss of precision and resulting in an irregular cube.

Solutions to precision problems

  • RTC plan
    • RTC (Relative To Center) transforms the vertex information of the model into coordinates Relative To a central point.
var vertices = [
0.5.0.5.0.5.0.5.0.5, -0.5.0.5, -0.5.0.5. ]Copy the code
  • Use two floats to transmit high-precision data
    • This method ensures the accuracy but also increases the amount of data, resulting in a data bandwidth bottleneck. It depends on the actual situation.
function doubleToTwoFloats(value) {
    var high;
    var low;
    if (value >= 0) {
        tempHigh = Math.floor(value / 65536) * 65536;
        high = tempHigh;
        low = value - tempHigh;
    } else {
        tempHigh = Math.floor(-value / 65536) * 65536;
        high = -tempHigh;
        low = value + tempHigh;
    }
    return [high, low];
}
Copy the code
uniform vec3 uViewerHigh;
uniform vec3 uViewerLow;

void main(void)
{
    vec3 highDifference = vec3(gl_VertexHigh - uViewerHigh);
    vec3 lowDifference = vec3(gl_VertexLow.xyz - uViewerLow);
    gl_Position = gl_ModelViewProjectionMatrix *
         vec4(highDifference + lowDifference, 1.0);
}
Copy the code