DivideConcept.net

le blog de divide.

Displacement Mapping realtime… le retour !

Certains de NoFrag s’en souviennent peut-être, il y a 3 ans j’avais développé un shader de displacement mapping limitant les artefacts et affichant également la silhouette du displacement (cf les 3 articles sur le displacement mapping: part1/part2/part3).
J’avais contacté alors plusieurs boites de JV, mais l’algorithme était lourd à mettre en place et encore trop couteux pour du ingame avec le matériel de l’époque.
Tout ça avait finit par s’embourber… avant de ressurgir sous la forme d’une nouvelle idée, il y a une semaine.

Voici donc le SSDM (Screen Space Displacement Mapping)

Une vidéo de démo (de la pre-alpha) est téléchargeable ici (wmv 720p, 11mo) (merci à NoFrag pour l’hébergement).
Vous pouvez aussi la visionner sur Vimeo, mais je vous recommande fortement le .wmv ci-dessus, en fullscreen.
Le modèle présenté dans cette vidéo utilise environ 8000 polygones, et le displacement appliqué dessus est équivalent à 1 million de polygones.

La liste des features, succinctement commentée:

-faster than parallax occlusion mapping 3.0

(GeForce 8800GTS, Full-HD, fullscreen quad)
POM 3.0: 80 fps
SSDM: 160 fps

-independant to scene complexity

(GeForce 8800GTS, Full-HD, fullscreen torus)
POM 3.0: 40 fps
SSDM: 160 fps

-objects sides displacement

-depth buffer displacement

-doesn’t need additional geometry

-doesn’t need precomputing

-handle per-pixel non-uniform, dynamic displacement vectors

Ce shader pourrait donc permettre la généralisation du displacement mapping sur tous les objets d’une scène, au même titre que les textures, puisqu’il est simple à mettre en place et que son coût en ressources est constant…

edit 8 novembre 2008: vidéo de la beta

edit2: SSDM: Screen Space Displacement Mapping (Paper)

