OpenGL and OpenGL ES define two concurrent types of precision.
- Storage precision in buffers
- Minimum computational precision used in shaders.
Storage precision is defined by your vertex attribute upload, such as GL_FLOAT
or GL_HALF_FLOAT
. This will be the precision used to store the data in memory.
Usage precision is defined in the shader as highp
(at least 32-bit), mediump
(at least 16-bit), and lowp
(at least 9-bit). These are minimum precisions; it is perfectly legal for a shader to specify a variable as mediump
and for the shader compiler to generate fp32 data types. Desktop GPUs tend to only support fp32 computation, so the use of highp
, mediump
and lowp
all map to fp32 data types (the precision qualifiers are only included to keep compatibility with OpenGL ES shaders, and can legally be ignored by the compiler). Mobile GPUs implementing OpenGL ES tend to map highp
to fp32, and mediump
and lowp
to fp16.
Detailed information can be found in the GLSL ES 3.0 Specification, Section 4.5.1
When binding a vertex attribute in memory to an input shader variable the storage and usage precisions are not required to match; the API will include transparent attribute precision conversion. It is perfectly legal for a user to upload e.g. a GL_FLOAT
and then use it in a shader as a mediump
fp16 variable, although it would be a waste of memory bandwidth to do so.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…