I missed this part when I first wrote GLSL, and I didn’t pay much attention to it. As a result, I met some problems in this aspect in the project today, so I hereby make a record to avoid further problems.
Let’s start with the following two pieces of code:
uniform sampler2D colorMap;
varying lowp vec2 varyingCoordPos;
void main() {
vec4 color = texture2D(colorMap,varyingCoordPos);
gl_FragColor = color;
}Copy the code
uniform sampler2D colorMap;
varying lowp vec2 varyingCoordPos;
void main() {
gl_FragColor = texture2D(colorMap,varyingCoordPos);
}Copy the code
Both pieces of code have the simplest logic — extract the texture’s color and assign it to gl_FragColor. But are both pieces of code correct? If not, what’s the problem? Note that the first section of code is wrong. Read this article to find out exactly what is wrong.
Three precision qualifiers
There are only three precision qualifiers in GLSL:
- Lowp: low accuracy
- Mediump: in precision
- Highp: high precision
The precision qualifier comes before the data type and after the storage qualifier, as in:
lowp float color;
varying mediump vec2 Coord;
highp mat4 m;Copy the code
Precision range
Note: Character constants and Boolean variables do not have precision modifiers.
Precision range for floating point variables
- Highp (-2 to the 62nd, 2 to the 62nd);
- Mediump (-2 to the 14th, 2 to the 14th);
- Lowp (2, 2);
Precision range for integer variables
- Highp (-2 to the 16th, 2 to the 16th);
- Mediump (-2 to the tenth, 2 to the tenth);
- Lowp (minus 2 to the eighth, 2 to the eighth);
From the precision range of these two data types, we know that for high and medium precision, integer variables can be converted to floating point variables with the same precision modifier.
For example: highp int can be converted to highp float, mediump int can be converted to mediump float; But a lowp int void cannot be converted to a lowp float. So why is that? It’s very simple, just like in C, just go from small to high, and not the other way around. For example, if the value of a lowp int variable is outside the range of a lowp float (-2, 2), this of course cannot be converted.
The default precision
We said that we can specify the precision of a variable directly by adding a precision qualifier to the type of the variable, but wouldn’t it be too tedious to add a precision qualifier to every integer or float (including integer vector, float vector, float matrix)? Is there a way to specify a default precision range directly?
The default precision can be specified using the precision keyword. The syntax is as follows:
precision precision-qualifier type; Qualifie can be one of highp, mediump, or LOWP, and only one of the three.Copy the code
If type is a float, this precision (precision-qualifie) will apply to any declaration of floating point numbers without precision modifiers, including scalars, vectors, and matrices.
If type is int, this precision (precision-qualifie) applies to any integer data declaration that has no precision qualifier, including scalars, vectors (matrices without integers in GLSL).
This includes global variable declarations, function return value declarations, function parameter declarations, and local variable declarations. Any variable that does not declare a precision modifier will use the precision of its nearest precision statement.
The specific writing is as follows:
precision highp float;
precision mediump int;Copy the code
Pre-defined precision
It is not necessary to declare precision for int and float data; GLSL pre-defines precision for some data types for us.
Predefined precision in vertex shaders
There are the following predefined global default precision statements in vertex shaders:
- precision highp float;
- precision highp int;
- precision lowp sampler2D;
- precision lowp samplerCube;
Predefined precision in the slice shader
In the fragment shader there are the following predefined global default precision statements:
- precision mediump int;
- precision lowp sampler2D;
- precision lowp samplerCube;
From this, we can conclude the following points:
- In Vertex Shader, float and int precision are highp if there is no default precision;
- In Vertex Shader, Fragment Shader, sampler2D and samplerCube have a default precision lowP.
- In Fragment Shader, only integer types have default precision, mediump; Float has no default precision
Now do we know why that code was wrong? Vec4 color = texture2D(colorMap,varyingCoordPos); Here we declare a temporary variable vec4 color in the slice shader, but we don’t specify the precision. The float in the slice shader has no default precision, so we get an error. Therefore, it is safe to add precision Highp float to the chip shader, whether necessary or not, to develop a good code specification. Of course, if you don’t add it, you can also change it to vec4 Mediump color.
Gl_FragColor = texture2D(colorMap,varyingCoordPos); gl_FragColor = texture2D(colorMap,varyingCoordPos); There’s no problem writing it that way.
- OpenGL first lesson — Name explanation
-
OpenGL is introduced in lesson 2 – The common fixed storage shader
-
OpenGL introduction third lesson — matrix transformation and coordinate system
-
OpenGL entry lesson 4 — Depth
-
OpenGL entry lesson 5 — front and back elimination
-
OpenGL entry lesson 6 — Clipping and Blending
-
OpenGL entry lesson 7 — Texture
-
OpenGL is in class 8 — a supplementary case
-
OpenGL ES que
-
The application of GLKit
-
GLSL met
-
How to use custom shaders written in GLSL in iOS
-
Precision qualifier in GLSL