48 commentaires pour “Displacement Mapping realtime… le retour !”

  1. fqboy dit :

    Ahhhh enfin le retour !

    Bon j’y comprends toujours rien mais ça à l’air bien.

  2. Oldbrush dit :

    Bon tu nous testes ça sur une vraie map ? Je veux un dire pas une texture tilée pour voir ? (ça c’est un "hey" dans le public pour dire, je peux tester/te le faire ?)

  3. divide dit :

    Ca serait avec plaisir, le prototype tourne actuellement sur RenderMonkey, faut que je vois si je peux charger des scènes avec plusieurs textures (ou alors va falloir se demerder pour n’utiliser qu’une seule grosse texture pour l’ensemble de la scène).
    A quel genre de scène tu pense ? (et que tu pourrais modéliser)

  4. Oldbrush dit :

    Je pensais a ton modele actuel et une vraie map (entendre une vraie texture). Mais si c’est pour une map (entendre niveau), je suis trop short en temps pour que ça ai un intéret visuellement.

  5. divide dit :

    ah oui ok.. ben si tu as un combo visage+displacement sous la main ca serait niquel, sinon je t’ai uploadé le modèle ici.

  6. Holi dit :

    sexy!

  7. Iggy dit :

    J’avais suivi tes précédents travaux, je dois dire que le résultat ici est superbe, vraiment bien joué!

  8. Oldbrush dit :

    J’ai pas de modele que je peux te filer comme ça, mais je vais t’en faire d’après ton modele modifié. (très modifié)

    Sinon question, les textures en 2048 ou 1024 ? et tu as diffuse+displace+spec ?

  9. divide dit :

    L’ennui avec RenderMonkey c’est qu’il gère difficilement le mipmapping et l’anisotropie, donc si j’applique une 2048 directement le résultat ne sera peut-être pas très lisse… Mais si c’est le cas au pire je resizerai en 1024, donc envois en 2048.
    Je n’ai pas encore implémenté le spec, mais si tu penses que c’est intéressant d’avoir une couche comme ca pour la démo, je peux le rajouter…

  10. Oldbrush dit :

    Pas obligatoire mais ça peut être un plus. Tout dépend des params de rendermonkey. Cela dit ma config a changé et maya n’est plus activé donc les textures arriveront ptet un peu après au moins la displace devrait arriver tot, ce qui veut dire que si c’est casse tête laisse tomber la spec.

  11. skaven dit :

    Ca doit bien manger du fillrate.

    Par contre, ce qui me gave un peu, c’est que pour TOUS les effets de displacement, TOUT le monde utilise LA MEME texture.
    Pour montrer que ton effet poutre, tu pourrais montrer quelque chose de différent?
    peut-etre pas quelque chose representatif dans un jeu mais au moins quelque chose de différent.
    Ensuite, le plus gros probleme avec ce genre de shader est la quantité de lecture pour le raycast.
    l’application en screenspace plutot qu’en rendu classique ne limite pas la bande passante puisque maintenant tout le monde fait 1 rendu de Z en prepass et profiter ainsi du early Z-Rejection.

  12. Bernardo_Guy dit :

    Respect Divide !

  13. divide dit :

    -Oui, enfin pas tant que ca (110fps en Full-HD sur 8800gts).
    -Complètement d’accord avec toi pour le coup de la texture, mais Oldbrush va m’arranger ca ;)
    -L’approche est en fait complètement différente des shaders habituels de displacement; ici, il y a très peu de lecture. La où un shader de parallax classique doit faire au minimum une vingtaine de lectures pour un résultat correct, comparativement je n’en fait que 6 (mais selon une autre logique).
    -L’application en screenspace limite la bande passante, mais effectivement on peux aussi limiter la bande passante avec du early Z..

  14. KickMe dit :

    Eh mais ! d’où tu sors tout ça ? ôO

  15. skaven dit :

    "110fps en Full-HD sur 8800gts"
    Tu pourrais compter par 1 occlusion query le nombre de pixels que tu peux calculer par seconde?
    Je continue tout de même de penser que toute technique de parralax reste trop gourmande par rapport au rendement visuel.
    Surtout qu’a une distance assez courte, tu ne vois plus la différence avec le même mesh seulement avec une normal map.

    Exemples tirés de ca
    Parralax Off:

    On

    Parralax Off:

    On

    Et en On, il doit y avoir une belle différence de framerate.

  16. skaven dit :

    Au passage, je me pose quelques questions.
    Tu es en screenspace, donc j’en déduis que tu fais 1 passe en fin de rendu (temps constant) et que tu recuperes des infos depuis un ensemble de textures (MRT).
    Ce que je ne comprends pas est simple.
    Tu as plusieurs objets avec des textures de displacement différentes, comment tu sais lors de ta passe dans quelle texture de displacement piocher?
    ou alors, tu as 2MRT et tu charges toutes les textures de displacement dans tes TMU au moment de ta passe?
    Dans ce cas, tu serais limité par le nombre de textures de displacement visibles par frame.

    Autre question, as tu essayé de faire du dynamic branching suivant le Z (depuis un early Z)?
    Z <0.1 = 10 samples
    Z <0.5 = 6 samples
    Z < 0.9 = 2 samples

  17. Oldbrush dit :

    Ça devrait ressembler a peu près à ça (textures très wip), si j’arrive a faire fonctionner le transfert polypaint>texture de zbrush.
    Par contre vu que c’est basé sur ton mesh de démo, je sais pas si je vais pas devoir refaire le lowpoly pour que ça colle bien (approximation des courbes peut-être problèmatique avec le mesh actuel).

  18. Anonyme dit :

    Ston boulot beat (la tête du mec là)?
    Si oui, tu ne cesse de progresser c’est impressionnant.

    Hmm sinon skaven, tes exemples de displacement vs normal sont vraiment pas les mieux choisis du tout. Le rendu est bien trop plat. Essaie sur un mur de brique (éh oui, le mur, et la brique, est un exemple récurrent car démonstratif, et les murs et les briques étant des choses que l’ont rencontre énormément dans les jeux, c’est très bien)
    Et le parralax est vraiment peu gourmand en fait hein (enfin, c’est un débat qui date d’il y a 3 ans là déjà… les cg récentes jonglent avec tous ces machins les doigts dans le nez- c ‘est simple d’ailleurs, pratiquement tous les jeux récents utilisent cette techo, sans complexe.)

  19. divide dit :

    Skaven:
    En ce qui concerne les exemples de Ysaneya, ils sont basés sur les limites du parallax mapping. Cette technique n’est finalement pas très interessante à grande échelle, puisque l’astuce ne marche que dans certains cas particuliers, sur des surfaces bien délimités. Même dans un jeu aussi poussé visuellement que Crysis, le parallax n’est utilisé qu’avec parcimonie, et toujours au niveau du sol; et pour cause, un niveau de parallax trop élevé produit l’effet d’escalier (comme le note Ysaneya) et il est impossible avec cette technique de détacher la silhouette displacé de sa surface polygonale.
    C’est pourquoi il a choisis des exemples typiques du parallax, avec du displacement extremement plat, utilisé avec parcimonie; forcément, à partir d’une certaine distance ca passe inaperçu (je rajouterai que la perception du relief est bien plus présente en mouvement que sur des screenshots).
    Mais avec le SSDM, on peut imaginer appliquer du displacement sur toute une scène; pour reprendre l’exemple de Crysis, non seulement au niveau du sol, mais aussi sur les troncs d’arbres, les batiments, et les coreens. L’ensemble avec et sans displacement mapping prend du coup une autre tournure, puisque toute la scène en est affecté.

    "Je continue tout de même de penser que toute technique de parralax reste trop gourmande par rapport au rendement visuel."
    Je suis d’accord, mais avec le SSDM on peut réellement parler de displacement, et plus seulement de parallax.
    De plus, cette technique consommera toujours un nombre constant de fps pour un gpu et une résolution donnée, donc autant ne pas se priver d’en mettre sur tous les objets.

    En ce qui concerne les détails de l’implémentation, ca va être délicat d’en parler ici si je veux licencier cette techno à une boite de JV…

    Oldbrush:
    si tu utilise zbrush, il est capable de sortir un modèle low-poly+displace non ? Parce que partir d’une tête de ninja pour arriver à Manu Katché, c’est… challenging, on va dire.
    Si t’arrive à faire un modèle approché, même avec peu de polygones, ca sera deja plus confortable que le ninja.
    Au fait, je fais du displacement positif, donc garde le modèle de support en dessous de la surface réelle.

  20. LeGreg dit :

    @Skaven : le parallaxe est plus intéressant en mouvement (ou à la rigueur en stéréovision) sinon il n’y a pas forcément de point de référence qui te dit à quelle profondeur se trouve tel ou tel point sur une image fixe. Mais bon c’est vrai que c’est généralement utile en vision de près donc à quelques mètres de l’observateur.

    @Divide : 110 fps, certes, mais ce n’est pas un chiffre très utile et ta présentation ne donne pas vraiment d’info (sauf si c’est juste un teaser ?). Surcoût par rapport au simple normal mapping sur une scène de jeu complexe (jeu de dernière génération, par rapport à la méthode de Crysis, de Call of Juarez, de Chaos theory etc) ? Combien de RTs et de passes supplémentaires ? Est-ce que tu laisses l’antialiasing sur le carreau ? Quels sont les compromis que tu as eu à faire pour le réaliser dans l’espace écran ?

    Aussi tu comptes l’utiliser dans un prochain jeu ou tu veux aller le vendre à une compagnie comme la dernière fois ? Le truc c’est que je ne crois pas que beaucoup de boites iront payer pour acheter juste un effet de shader. Ou tu comptes le déposer en brevet ?

    Sinon Direct3D11 va réintroduire la tesselation (adaptative) et donc on risque de revoir le vrai displacement mapping réapparaitre (avec intersection gérée par le zbuffer, level of detail en fonction de l’apparence/taille à l’écran, et antialiasing sur les bords des triangles comme la géométrie normale). Après il y a des avantages à l’une comme à l’autre méthode (real ou virtual). Tout dépendra du coût d’implémentation/authoring vs performance vs impact visuel.

  21. divide dit :

    110fps, ca signifie que l’effet mettra toujours moins de 1ms à s’executer, en 1920×1080, sur une geforce 8800gts.
    Ce temps étant proportionnel à la résolution graphique et à la capacité de calcul du gpu, tu peux extrapoler les performances pour n’importe quel configuration, et donc estimer si c’est viable de l’implémenter dans un jeu.

    Après c’est effectivement du teasing que je fais la, donc pour le détail d’implémentation, les artefacts possibles etc je ne peux voir qu’au cas par cas avec les intéressés.

    Je ne développe moi-même pas de jeu, mais je pense que l’effet soulève suffisament d’enjeu pour intéresser quelques boites de JV… Après on verra bien où ça ménera (d’ou le teasing) !

    Il me semble que DirectX 10 permet deja de faire de la tesselation (avec les geometry shaders) ? Mais dans l’immédiat, ça reste moins efficace que l’approche pixel shader (puisque re-transformation de géométrie, et nécessité de recalculer la densité du maillage à la volée).

  22. LeGreg dit :

    Non non pas de tesselation avec geometry shaders (ou du moins pas à cette génération ci). Meme si des gens ont imaginé l’implémenter sur le papier, ça ne marche pas pour plein de raisons.

    Je rentrerai bien dans les détails mais je tease moi aussi :)

  23. shletten dit :

    Haha la musique de rave dans la Matrice Rechargée. Sinon très intéressante technologie.

  24. Anonyme dit :

    Sur la video, on ne voit qu’un seul objet: Je suis curieux de voir comment tu gères la superposition entre plusieurs objets (et notamment comment faire pour que les objets ne se mettent pas a "baver" les uns sur les autres) sans faire de ray marching en espace ecran.

  25. divide dit :

    screen avec 2 objets:

    tout n’est pas encore parfait, mais il s’agit d’une pre-alpha…

  26. DindonPoilu dit :

    Et si tu déplaces ton objet en second plan plus sur la droite, de manière à ce que son displacement se face vers l’objet en premier plan ? C’est pas dans ce genre de cas que ça pourrait "baver" ?

  27. divide dit :

  28. Anonyme dit :

    Ça a l’air de bien marcher :)

    Bien joué. Penses-tu utiliser cette technique pour faire d’autres style de déplacement (genre de la réfraction pour des objets sous un plan d’eau) ?

  29. divide dit :

    tient, bonne idée !

  30. Oldbrush dit :

    @Anon: ouep c’est de moi.
    @Divide: pour le base mesh c’est peut-être pas un problème.

    -Peut-être parce que zbrush modifie les niveau les plus bas et qu’il modifie par conséquent le baase mesh pour pouvoir "soutenir" les niveaux plus haut, en gros si je te montre le base mesh maintenant ça ne ressemble plus au ninja (scorpion/subzero ?).
    -Peut-être aussi parce que c’est qu’une approximation low poly du modele présenté. Du coup comme tu dis que ton displace est positif faudrait que je modifie manuellement certains vertices pour que ça marche…

    Donc en fait pas du tout, faut que je refasse le low affaire règlée (et voilà un cheminement de pensée en temps réel, c’est fou la technologie de l’internet deu poin zero).

    Sinon mon problème actuel est plutot d’arriver a projeter la peinture par polygone de zbrush sur la texture d’après uv que tu as créé et ça semble par marcher des masses sous zb, du moins je n’en saisis pas toutes les subtilités pour le moment mais je vais trouver :)

  31. __MaX__ dit :

    divide, tu me dégoutes comment tu poutres :|
    J’aimerais autant pouvoir penser des trucs comme ça que, poser des notes sur une partoche ** jaloux **

    Le depth buffer, ça permettrait techniquement d’influer sur la position d’un objet à la surface de ton poly ?

    Je me suis toujours demandé si le parallax permettrait un jour de compenser les modèles de surface, genre tu sais, les logo très épais sur un mur, est-ce-que cela serait possible de faire une réelle déformation de surface si importante, que l’on pense que c’est un modèle a part entière sur la surface du mur par exemple ?

  32. divide dit :

    __MaX__: Le depth buffer, ca permet quand tu rajoute un nouvel objet dans ta scène (ou effet, type fumée) de savoir à partir de quelle profondeur il sera masqué par les objets deja présents.
    Ici, le "depth buffer displacement" permet de rectifier le depth buffer pour qu’il ne reste pas enregistré sur la surface plane du polygone de support, mais bien sur la surface réelle déformée; et donc d’avoir des intersections correctes pour les futures passes de rendu.

    Pour la pre-alpha j’ai volontairement limité la taille du displacement (pour des commodités de programmation), mais la version finale permettra effectivement de faire ce que tu dis (pour un cout de calcul quasiment inchangé).

    Oldbrush: tu t’en sors ?

  33. __MaX__ dit :

    Sans une déformation de la texture trop prononcée ? Parceque certains systèmes limitent les artefacts, mais quand le parallax devient trop prononcé, les rebords des textures sont hyper étirés.

    M’enfin sinon, keep the good work, je suis fan.

  34. divide dit :

    Pour un objet qui sort trop verticalement, pour limiter l’étirement de la texture il faut prévoir quelques polygones de support en plus…

  35. Oldbrush dit :

    @Divide: zbrush m’ayant fagociter l’uv, je suis dans l’incapacité d’exporter la texture que j’ai fais dans le soft, par conséquent je refait un low actuellement, je vais tenter une autre méthode mais ça risque de prendre un peu plus de temps (j’espèrais te filer le modele complet aujourd’hui ça me fait chier.)

  36. divide dit :

    ok pas de pb, prend le temps qu’il faut !

  37. Darkstryder dit :

    Est-ce que la technique prends en entrée une height map toute bête, ou est-ce qu’il est nécessaire d’appliquer un pré-processing quelconque dessus pour obtenir le format de données utilisable par la technique ?
    Si le format est particulier, combien d’octet par pixel consomme-t-il ?
    Toujours si le format est particulier, quel est la complexité algorithmique du pré-processing ?

  38. divide dit :

    "doesn’t need precomputing", donc pas de pre-process requis :)
    J’ai également fait un test avec la compression DXT5 (compression de texture souvent utilisé dans les jeux), avec RGB en couleur et A en height map, et ca marche tout aussi bien.

  39. Blade_Runner dit :

    Comme d’hab, ça en jette, et comme le premier moteur (celui avec les milliers de visage) dommage que les screens, pourtant impressionnants, ne soient pas plus représentatifs des possibilités.

    Ca donnerait quoi avec des vêtements, des touches de téléphone/ de clavier, de l’herbe ? Bref, quelque chose qui montre des applications concrètes.

    Me tarde de voir l’évolution de ce truc (et aussi celle de ta caméra 3D, celle du moteur voxel et puis le plan de ton moteur hyperespace -ah non, ça c’est encore secret).

  40. divide dit :

    Pas trop le temps de faire l’artiste dans l’immédiat, mais je vais essayer de récolter un peu plus sources concrètes…!

    Pour l’évolution de la cam3d, ca sera fin 2008/debut 2009 je pense (teasing !)

    stay tuned..

  41. Oldbrush dit :

    Divide, tu me recommande combien de poly pour le low ? Actuellement je suis a 1828 triangles (aucun tris que du quad) vaut mieux plus (7400 tris environ en subdiv 1) ?

    Ah et dernière question: ça pose problème si les yeux sont des spheres independantes du modele (je peux les combiner mais ce sera une enveloppe en plus du visage) ?

  42. divide dit :

    @Oldbrush: envois moi les 2 deux versions, 1828 et 7400, ca me permettra de voir ce qui marche le mieux avec le SSDM.
    Pour les yeux effectivement ca risque de poser pb mais on verra bien, faudra peut-être les virer ou tweaker ca, ca sera la surprise…
    Pour les fichiers, tu pourras envoyer à divide at divideconcept.net (si tu n’as pas de serveur).

  43. vimes dit :

    C’est ptet au coeur de ta techno donc je ne t’en voudrais pas de pas répondre mais est-ce que tu fais du displacement sur tout ton objet, juste là où ça compte vraiment (i.e. sur le contour) ou est-ce que tu sample moins au fur et à mesure que les normales (i.e. les faces qui sont à l’intérieur du model) ?

  44. divide dit :

    Je ne peux malheureusement pas répondre en détail, disons que j’essaye que tout ça soit le plus uniforme possible visuellement.
    Prochaine démo d’ici 2 jours je pense, avec une version un peu plus avancée…

  45. Plouf dit :

    Des nouvelles ?

  46. divide dit :

    J’ai eu un dialogue avec Crytek qui proposait de m’embaucher, car ils n’achètent pas de technos seules…
    Du coup je ne sais pas trop quoi faire de cette techno, il faudrait que je monte moi-même un projet de jeu dessus :/

  47. billitch dit :

    > “doesn’t need precomputing”, donc pas de pre-process requis :)

    Ça veut dire que tu pourrais animer cette texture !? Ça serait énorme =)

    Il faudrait coder une démo et la poster sur pouet.net là tu aurais une vraie portée médiatique de geeks ;)

    Sinon tu as pensé aux industriels ? Ils ont toutes sortes de besoins de visualisation eux aussi, par exemple en biologie ils ont pas mal de systèmes de visualisation 3D hors de prix.

  48. divide dit :

    Yep ca marche avec des textures animés aussi :)

    Sinon effectivement je n’ai pas pensé à contacter des industriels hors jeux vidéos…

Laisser un commentaire

Si vous avez un compte sur WeFrag, connectez-vous pour publier un commentaire.

Vous pouvez, entre autres, utiliser les tags XHTML suivant :
<a href="" title="">...</a>,<b>...</b>,<blockquote cite="">...</blockquote>,<code>...</code>,<i>...</i>