为什么需要为片段着色器设置精度?

Why it is necessary to set precision for the fragment shader?

我学习 WebGL。下一个着色器工作正常:

// vertex.shader
// precision mediump float;
attribute vec4 a_Position;
attribute float a_PointSize;

void main(){
  gl_Position = a_Position;
  gl_PointSize = a_PointSize;
}

// fragment.shader
precision mediump float;
uniform vec4 u_FragColor;

void main(){
  gl_FragColor = u_FragColor;
}

为什么需要设置片段着色器的精度?顶点着色器没有这个就可以工作,但是片段着色器没有这个代码行就不能工作(正如我所见)。为什么存在不同的行为?

我以前读过this,但对我没有帮助。

OpenGL ES 2.0 的片段着色器中的 fp 类型不存在默认精度。

在顶点着色器中,如果您没有显式设置浮点类型的默认精度,则默认为 highp。但是,如果片段着色器也默认为 highp,那将导致问题,因为 OpenGL ES 2.0 不 要求 支持片段中的高精度浮点类型着色器阶段。

OpenGL ES Shading Language - 4. Variables and Types - pp. 35-36

The fragment language has no default precision qualifier for floating point types. Hence for float, floating point vector and matrix variable declarations, either the declaration must include a precision qualifier or the default float precision must have been previously declared.

4.5.4 Available Precision Qualifiers

The built-in macro GL_FRAGMENT_PRECISION_HIGH is defined to one on systems supporting highp precision in the fragment language

#define GL_FRAGMENT_PRECISION_HIGH 1

and is not defined on systems not supporting highp precision in the fragment language. When defined, this macro is available in both the vertex and fragment languages. The highp qualifier is an optional feature in the fragment language and is not enabled by #extension.

简单的答案是规范没有为片段着色器定义默认的浮点精度,所以你必须自己指定它。

我一直认为没有默认值有点奇怪。其他所有内容都有默认精度。默认值不能是 highp,因为不能保证在片段着色器中可用。但是我没有看到默认情况下不能 mediump 的充分理由。 mediumpint 的默认值,它也可以是 float.

规范的第 10 节(“问题”)中的解释变得相当清楚。本节包含讨论规范时未解决的各种问题,然后进行了回答。通常会有一些解释,说明为什么选择答案。

特别是“10.3 精度限定符”处理了这个问题。其中一个问答(第85页)是:

Should there be a default precision? It would make sense to specify the default vertex precision as highp as that it what is currently specified. There is no agreement on what the default precision for the fragment side should be.

RESOLUTION: highp for the vertex shader, no default precision for the fragment shader.

我认为这其中的关键部分是:“没有达成一致”。听起来他们想定义一个默认的精度,但不同的供应商无法就它应该是什么达成一致,他们陷入僵局,最终根本没有定义一个。