Je comprends la syntaxe de HLSL, par exemple supposons que je l'ai comme HLSL:
struct VOut
{
float4 position : SV_POSITION;
float4 color : COLOR;
};
VOut VShader(float4 position : POSITION, float4 color : COLOR)
{
VOut output;
output.position = position;
output.position.xy *= 0.7f; // "shrink" the vertex on the x and y axes
output.color = color;
return output;
}
float4 PShader(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET
{
return color;
}
et je le compile comme ceci:
D3DX11CompileFromFile(L"shaders.hlsl", 0, 0, "VShader", "vs_5_0", 0, 0, 0, &VS, 0, 0);
D3DX11CompileFromFile(L"shaders.hlsl", 0, 0, "PShader", "ps_5_0", 0, 0, 0, &PS, 0, 0);
Comment ça aime ... savoir changer ... Je ne sais pas exactement quel est le pipeline entre HLSL et les pixels / sommets réels à l'écran.
Est-ce bien cela qui les "applique"?
dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);
dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);
// set the shader objects
devcon->VSSetShader(pVS, 0, 0);
devcon->PSSetShader(pPS, 0, 0);
Gardez à l'esprit que je suis comme un débutant littéral dans ce genre de choses. Quelqu'un peut-il peut-être expliquer ce qu'il fait? Je suppose que la fonction de sommet HLSL passe par chaque sommet, puis les change en tout ce que j'ai dans la fonction, et la sortie est ce qui a été changé ... et de même pour le pixel shader?
Autre confusion, je sais ce qu'est un pixel et je comprends ce qu'est un sommet ... mais que fait exactement le pixel shader?
Réponses:
Cela fonctionne à peu près comme ceci: lorsque vous émettez un appel de dessin (DrawPrimitives, DrawIndexedPrimitives dans D3D, Draw dans 10+, et cetera), les données de géométrie que vous avez liées au pipeline (vos tampons de vertex) sont traitées. Pour chaque sommet, le vertex shader est exécuté pour produire un sommet de sortie dans l'espace de clip.
Le GPU exécute ensuite certaines fonctions fixes sur ce sommet de l'espace d'écrêtage, telles que le découpage / élimination et le placement du sommet dans l'espace d'écran, où il commence à pixelliser les triangles. Lors de la pixellisation de chaque triangle, le GPU interpole les attributs de sommet sur la surface de ce triangle, alimentant chaque attribut interpolé au pixel shader pour produire une couleur semi-finale pour ce pixel (le mélange est appliqué après l'exécution du pixel shader, donc "semi- final").
Le code que vous avez publié compile d'abord les shaders, puis les lie au pipeline où ils restent actifs pour tous les appels de tirage ultérieurs jusqu'à ce qu'ils soient modifiés. Cela ne provoque pas leur exécution.
Le vertex shader est responsable de la transformation des sommets de l'espace objet en espace clip.
Le pixel shader est responsable du calcul de l'avant-dernière couleur / profondeur pour un pixel sur la base des attributs de sommet interpolés.
la source
Je vais essayer d'expliquer comment les choses fonctionnent sans utiliser beaucoup de jargon.
Si la simplicité plutôt que la vitesse interactive est votre préoccupation, une surface 3D dans l'ordinateur ne serait qu'un énorme nuage de points dans l'espace, suffisamment dense pour que nous puissions simplement rendre chaque point individuellement, sans espaces entre eux.
Vous ne voulez stocker un modèle qu'une seule fois en mémoire, mais vous devez l'afficher à différentes tailles et sous différents angles, donc lorsque vous effectuez le rendu d'un modèle 3D, vous devez "transformer" tous les points lorsque vous les lisez de la mémoire. Par exemple, pour rendre le modèle 50% plus grand, vous devez redimensionner les positions des points de moitié:
C'est presque le "vertex shader" le plus simple que l'on puisse concevoir: une position de sommet entre en mémoire et une nouvelle position de sommet, à moitié aussi grande. Le sommet à moitié aussi grand n'est pas stocké en mémoire - il est utilisé immédiatement pour le rendu, puis jeté.
Bien qu'une simplification flagrante qui manque de concepts clés , cela dans l'esprit décrit les aspects de la façon dont les films font des graphiques.
Les graphiques interactifs (jeux) ne peuvent pas se permettre d'être aussi simples, car ils doivent rendre les graphiques plusieurs ordres de grandeur plus rapidement qu'un film.
Dans les jeux, nous ne pouvons pas nous permettre de rendre un point pour chaque pixel à l'écran, plus des extras pour combler les lacunes. Donc, à titre de compromis, l'écart entre chacun des trois points voisins est rendu sous la forme d'un triangle qui, pour diverses raisons techniques, préfère avoir au moins 10 pixels de large à l'écran.
Un triangle 3D peut être projeté sur un écran 2D, puis divisé en une pile de lignes 1D, chacune pouvant être divisée en une pile de 0D pixels. Nous pouvons ainsi diviser et conquérir le problème du rendu d'un triangle 3D en un problème plus simple de rendu de beaucoup de pixels 0D de manière isolée. Un ordinateur peut résoudre des problèmes plus simples en moins de temps.
Un pixel shader est un petit programme que nous exécutons sur chaque pixel généré par le démontage d'un triangle.
C'est presque le "pixel shader" le plus simple que l'on puisse concevoir: dedans va un mélange des couleurs de trois sommets triangulaires, et dehors va la même couleur. Les entrées proviennent des sorties du "vertex shader" et les sorties sont écrites sur l'écran en mémoire.
Ainsi, le "vertex shader" est un programme qui s'exécute à l'intérieur de la puce GPU. Son entrée est un "vertex buffer" dans la mémoire GPU, et sa sortie est directement alimentée dans un "pixel shader". Un "pixel shader" est également un programme qui s'exécute à l'intérieur de la puce GPU. Ses entrées sont un mélange de trois sommets du vertex shader, et sa sortie est un pixel à l'écran.
la source
Outre les autres réponses, voici une petite image de ce qui se passe
À partir des étapes du pipeline, d3d10 (identique à d3d11).
Voir également
la source
Ne vous inquiétez pas pour un pixel shader en ce moment. Si vous êtes un débutant complet, vous devriez être bonjour au monde de GLSL / HLSL avec des shaders de vertex et de fragment uniquement. Une fois que vous êtes familier et que vous commencez à comprendre les mouvements variables et autres, élargissez vos horizons.
Je recommande fortement un livre de texte pour comprendre le fonctionnement de l'API. Les livres OpenGL illustrent également bien comment les choses ont changé au fil des ans, passant du pipeline fixe au pipeline programmable dynamique.
Allez champion!
la source