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

Développement 2D, 3D et Jeux Discussion :

Le rendu au raytracing dans les jeux vidéos.


Sujet :

Développement 2D, 3D et Jeux

  1. #41
    Rédacteur/Modérateur

    Avatar de yahiko
    Homme Profil pro
    Développeur
    Inscrit en
    Juillet 2013
    Messages
    1 423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 1 423
    Points : 8 700
    Points
    8 700
    Billets dans le blog
    43
    Par défaut
    Si je ne m'abuse, la cible c'est l"animation photoréaliste en temps réel.
    Si d'autres techniques que le Ray Tracing parviennent au même résultat avec moins de calcul, pourquoi pas, mais je ne suis pas sûr que ce soit vraiment photoréaliste.
    Tutoriels et FAQ TypeScript

  2. #42
    Invité
    Invité(e)
    Par défaut
    Pour faire du raytracing avec le gpu il faudrait que celui-ci soit optimisé pour un algorithme de ce genre :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
     
     for (unsigned int i = 0; i < m_instances.size(); i++) {
                    for (unsigned int j = 0; j < m_instances[i]->getVertexArrays().size(); j++) {
                        TransformMatrix& tm = m_instances[i]->getTransforms()[j].get();
                        for (unsigned int k = 0; k < m_instances[i]->getVertexArrays()[j]->getVertexCount(); k++) {
                            math::Matrix4f texM;
                            math::Matrix4f invTexM;
                            if (m_instances[i]->getMaterial().getTexture() != nullptr) {
                                texM = m_instances[i]->getMaterial().getTexture()->getTextureMatrix();
                                invTexM = texM.inverse();
                            }
                            if (m_instances[i]->getVertexArrays()[j]->getPrimitiveType() == sf::TrianglesFan
                                && m_instances[i]->getVertexArrays()[j]->getVertexCount() >= 3
                                && k < m_instances[i]->getVertexArrays()[j]->getVertexCount() - 2) {
                                math::Vec3f p1 = math::Vec3f((*m_instances[i]->getVertexArrays()[j])[0].position.x,(*m_instances[i]->getVertexArrays()[j])[0].position.y,(*m_instances[i]->getVertexArrays()[j])[0].position.z);
                                math::Vec3f p2 = math::Vec3f((*m_instances[i]->getVertexArrays()[j])[k+1].position.x,(*m_instances[i]->getVertexArrays()[j])[k+1].position.y,(*m_instances[i]->getVertexArrays()[j])[k+1].position.z);
                                math::Vec3f p3 = math::Vec3f((*m_instances[i]->getVertexArrays()[j])[k+2].position.x,(*m_instances[i]->getVertexArrays()[j])[k+2].position.y,(*m_instances[i]->getVertexArrays()[j])[k+2].position.z);
                                p1 = tm.transform(p1);
                                p2 = tm.transform(p2);
                                p3 = tm.transform(p3);
                                math::Vec3f orig = math::Vec3f(view.getPosition().x, view.getPosition().y, view.getViewport().getPosition().z);
                                for (unsigned int x = 0; x < size.x; x++) {
                                    for (unsigned int y = 0; y < size.y; y++) {
                                       math::Vec3f ext = window.mapPixelToCoords(math::Vec3f(x, y, view.getViewport().getPosition().z + view.getViewport().getSize().z), view);
                                       math::Ray ray(orig, ext);
                                       math::Vec3f o, point;
                                       math::Vec3f r = ray.getOrig() - ray.getExt();
                                       math::Vec3f u = p2 - p1;
                                       math::Vec3f v = p3 - p1;
                                       math::Vec3f n = u.cross(v);
                                       math::Vec3f otr = ray.getOrig() - p1;
                                       point.x = n.dot2(otr) / n.dot2(r);
                                       point.y = -otr.cross(u).dot2(r) / n.dot2(r);
                                       point.z = -v.cross(otr).dot2(r) / n.dot2(r);
                                       if (0 <= point.x
                                       && 0 <= point.y && point.y <= 1
                                       &&  0 <= point.z && point.z <= 1
                                       && point.y + point.z <= 1) {
                                           //std::cout<<"intersects"<<std::endl;
                                            sf::Color c1 = (*m_instances[i]->getVertexArrays()[j])[0].color;
                                            sf::Color c2 = (*m_instances[i]->getVertexArrays()[j])[k+1].color;
                                            sf::Color c3 = (*m_instances[i]->getVertexArrays()[j])[k+2].color;
                                            math::Vec3f ct1 = texM * math::Vec3f((*m_instances[i]->getVertexArrays()[j])[0].texCoords.x,(*m_instances[i]->getVertexArrays()[j])[0].texCoords.y, 1.f);
                                            math::Vec3f ct2 = texM * math::Vec3f((*m_instances[i]->getVertexArrays()[j])[k+1].texCoords.x,(*m_instances[i]->getVertexArrays()[j])[k+1].texCoords.y, 1.f);
                                            math::Vec3f ct3 = texM * math::Vec3f((*m_instances[i]->getVertexArrays()[j])[k+2].texCoords.x,(*m_instances[i]->getVertexArrays()[j])[k+2].texCoords.y, 1.f);
                                            math::Vec3f z (p1.z, p2.z, p3.z);
                                            float bz = z.x * point.x + z.y * point.y + z.z * point.z;
                                            float actualZ = depthBuffer[y * size.x + x].z;
                                            if (bz >= view.getViewport().getPosition().z && bz <= view.getViewport().getSize().z) {
                                                math::Vec3f r = math::Vec3f (c1.r / 255.f, c2.r / 255.f, c3.r / 255.f);
                                                math::Vec3f g = math::Vec3f (c1.g / 255.f, c2.g / 255.f, c3.g / 255.f);
                                                math::Vec3f b = math::Vec3f (c1.b / 255.f, c2.b / 255.f, c3.b / 255.f);
                                                math::Vec3f a = math::Vec3f (c1.a / 255.f, c2.a / 255.f, c3.a / 255.f);
                                                std::array<math::Vec3f, 2> colors;
                                                colors[0] = math::Vec3f(r.x * point.x + r.y * point.y + r.z * point.z,
                                                                        g.x * point.x + g.y * point.y + g.z * point.z,
                                                                        b.x * point.x + b.y * point.y + b.z * point.z,
                                                                        a.x * point.x + a.y * point.y + a.z * point.z);
                                                math::Vec3f finalColor = colors[0];
                                                depthBuffer[y * size.x + x] = math::Vec3f(0, 0, bz, colors[0].w);
                                                frameBuffer[(y * size.x + x) * 4] = finalColor.x * 255;
                                                frameBuffer[(y * size.x + x) * 4 + 1] = finalColor.y * 255;
                                                frameBuffer[(y * size.x + x) * 4 + 2] = finalColor.z * 255;
                                                frameBuffer[(y * size.x + x) * 4 + 3] = finalColor.w * 255;
                                            }
                                       }
                                    }
                                }
                            }
                        }
                    }
                 }

    M'enfin bon, je ne pense pas que ça soit pour demain!

  3. #43
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Citation Envoyé par Lolilolight Voir le message
    Pour faire du raytracing avec le gpu il faudrait que celui-ci soit optimisé pour un algorithme de ce genre :
    (...)
    M'enfin bon, je ne pense pas que ça soit pour demain!
    Ce que tu as écrit là ce n'est pas du raytracing, c'est de la (mauvaise) rastérisation et c'est exactement ce pour quoi le GPU est optimisé depuis vingt ans !

    Quant au raytracing les derniers GPU sont au contraire bien adaptés puisqu'ils ils gèrent les sparse octrees directement au niveau matériel (dx 11.1 je crois), qu'ils sont massivement parallèles et que le cohérence spatiale doit déboucher sur une exécution efficace des branchements conditionnels.

    Par contre ils ne font pas encore dans le vaudou, ce qui explique qu'ils ne soient toujours pas capables de faire du raytracing en temps réel du fait des besoins colossaux en puissance de calcul.

  4. #44
    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
    Raytracing dans les jeux vidéos ? Réponse de Normand comme souvent en programmation : c'est compliqué !

    On peut noter une tendance et cela se confirmera peut-être que dans quelques années le rendu des ray/path tracers et rasterizers aura convergé suffisamment pour qu'on puisse passer de l'un à l'autre et avoir un "feeling" similaire sur une scène lambda.

    Voilà une scène super simple mais qui utilise des concepts utilisés désormais couramment dans les jeux conçus pour les rasterizers, éclairage direct (avec ombrage "tranché"), ambient occlusion, éclairage à base d'image (pour le terme ambiant), environment map, etc :


    Et voici la même scène, mêmes paramètres de matériaux, mêmes valeurs d'éclairage mais cette fois rendue dans un raytracer/path tracer basé sur la physique (Mitsuba) :


    Bien entendu si j'introduisais des réflexions miroir et des interreflexions (illumination globale), caustiques, etc très visibles dans la scène, la donne changerait légèrement, mais ces choses seront peut-être mieux gérées dans le futur et font déjà parfois l'objet de solutions ad hoc convaincantes (screen space reflections ou env maps pour les réflexions, voxel gi ou propagation volume ou lightmaps pour les interreflexions, rendus procéduraux pour les caustiques. etc). Le tout en restant très intéractifs voire fluide et avec un rendu pas forcément aussi bruité que avec un path tracer brut.

    Au final ce qui importe ce n'est pas tant la méthode qui est utilisée mais celle qui permet d'atteindre l'objectif voulu. Le jeu vidéo va encore privilégier le haut frame rate (30 à 60 fps dans une scène complexe) à une solution théorique plus exacte physiquement. Ça ne veut pas dire non plus que dans le futur le rasterizer aura à faire trop de sacrifices non plus.

    Bref chacun voit midi à sa porte comme on dit. La personne qui a un objectif de rendu architectural parfait va privilégier les rendus offlines pour leurs capacités à propager la lumière et exceller avec les surfaces un peu plus complexes (verre, marbre, métaux, etc), pareil pour l'ingénieur automobile qui voudra un rendu "parfait" de la réflection de l'environnement sur la carrosserie simulée d'une future voiture, idem dans les films où l'oeil exercé du spectateur sera plus important que le temps de rendu d'un film (rendu une seule fois et rejoué des millions de fois au format "video").

    Le développeur de jeu va voir ce qui lui permet d'atteindre le plus facilement sa cible de 60 fps et si il a le budget en puissance de calcul n'hésitera pas à utiliser des méthodes qui ressemblent à celle du rendu offline (lancers de rayons dans la scène/espace de texture/espace de l'écran ou dans un arbre volumétrique, cf self shadows, ambient occlusion, global illumination). Si cela améliore l'expérience visuelle bien entendu.

    Bref, pensez comme un programmeur de jeu. Imaginez que vous avez un problème à résoudre. Exemple parmi tant d'autres, distortion de caméra de l'Oculus Rift.


    Vous pourriez (naïvement) vous dire : eh c'est un problème tout simple pour un raytracer, il n'y aucun surcoût à ajouter de la distortion en envoyant les rayons légèrement différemment.. Sauf que votre frame rate de base pour ce même rendu serait super bas. Et que l'Oculus en plus a des impératifs de latence/fluidité beaucoup plus haute que pour un jeu sur écran normal.
    Donc même si ça semble moins naturel, il est tout à fait normal de faire le rendu dans une texture et de faire la distortion de cette texture sur l'écran avec un bon vieux rasterizer comme ce qui est fait dans cette image.
    Vous aurez la même discussion interne pour tous les autres choix (reflection, ombres..).

    Après, on ne vous décourage pas j'espère. Rien ne vous empêche de porter des jeux en raytracing juste pour le fun :


    ou de faire des choses très différentes (Euclideon, unlimited details) :


    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

  5. #45
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Citation Envoyé par LeGreg Voir le message
    Raytracing dans les jeux vidéos ? Réponse de Normand comme souvent en programmation : c'est compliqué !
    Et il y a une chose qu'on pourrait ajouter : finalement cela fait des années que les jeux utilisent le raytracing et la radiosité, sauf qu'ils l'utilisaient uniquement en pré-calculé, pour générer les lightmaps. La nouveauté c'est que l'on peut désormais appliquer des techniques similaires en temps réel (en trichant beaucoup) pour les lumières dynamiques. et autres.

Discussions similaires

  1. Réponses: 88
    Dernier message: 01/09/2012, 13h15
  2. Les métiers de la programmation dans les jeux vidéos
    Par NiamorH dans le forum Développement 2D, 3D et Jeux
    Réponses: 36
    Dernier message: 09/10/2007, 14h10
  3. Réponses: 49
    Dernier message: 31/08/2007, 12h30
  4. Les threads dans les jeux vidéos
    Par Davidbrcz dans le forum Développement 2D, 3D et Jeux
    Réponses: 24
    Dernier message: 22/08/2007, 18h59

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