Comment WebGL œuvres?
je cherche une compréhension approfondie du fonctionnement de WebGL. Je veux acquérir des connaissances à un niveau auquel la plupart des gens se soucient moins, parce que les connaissances ne sont pas nécessairement utiles au programmeur WebGL moyen. Par exemple, Quel rôle joue chaque partie(navigateur, pilote graphique, etc..) du système de rendu total joue en obtenant une image sur l'écran? Chaque navigateur doit-il créer un moteur/environnement javascript/html pour exécuter WebGL dans le navigateur? Pourquoi chrome est une tête de tout le monde autrement en termes de compatibilité avec WebGL?
alors, quelles sont les bonnes ressources pour commencer? La spécification de kronos fait en quelque sorte défaut( d'après ce que j'ai vu la parcourir pendant quelques minutes ) pour ce que je veux. Je veux surtout savoir comment cela est accompli / mis en œuvre dans les navigateurs et ce qui doit changer sur votre système pour le rendre possible.
2 réponses
espérons que ce petit rapport vous sera utile. Il résume une grande partie de ce que j'ai appris sur WebGL et la 3D en général. BTW, si j'ai eu quelque chose de mal, que quelqu'un me corrige s'il vous plaît -- parce que j'apprends encore, aussi!
Architecture
Le navigateur est juste que, d'un navigateur Web. Il ne fait qu'exposer L'API WebGL (via JavaScript), avec laquelle le programmeur fait tout le reste.
aussi proche que je puisse le dire, L'API WebGL est essentiellement juste un ensemble de fonctions JavaScript (fournies par le navigateur) qui enveloppent la spécification OpenGLES. Donc si vous connaissez OpenGLES, vous pouvez adopter WebGL assez rapidement. Mais ne confonds pas ça avec de l'OpenGL pur. Le " ES " est important.
la spécification WebGL a été intentionnellement laissée très bas niveau, laissant beaucoup à être mis en œuvre de nouveau d'une application à l'autre. C'est à l' la communauté d'écrire des cadres pour l'automatisation, et au développeur choisir d'utiliser le framework (le cas échéant). Il n'est pas entièrement difficile pour restaurer votre propre, mais il ne signifie pas une beaucoup de frais généraux passé sur réinventer la roue. (FWIW, je travaille sur mon propre WebGL cadre appelé Jax pour un certain temps maintenant.)
le pilote graphique fournit l'implémentation des options qui font fonctionner votre code. À ce stade, il tourne sur le matériel de la machine, en dessous même du code C. Alors que C'est ce qui fait WebGL possible en premier lieu, c'est aussi une arme à double tranchant parce que les bogues dans le pilote OpenGLES (que j'ai déjà noté un certain nombre) apparaîtront dans votre application Web, et vous ne le saurez pas nécessairement à moins que vous ne puissiez compter sur votre base d'utilisateurs pour déposer des rapports de bogue cohérents incluant OS, matériel vidéo et versions des pilotes. voici à quoi ressemble le processus de débogage pour de tels problèmes.
Sur Windows, il y a une couche supplémentaire qui existe entre le API WebGL et le matériel:ANGLE, ou "Presque Native Couche Graphique Moteur". Parce que les pilotes OpenGLES sur Windows sont généralement nuls, ANGLE reçoit ces appels et les traduit en appels DirectX 9 à la place.
dessin en 3D
maintenant que vous savez comment les pièces s'assemblent, regardons une explication de niveau inférieur de la façon dont tout se réunit pour produire une image 3D.
JavaScript
tout d'abord, le JavaScript le code obtient un contexte 3D à partir d'un HTML5 toile élément. Puis il enregistre un ensemble de shaders, qui sont écrits en GLSL (langage de Shading[Open] GL) et ressemblent essentiellement au code C.
Le reste du processus est très modulaire. Vous avez besoin d'obtenir des données de vertex et toute autre information que vous avez l'intention d'utiliser (comme les couleurs de vertex, les coordonnées de texture, et ainsi de suite) jusqu'à la filière graphique en utilisant des uniformes et des attributs qui sont définis dans le shader, mais l'exacte la mise en page et la désignation de ces informations dépendent beaucoup du développeur.
JavaScript configure les structures de données initiales et les envoie à L'API WebGL, qui les envoie soit à ANGLE, soit à OpenGLES, qui les envoie finalement au matériel graphique.
Vertex Shaders
une fois que l'information est disponible pour le shader, le shader doit transformer l'information en 2 phases pour produire des objets 3D. La première phase est le vertex shader, qui définit le maillage coordonnées. (Cette étape se déroule entièrement sur la carte vidéo, sous toutes les API discutées ci-dessus. La plupart du temps, le processus exécuté sur le vertex shader ressemble à quelque chose comme ceci:
gl_Position = PROJECTION_MATRIX * VIEW_MATRIX * MODEL_MATRIX * VERTEX_POSITION
où VERTEX_POSITION
est un vecteur 4D (x, y, z, et w qui est habituellement défini à 1);VIEW_MATRIX
est une matrice 4x4 représentant la vue de la caméra dans le monde; MODEL_MATRIX
est une matrice 4x4 qui transforme les coordonnées objet-espace (c'est-à-dire des coord locaux à l'objet avant la rotation ou traduction ont été appliqués) dans le monde-coordonnées de l'espace; et PROJECTION_MATRIX
qui représente l'objectif de la caméra.
le Plus souvent, le
VIEW_MATRIX
etMODEL_MATRIX
sont précalculées et appeléMODELVIEW_MATRIX
. De temps en temps, les 3 sont précalculés enMODELVIEW_PROJECTION_MATRIX
ouMVP
. Ce sont généralement destinés comme optimisations, bien que j'aimerais trouver le temps de faire quelques repères. C'est il est possible que le pré-calcul soit en fait plus lent en JavaScript s'il est fait chaque image, parce que JavaScript lui-même n'est pas très rapide. Dans ce cas, l'accélération matérielle accordée par faire le calcul sur la GPU pourrait bien être plus rapide que de le faire sur le CPU en JavaScript. Nous pouvons bien sûr, j'espère que les futures implémentations JS résoudront ce potentiel. gotcha simplement en étant plus rapide.
Coordonnées Des Clips
lorsque tous ces éléments ont été appliqués, le gl_Position
variable aura un ensemble de coordonnées XYZ allant à l'intérieur de [-1, 1], et un composant W. Ils sont appelées coordonnées de clip.
il est intéressant de noter que les coordonnées de clip est la seule chose que le vertex shader vraiment besoin de produire. Vous pouvez complètement sauter les transformations de matrice exécuté ci-dessus, tant que vous produisez un résultat de coordonnée de clip. (J'ai même expérimentée avec l'échange de matrices pour les quaternions; elle a fonctionné très bien, mais j'ai abandonné le projet car je n'ai pas le amélioration des performances que j'espérais pour.)
après avoir fourni les coordonnées du clip à gl_Position
WebGL divise le résultat par gl_Position.w
production de ce qu'on appelle des coordonnées normalisées.
De là, projeter un pixel sur l'écran est une simple question de multiplier par 1/2 Les dimensions de l'écran et d'ajouter ensuite la moitié des dimensions de l'écran. [1] voici quelques exemples de coordonnées de clip converties en coordonnées 2D sur un écran 800x600:
clip = [0, 0]
x = (0 * 800/2) + 800/2 = 400
y = (0 * 600/2) + 600/2 = 300
clip = [0.5, 0.5]
x = (0.5 * 800/2) + 800/2 = 200 + 400 = 600
y = (0.5 * 600/2) + 600/2 = 150 + 300 = 450
clip = [-0.5, -0.25]
x = (-0.5 * 800/2) + 800/2 = -200 + 400 = 200
y = (-0.25 * 600/2) + 600/2 = -150 + 300 = 150
Pixel Les Shaders
une Fois qu'il est déterminé où un pixel doit être établi, le pixel est remis à l'pixel shader, qui choisit la couleur réelle du pixel sera. Cela peut être fait d'une multitude de façons, allant du simple codage dur d'une couleur spécifique à la recherche de texture à la cartographie normale et parallaxe plus avancée (qui sont essentiellement des façons de "tricher" la recherche de texture pour produire des effets différents).
Profondeur et le Tampon de Profondeur
maintenant, jusqu'à présent nous avons ignoré le composant Z des coordonnées du clip. Voici comment cela fonctionne. Lorsque nous avons multiplié par la matrice de projection, la troisième composante de clip a donné un certain nombre. Si ce nombre est supérieur à 1,0 ou inférieur à -1,0, alors le nombre est au-delà de la plage de vision de la matrice de projection, correspondant aux valeurs Zfar et zNear de la matrice, respectivement.
donc si elle n'est pas dans la gamme [-1, 1] alors elle est coupée entièrement. Si c' dans cette gamme, puis le Z la valeur est ajustée à 0 pour 1 [2] et est comparée à la profondeur de la mémoire tampon [3]. Le tampon de profondeur est égal aux dimensions de l'écran, de sorte que si une projection de 800x600 est utilisée, le tampon de profondeur est 800 pixels de large et 600 pixels de haut. Nous avons déjà les coordonnées X et Y des pixels, donc ils sont connectés dans le tampon de profondeur pour obtenir la valeur Z actuellement stockée. Si la valeur Z est supérieure à la nouvelle valeur Z, alors la nouvelle valeur Z est plus près que ce était auparavant établi, et le remplace [4]. À ce point, il est sûr d'éclairer le pixel en question (ou dans le cas de WebGL, de dessiner le pixel sur la toile), et de stocker la valeur Z comme la nouvelle valeur de profondeur.
si la valeur Z est plus grand que la valeur de profondeur stockée, alors il est considéré comme "derrière" ce qui a déjà été dessiné, et le pixel est écarté.
[1] la conversion actuelle utilise le gl.viewport
paramètres pour convertir les coordonnées normalisées de l'appareil en pixels.
[2]il est en fait adapté à la gl.depthRange
paramètres. Par défaut est de 0 à 1.
[3] en supposant que vous avez un tampon de profondeur et que vous avez activé les tests de profondeur avec gl.enable(gl.DEPTH_TEST)
.
[4] vous pouvez définir comment les valeurs de Z sont comparées avec gl.depthFunc
je voudrais lire ces articles
http://webglfundamentals.org/webgl/lessons/webgl-how-it-works.html
en supposant que ces articles sont utiles, le reste de l'image est que WebGL tourne dans un navigateur. Il renvoie à une étiquette de toile. Vous pouvez penser à une balise canvas comme une balise img, sauf que vous utilisez L'API WebGL pour générer une image au lieu d'en télécharger une.
comme les autres étiquettes HTML5, l'étiquette canvas peut être coiffée de CSS, être placée sous ou sur d'autres parties de la page. Est composée (mixte) avec d'autres parties de la page. Être transformé, tourné, mis à l'échelle par CSS avec d'autres parties de la page. C'est une grande différence avec OpenGL ou OpenGLES.