WebGL / GLSL - comment fonctionne un ShaderToy?

J'ai frappé autour de Shadertoy - https://www.shadertoy.com / - récemment, dans un effort pour en savoir plus sur OpenGL et GLSL en particulier.

D'après ce que j'ai compris jusqu'à présent, L'utilisateur OpenGL doit d'abord préparer toute la géométrie à utiliser et configurer le serveur OpenGL (nombre de lumières autorisé, stockage de texture, etc.). Une fois cela fait, l'utilisateur doit alors fournir au moins un vertex shader programme, et un fragment shader programme avant qu'un programme OpenGL ne se compile.

cependant, quand je regarde les échantillons de code sur Shadertoy, Je ne vois qu'un seul programme de shader, et la plupart de la géométrie utilisée semble être écrite directement dans le code GLSL.

comment ça marche?

à mon avis, un shader vertex est déjà préparé à l'avance, et le shader modifiable/échantillon n'est qu'un shader de fragment. Mais cela n'explique pas la géométrie dans certains des exemples plus complexes...

est-ce que quelqu'un peut expliquer comment Shadertoy fonctionne?

42
demandé sur Abstract Algorithm 2013-10-18 16:24:02

4 réponses

ShaderToy est un outil pour écrire des pixels shaders.

que sont les pixels shaders?

si vous faites un quad plein écran, ce qui signifie que chacun des quatre points est placé dans un des quatre coins du viewport, alors le shader de fragment pour ce quad est appelé pixel shader, parce que vous pourriez dire que maintenant chaque fragment correspond exactement à un pixel de l'écran. Donc un pixel shader est un fragment shader pour un quad plein écran.

ainsi les attributs sont toujours les mêmes et il en va de même pour un shader vertex:

positions = [ [-1,1], [1,1], [-1,-1], [1,-1] ]
uv = [ [0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [1.0, 1.0] ]

et que quad est rendu comme TRIANGLE_STRIP . En outre, au lieu de définir explicitement UVs , certains préfèrent utiliser la variable intégrée de fragment shader gl_FragCoord , qui est ensuite divisée avec, par exemple, un uniform vec2 uScreenResolution .

Vertex shader:

attribute vec2 aPos;
attribute vec2 aUV;
varying vec2 vUV;

void main() {
    gl_Position = vec4(aPos, 0.0, 1.0);
    vUV = aUV;
}

et fragment shader ressemblerait alors à quelque chose comme ceci:

uniform vec2 uScreenResolution;
varying vec2 vUV;

void main() {
    // vUV is equal to gl_FragCoord/uScreenResolution
    // do some pixel shader related work
    gl_FragColor = vec3(someColor);
}

ShaderToy peut vous fournir quelques uniformes par défaut, iResolution (alias uScreenResolution ), iGlobalTime , iMouse ,... que vous pouvez utiliser dans votre pixel shader.

pour coder la géométrie directement dans le fragment shader (alias pixel shader), développeur utiliser quelque chose appelé ray-tracing. Il s'agit d'un domaine de programmation assez complexe, mais en bref: Vous présentez votre géométrie à travers quelques formules mathématiques, et plus tard en Pixel shader, quand vous vous souhaitez vérifier si un pixel fait partie de votre géométrie, vous utilisez cette formule pour récupérer cette information. Google-ing un peu devrait vous donner beaucoup de ressources pour lire à partir de quoi et comment les traceurs de rayon sont construits exactement, et cela pourrait aider: Comment faire du lancer de rayons moderne OpenGL?

Espérons que cette aide.

53
répondu Abstract Algorithm 2017-05-23 12:34:41

shadertoy affiche simple GLSL qui est programmé pour gérer tout l'éclairage, la géométrie, etc, ce n'est pas la géométrie vertex, il est raycaster la plupart de celui-ci, la substance 3D, ou vous pouvez faire des shaders 2D, etc

N'importe quelle couleur et les maths spatiales peuvent être programmées en langage GLSL. Les combinaisons d'algorithmes avancés font des isosurfaces, des formes, puis projettent des textures sur des isosurfaces, et raycasting, envoyant des lignes imaginaires du spectateur à la distance, intercepte n'importe quoi dans le il y a beaucoup de techniques de raycasting pour la 3D.

visite www.iquilezles.org pour avoir une idée des différents outils qui sont utilisés dans shadertoy/glsl graphiques

6
répondu com.prehensible 2015-10-29 21:24:51

c'est simplement pousser le code source du pixel shader GLSL directement sur la carte graphique.La vraie magie se produit dans les algorithmes incroyablement intelligents que les gens utilisent pour créer des effets étonnants, comme Ray marching, ray casting, ray tracing. il est préférable de jeter un oeil à d'autres bacs à sable GLSL vivants comme: http://glsl.heroku.com / et http://webglplayground.net / . Son essentiellement la création d'une fenêtre typiquement deux triangles qui représentent l'écran, puis le shader fonctionne sur chaque pixel comme un lancer de rayons.

J'ai regardé ces derniers un moment maintenant, et les algorithmes que les gens utilisent sont époustouflants, vous aurez besoin de quelques côtelettes mathématiques sérieuses et de chercher le code source "demo coding" pour pouvoir envelopper votre tête autour d'eux. De nombreux shader jouet, souffler votre esprit ! Donc, pour résumer, vous avez juste besoin d'apprendre GLSL shader codage et algorithmes. Pas de solution facile.

5
répondu panpsychist 2014-02-18 18:31:53

traditionnellement, en informatique, la géométrie est créée à l'aide de sommets et rendue à l'aide d'une certaine forme de matériaux (par exemple, textures avec éclairage). Dans GLSL, le shader de sommet traite les sommets et le shader de fragment (pixel) traite les matériaux.

Mais ce n'est pas la seule manière de définir les formes. Tout comme une texture pourrait être définie par une procédure (au lieu de chercher ses texels), une forme pourrait être définie par une procédure (au lieu de chercher sa géométrie).

donc, comme pour le traçage des rayons, ces shaders de fragments sont capables de créer des formes sans avoir leur géométrie définie par des sommets.

il y a encore d'autres façons de définir les formes. Par exemple: données de volume (voxels), courbes de surface, etc. Une infographie texte devrait couvrir certains d'entre eux.

1
répondu mlepage 2015-05-14 13:41:28