IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

DirectX Discussion :

[DirectX HLSL] Récupérer les vertex depuis les Shaders


Sujet :

DirectX

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 6
    Points : 6
    Points
    6
    Par défaut [DirectX HLSL] Récupérer les vertex depuis les Shaders
    Bonjour,

    Dans le logiciel que je développe, j'utilise des Pixel et Vertex Shaders pour effectuer mes rendus. Dans ces shaders, je calcule les UVs de mes vertex selon certains algorithmes et une depth map. Jusque là, aucun souci, tout marche à merveille.

    Cependant, il me faudrait pouvoir récupérer dans mon code C# les vertex modifiés par les shaders ... Je n'ai pas trouvé de moyen pour récupérer des données depuis les shaders.

    Je ne sais pas si c'est très clair, je peux donner plus de précisions si vous pensez pouvoir m'aider !

    Merci.

  2. #2
    Expert éminent
    Avatar de raptor70
    Inscrit en
    Septembre 2005
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Septembre 2005
    Messages : 3 173
    Points : 6 812
    Points
    6 812
    Par défaut
    Le principe des shaders est d'appliquer, sur tes pixel/vertex, une opération "post-process", soit jsute avant l'écriture dans le buffer.

    Il n'est donc pas possible de réappliquer quelque chose en plus ...
    Mes Tutos DirectX, OpenGL, 3D : http://raptor.developpez.com/

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 6
    Points : 6
    Points
    6
    Par défaut
    Ce que je voudrais c'est récupérer les vertex après leur passage dans le vertex shader, pas les modifier. Juste accéder aux valeurs des UVs de chaque vertex, qui sont calculés dans les shaders.

  4. #4
    Expert éminent
    Avatar de raptor70
    Inscrit en
    Septembre 2005
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Septembre 2005
    Messages : 3 173
    Points : 6 812
    Points
    6 812
    Par défaut
    Je ne crois pas que cela soit possible
    Mes Tutos DirectX, OpenGL, 3D : http://raptor.developpez.com/

  5. #5
    Membre confirmé

    Inscrit en
    Août 2007
    Messages
    300
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 300
    Points : 527
    Points
    527
    Par défaut
    Mise à jour de cette discussion après redémarrage du forum: Seliah travaille avec DX9/C#, donc le seul moyen est de coder le résultat dans des textures dynamiques, puis de les relire depuis le PC par Lock.
    CUDA est bien adapté pour des calculs généraux sur le GPU, mais pas à la récupération des résultats des calculs HLSL.
    Avec DX10 (donc C++, ou de façon un peu plus acrobatique C# via SlimDX), la technique consiste à faire un faux "geometry shader" qui se contente de ranger dans un "vertex buffer" (VB) le résultat du "vertex shader" (ce que le VS ne peut faire par lui-même: seuls les GS peuvent écrire par "stream-out"). Ensuite, il faut copier, à l'intérieur du GPU, ce VB dans un autre lisible par le CPU, et récupérer son contenu par Map/Unmap. La raison pour laquelle il faut deux VB est qu'il y a des restrictions sur les possibilités des VB selon leurs droits d'accès CPU et GPU.
    "Maybe C++0x will inspire people to write tutorials emphasizing simple use, rather than just papers showing off cleverness." - Bjarne Stroustrup
    "Modern C++11 is not your daddy’s C++" - Herb Sutter

  6. #6
    Membre expérimenté

    Profil pro
    Programmeur
    Inscrit en
    Août 2002
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Août 2002
    Messages : 1 091
    Points : 1 679
    Points
    1 679
    Par défaut
    La question c'est pourquoi ? Qu-est-ce que tu essaies de faire ?

    Après on peut peut-etre essayer de voir les solutions possibles.

    LeGreg

    Mon site web | Mon blog | Mes photos | Groupe USA
    > BONJOUR, JE SUIS NOUVEAU SUR CE FORUM
    > presse la touche caps lock, stp
    > OH.. MERCI C EST BEAUCOUP PLUS FACILE COMME CA

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 6
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par LeGreg Voir le message
    La question c'est pourquoi ? Qu-est-ce que tu essaies de faire ?
    Bon, mon problème est résolu (enfin je l'ai contourné, quoi :p) mais je peux quand meme expliquer ce que je voulais faire : pour faire bref, je calculais les UVs à appliquer à mon objet 3D directement dans le Vertex shader, selon des algorithmes particuliers, afin de faire travailler un peu la carte graphique. Il s'est avéré plus tard que j'avais besoin d'implémenter une fonctionnalité d'export en .OBJ de l'objet 3D manipulé dans le logiciel que je développe, donc j'avais besoin des UVs calculés afin de les mettre dans le .OBJ.

    C'est pour ca que je souhaitais récupérer en sortie du vertex shaders les valeurs des UVs pour chaque vertex. Je voulais éviter de déplacer les calculs d'UVs dans le code C# car le calcul est lourd et donc aurait ralenti l'application.

    La solution toute bête que j'ai trouvée est que je continue de calculer ces UVs dans les shaders, et je les re-calcule dans le code C# que lors de l'export en .OBJ ... J'aurais pu y penser plus tôt, je sais

    D'après un PM que m'a envoyé ac_wingless, récupérer les vertex en sortie des shaders n'est pas vraiment possible en DirectX9.0, mais si tu as une idée, je suis toujours preneur, ca servira surement un jour !

  8. #8
    Membre expérimenté

    Profil pro
    Programmeur
    Inscrit en
    Août 2002
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Août 2002
    Messages : 1 091
    Points : 1 679
    Points
    1 679
    Par défaut
    Beaucoup de choses sont possibles mais il faut tenir compte des compromis (trade off).

    En gros il faut que tu regardes le GPU comme une boite noire parallèle, tu envoies des commandes. La destination "naturelle" de ces commandes est l'écran : le GPU d'aujourd'hui est équipé pour afficher les choses le plus rapidement possible à l'écran. Le mode est "fire and forget" (tire et oublie). Les tentatives de resynchroniser par derrière le rendu avec le CPU sont donc généralement peu "efficaces" et les tentatives naïves sont généralement vouées à l'échec (si ils ne tiennent pas compte du cout de cette communication). Bien entendu sur une carte graphique haut de gamme, la puissance de calcul disponible est tellement énorme (calcul parfois 20 fois plus rapide que ce que peut faire le CPU) que pour un très gros calcul il est plus efficace de faire tout sur le GPU et payer le coût de synchronisation (approche des GPGPUs et de Cuda par exemple).

    Donc maintenant ta situation consiste à évaluer si ton calcul d'UV rentre dans cette catégorie. Est-ce que le nombre d'opérations que tu fais par UV justifie le coût de plusieurs memcopy (pour rendre disponibles les données au GPU et pour les récupérer), et d'une boucle de synchronisation (est-ce que le CPU fait autre chose en attendant ou peut préparer les commandes suivantes ?), ainsi que le coût d'écriture de code spécialisé (le coût d'écriture et de déboguage n'est pas à négliger)? Si tu fais un rendu sur écran ce coût est justifié parce que la commande est déjà envoyé quoi qu'il arrive et ça décharge le CPU (pour l'AI, la physique, le code réseau). Si tu fais du pré processing de vertex, à toi de faire une évaluation de ton cas particulier.

    Une fois que tu as déterminé cela, reste à imaginer la solution à ton problème. Comme on l'a dit sous Direct3D10 tu as stream output qui est intéressant parce qu'il permet de créer des sommets et des triangles. Sous Direct3D9 ce n'est pas possible mais ça ne veut pas dire que tu ne peux pas faire de calculs parallèles dessus.
    En fait sur les anciennes cartes D3D9 (geforce 6/7), la puissance de calcul des pixel shaders était beaucoup plus importante que celle du calcul des vertex shaders (qui en plus est limité par la rapidité du setup de triangles..). Et donc toute décharge de calcul essaie généralement de faire le plus d'opérations sous forme de pixel shader.
    Comment ça ? Un vertex buffer c'est une input, les pixel shaders ont deux types d'input : constant buffers et texture buffers, tu peux donc passer tes données de vertex sous ces deux formes (les constant buffers ne sont vraiment efficaces que depuis la geforce 8 et d3d10 cependant). Pour l'output (la color target) si tu calcules U et V, un format de texture qui contient des nombres flottant devrait marcher (ABGR32F par exemple). Tu peux même utiliser les MRTs pour avoir plus de 4 nombres flottants etc. Inconvénient : il faut un minimum prédire l'expansion de tes données (en dehors du pixel shader) pour savoir dans quelle partie du buffer elles vont atterrir (le cas du geometry shader gère l'expansion automatiquement).

    Si tu ne veux pas te casser la tête à faire passer du calcul de vertex dans un pixel shader dans d3d tu peux aussi passer par Cuda qui te génère un code qui ne se soucie pas de savoir si ce sont des sommets/pixels/bananes et qui s'occupe de la synchro de lui-meme. Mais Cuda est disponible uniquement sur geforce 8 (pour la version accélérée).

    Sinon, tu regardes ton calcul d'UV, tu te dis qu'une multiplication de deux matrices en SSE finalement ce n'est pas si lent que ça par rapport à l'alternative de création de context/shader etc., tu écris une partie de ton programme en C++ avec intrinsic SSE1/2, si tu es vraiment hardcore sur la performance..

    LeGreg

    Mon site web | Mon blog | Mes photos | Groupe USA
    > BONJOUR, JE SUIS NOUVEAU SUR CE FORUM
    > presse la touche caps lock, stp
    > OH.. MERCI C EST BEAUCOUP PLUS FACILE COMME CA

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Alimentation depuis les progiciels et les ERP
    Par ylesaint dans le forum Alimentation
    Réponses: 1
    Dernier message: 11/03/2016, 13h36
  2. Réponses: 13
    Dernier message: 25/12/2011, 20h17
  3. [SP-2010] Prendre les Informations depuis les Profiles Sharepoint
    Par hamzaj dans le forum SharePoint
    Réponses: 4
    Dernier message: 19/11/2010, 12h33
  4. Réponses: 2
    Dernier message: 22/08/2007, 12h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo