web-dev-qa-db-fra.com

Dans OpenGL ES 2.0 / GLSL, où avez-vous besoin de spécificateurs de précision?

La variable dans laquelle vous insérez des valeurs dicte-t-elle la précision avec laquelle vous travaillez, à droite du signe égal?

Par exemple, y a-t-il une différence de signification avec le spécificateur de précision ici:

gl_FragColor = lowp vec4(1);

Voici un autre exemple:

lowp float floaty = 1. * 2.;
floaty = lowp 1. * lowp 2.;

Et si vous prenez des flottants et créez un vecteur ou une matrice à partir d'eux, ce vecteur ou cette matrice prendra-t-il la précision des valeurs avec lesquelles vous le remplissez, ou ces valeurs se transformeront-elles en un autre niveau de précision?

Je pense qu'optimiser cela répondrait le mieux à la question:

dot(gl_LightSource[0].position.xyz, gl_NormalMatrix * gl_Normal)

Je veux dire, faut-il aller aussi loin, si vous le voulez aussi vite que possible, ou une partie est-elle inutile?

lowp dot(lowp gl_LightSource[0].position.xyz, lowp gl_NormalMatrix * lowp gl_Normal)

Je sais que vous pouvez définir la précision par défaut pour float, et que celle-ci est censée être utilisée par la suite pour les vecteurs et les matrices. Supposons, aux fins de l'éducation, que nous l'avions défini précédemment:

precision highp float;
48
Jessy
  1. Vous n'avez pas besoin de spécificateurs de précision sur les constantes/littéraux car ceux-ci obtiennent le temps de compilation évalué selon ce à quoi ils sont affectés. De plus, comme la précision de gl_FragColor Est déjà définie en fonction de la profondeur de la cible de rendu, la précision que vous lui affectez ne devrait pas avoir d'importance.

  2. Dans les vertex shaders, les précisions suivantes sont déclarées par défaut: (4.5.3 Default Precision Qualifiers)

    precision highp float;
    precision highp int;
    precision lowp sampler2D;
    precision lowp samplerCube;
    

    Et dans les shaders de fragments, vous obtenez:

    precision mediump int;
    precision lowp sampler2D;
    precision lowp samplerCube;
    

    Cela signifie que si vous déclarez un float dans un fragment shader, vous devez dire s'il s'agit d'un lowp ou d'un mediump. Les précisions par défaut float/int s'étendent également aux matrices/vecteurs.

  3. highp n'est pris en charge que sur les systèmes dont la macro GL_FRAGMENT_PRECISION_HIGH est définie sur 1; sur le reste, vous obtiendrez une erreur de compilation. (4.5.4 Available Precision Qualifiers)

  4. La règle de précision dans une expression est qu'ils sont automatiquement convertis en type d'affectation/paramètre auquel ils sont liés. Ainsi, pour votre point, il utiliserait la précision des types d'entrée par défaut et les lowp supplémentaires sont inutiles (et syntaxiquement incorrects). Si vous souhaitez rétrograder un type avec une précision inférieure, la seule façon de le faire est de l'affecter explicitement à une précision inférieure.

Ces réponses proviennent toutes de la spécification Khronos GLSL, que vous pouvez trouver ici (les sections pertinentes sont 4.5.2 et 4.5.3): http://www.khronos.org/registry/gles/specs/2.0/ GLSL_ES_Specification_1.0.17.pdf

71
Mikola