在 OpenGL ES 2.0 / GLSL 中,哪里需要精度说明符?
您要填充值的变量是否决定了您在等号右侧使用的精度?
例如,这里的精度说明符是否有任何含义上的差异:
gl_FragColor = lowp vec4(1);
这是另一个例子:
lowp float floaty = 1. * 2.;
floaty = lowp 1. * lowp 2.;
如果您采用一些浮点数,并从中创建一个向量或矩阵,该向量或矩阵是否会采用您所计算的值的精度填充它,或者这些值会转换成另一个精度级别吗?
我认为优化这一点可以最好地回答这个问题:
dot(gl_LightSource[0].position.xyz, gl_NormalMatrix * gl_Normal)
我的意思是,如果你想要尽可能快地实现它,是否需要走这么远,或者其中一些是无用的?
lowp dot(lowp gl_LightSource[0].position.xyz, lowp gl_NormalMatrix * lowp gl_Normal)
我知道您可以定义浮点数的默认精度,并且这应该用于之后的向量和矩阵。出于教育目的,假设我们之前已经定义过:
precision highp float;
Does the variable that you're stuffing values into dictate what precision you're working with, to the right of the equals sign?
For example, is there any difference, of meaning, to the precision specifier here:
gl_FragColor = lowp vec4(1);
Here's another example:
lowp float floaty = 1. * 2.;
floaty = lowp 1. * lowp 2.;
And if you take some floats, and create a vector or matrix from them, will that vector or matrix take on the precision of the values you stuff it with, or will those values transform into another precision level?
I think optimizing this would best answer the question:
dot(gl_LightSource[0].position.xyz, gl_NormalMatrix * gl_Normal)
I mean, does it need to go this far, if you want it as fast as possible, or is some of it useless?
lowp dot(lowp gl_LightSource[0].position.xyz, lowp gl_NormalMatrix * lowp gl_Normal)
I know you can define the default precision for float, and that this supposedly is used for vectors and matrices afterwards. Assume for the purpose of education, that we had defined this previously:
precision highp float;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您不需要常量/文字的精度说明符,因为它们的编译时间会根据它们被分配的内容进行评估。
在顶点着色器中,默认声明以下精度:(
4.5.3 默认精度限定符
)在片段着色器中,您将得到:
这意味着,如果您在片段着色器中声明浮点数,则必须说出它是
lowp
还是mediump
。默认的float
/int
精度也扩展到矩阵/向量。highp
仅在将GL_FRAGMENT_PRECISION_HIGH
宏定义为1
的系统上受支持;其余的你会得到一个编译器错误。 (4.5.4 可用的精度限定符
)表达式中的精度规则是它们自动转换为它们所绑定的赋值/参数的类型。因此,对于您的点,默认情况下它将使用输入类型的精度,并且额外的
lowp
是不必要的(并且语法上不正确)。如果您想将类型向下转换为较低的精度,唯一的方法就是显式地将其分配给较低的精度。这些答案均来自 Khronos GLSL 规范,您可以在这里找到(相关部分为 4.5.2 和 4.5.3): https://www.khronos.org/registry/OpenGL/specs/es/2.0/GLSL_ES_Specification_1.00.pdf
在最新版本的规范,这些部分是 4.7.3 和 4.7.4。除了向两个列表添加默认的精度 highpatomic_uint; 之外,没有任何变化。请参阅https://www.khronos.org/registry/ OpenGL/specs/es/3.2/GLSL_ES_Specification_3.20.pdf
You don't need precision specifiers on constants/literals since those get compile time evaluated to whatever they are being assigned to.
In vertex shaders, the following precisions are declared by default: (
4.5.3 Default Precision Qualifiers
)And in fragment shaders you get:
This means that if you declare a float in a fragment shader, you have to say whether it is a
lowp
or amediump
. The defaultfloat
/int
precisions also extend to matrices/vectors.highp
is only supported on systems that have theGL_FRAGMENT_PRECISION_HIGH
macro defined to1
; on the rest you'll get a compiler error. (4.5.4 Available Precision Qualifiers
)The rule for precision in an expression is that they get cast automatically to the type of the assignment / parameter they are bound to. So for your dot, it would use the precision of the input types by default and the additional
lowp
's are unnecessary (and syntactically incorrect). If you want to down-cast a type to a lower precision, the only way to do it is to explicitly assign it to a lower precision.These answers are all from the Khronos GLSL spec, which you can find here (relevant sections are 4.5.2 and 4.5.3): https://www.khronos.org/registry/OpenGL/specs/es/2.0/GLSL_ES_Specification_1.00.pdf
In more recent versions of the spec, those sections are 4.7.3 and 4.7.4. Nothing has changed, except adding a default
precision highp atomic_uint;
to both lists. See https://www.khronos.org/registry/OpenGL/specs/es/3.2/GLSL_ES_Specification_3.20.pdf