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

OpenGL Discussion :

Ray Tracing GPU : Caméra [OpenGL 3.x]


Sujet :

OpenGL

  1. #1
    Membre régulier
    Inscrit en
    Mars 2006
    Messages
    209
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 209
    Points : 95
    Points
    95
    Par défaut Ray Tracing GPU : Caméra
    Bonjour à vous tous :-).

    Voilà, je m'intérèsse depuis très peu de temps au ray tracing.
    J'ai réussis (ou presque) à faire une fonction permettant de calculer les intersections avec une quadrique telle qu'une sphère, ou une hyperboloïde à une nappe en passant par un plan et d'autres encore.

    Bref, voilà, après avoir fait tout ça, j'ai voulu rajouter une caméra, chose très difficile à faire pour moi ^_^. Après moult recherches, j'ai trouver un truc pas mal, et effectivement tout fonctionne (dans le cas du plan ou de la sphère en tout cas), mais quand j'ai voulu rajouter mon hyperboloïde, misère... Mauvais affichage...
    Donc deux possibilités, soit je me suis trompé dans ma fonction de résolution de l'équation (possible, mais je ne pense pas), soit je me suis trompé pour la caméra et c'est pas impossible..., bien que ça me semble bizarre que ça ne marche pas pour l'hyperboloïde et que ça fonctionne avec les sphères / plans...

    Les "vexteurs" pos, dir, up correspondent à ceux que l'on rentre dans la fonction lookAt (gluLookAt pour les OpenGL 2.1) avec le vecteur up : up(0.0, 1.0, 0.0);

    Ceci est un code en GLSL, mais je pense qu'il n'est pas trop complexe à comprendre quand même.

    Code : 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
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    #version 330 core
     
    precision highp float;
     
    uniform int numberQuadric;
     
    struct QuadricData
    {
        // ax^2 + by^2 + cz^2 + 2dxy + 2exz + 2fyz + gx + hy + iz + j = 0
        float a, b, c, d, e, f, g, h, i, j;
     
        // Intervalle
        float xMin, xMax, yMin, yMax, zMin, zMax;
     
        // Couleur
        float rColor, gColor, bColor;
     
        float useless;
    };
     
    uniform Camera
    {
        float xPos, yPos, zPos;
        float xDir, yDir, zDir;
        float xUp, yUp, zUp;
        float cotanHalfFovY;
        int width, height;
    }camera;
     
    uniform Quadric
    {
        QuadricData q[500];
    }quadric;
     
     
    out vec4 color;
     
    // Si inférieur, c'est 0
    float minZero = 0.001;
     
    float computeDistQuadric(in vec3 ro, in vec3 rd, in QuadricData q, out vec3 pointIntersect)
    {
        /* Equation d'une quadric :ax² + bx² + cx² + 2dxy + 2exz + 2fyz + gx + hy + iz + j = 0
            (x, y, z) = ro + dist*rd;
            Objectif : Calculer la distance dist
        */
        /* On se ramène à une équation en a*dist^2 + b*dist + c */
        // a = partie en dist^2
        float a = q.a * rd.x * rd.x + q.b * rd.y * rd.y + q.c * rd.z * rd.z + 2 * q.d * rd.x * rd.y + 2 * q.e * rd.x * rd.z + 2 * q.f * rd.y * rd.z;
     
        // b Partie en dist
        float b = 2 * (q.a * rd.x * ro.x + q.b * rd.y * ro.y + q.c * rd.z * ro.z + q.d * (rd.x * ro.y + rd.y * ro.x) + q.e * (rd.x * ro.z + rd.z + ro.x) + q.f * (rd.y * ro.z + rd.z * ro.y)) + q.g * rd.x + q.h * rd.y + q.i * rd.z;
     
        // c Partie Constante
        float c = q.a * ro.x * ro.x + q.b * ro.y * ro.y + q.c * ro.z * ro.z + 2 * q.d * ro.x * ro.y + 2 * q.e * ro.x * ro.z + 2 * q.f * ro.y * ro.z + q.g * ro.x + q.h * ro.y + q.i * ro.z + q.j;
     
        if(abs(a) < minZero)
            return -c / b;
     
        float delta = b * b - 4.0 * a * c;
     
        // Il n'y a pas d'intersection
        if(delta < 0.0)
            return -1.0;
     
        // On récupère les distances
        float disc = sqrt(delta);
        float dist1 = (-b - disc) / (2.0 * a);
        float dist2 = (-b + disc) / (2.0 * a);
     
        // On récupère la bonne distance
        float goodDistance;
     
        // Les intersections sont derrières
        if(dist1 < 0.0 && dist2 < 0.0)
            return -1.0;
     
        if(dist1 > 0.0)
            goodDistance = dist1;
     
        // Distance 2 plus petites que la première
        if((dist2 > 0.0 && dist1 > 0.0) && dist2 < dist1)
            goodDistance = dist2;
     
        if(dist2 > 0.0 && dist1 < 0.0)
            goodDistance = dist2;
     
        pointIntersect = ro + goodDistance * rd;
     
        // Test l'interval
        if(pointIntersect.x < q.xMin || pointIntersect.x > q.xMax ||
           pointIntersect.y < q.yMin || pointIntersect.y > q.yMax ||
           pointIntersect.z < q.zMin || pointIntersect.z > q.zMax)
            return -1.0;
     
        return goodDistance;
    }
     
    void intersect(in vec3 ro, in vec3 rd)
    {
        color = vec4(0.0);
        float lessDist = 100000.0;
        int i;
        vec3 pointIntersect;
     
        float dist;
     
        for(i = 0; i < numberQuadric; ++i)
        {
            dist = computeDistQuadric(ro, rd, quadric.q[i], pointIntersect);
     
            // Si la distance d'intersection est plus petite que l'ancienne (z-Buffer)
            if(dist > 0.0 && dist < lessDist)
            {
                color = vec4(quadric.q[i].rColor, quadric.q[i].gColor, quadric.q[i].bColor, 1.0);
                lessDist = dist; // On met à jour la nouvelle distance
            }
        }
    }
     
    void main(void)
    {
        float i = (gl_FragCoord.x / camera.width) * 2.0 - 1.0;
        float j = (gl_FragCoord.y / camera.height) * 2.0 - 1.0;
     
        vec3 ro = vec3(camera.xPos, camera.yPos, camera.zPos);
        vec3 dir = vec3(camera.xDir, camera.yDir, camera.zDir);
        vec3 up = vec3(camera.xUp, camera.yUp, camera.zUp);
        vec3 right = cross(dir, up);
     
        // On recalcule le up pour avoir les 3 axes de telle sorte qu'elle forme une base orthonormal
        up = cross(right, dir);
     
        vec3 rd = normalize(camera.cotanHalfFovY * dir + i * right + j * up);
     
        intersect(ro, rd);
    }
    Voilà le côté parfait de l'hyperboloïde

    Nom : good.png
Affichages : 194
Taille : 2,8 Ko

    Là on commence à voir le bug : On ne voit pas l'arrière de l'hyperbole alors que dans ce mode de vue, on devrait

    Nom : fail2.png
Affichages : 150
Taille : 3,4 Ko

    Et le dernier, on voit bien le gros problème ^_^

    Nom : fail.png
Affichages : 153
Taille : 3,8 Ko

    Merci de votre aide à tous et à toutes :-)

    EDIT : Erreur trouvé, excusez moi pour le dérangements...

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 579
    Points
    218 579
    Billets dans le blog
    120
    Par défaut
    Quelle était l'erreur ?

    Sinon, vous avez vu cette vidéo de IQ : http://jeux.developpez.com/videos/GL...r-live-coding/ ?
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Membre régulier
    Inscrit en
    Mars 2006
    Messages
    209
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 209
    Points : 95
    Points
    95
    Par défaut
    Bonjour :-).

    L'erreur était dû à mes tests d'intervalle ^_^.

    Oui c'est justement cette vidéo qui m'a permis de prendre conscience de la possibilité de ray tracing en temps réel

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

Discussions similaires

  1. NVIDIA OptiX ou le ray tracing sur GPU
    Par dourouc05 dans le forum CUDA
    Réponses: 5
    Dernier message: 04/11/2009, 05h23
  2. Ray tracing CAML
    Par m0a-Stelle dans le forum Caml
    Réponses: 7
    Dernier message: 13/10/2008, 23h52
  3. [openGL] demande explication frustum, ray tracing, etc
    Par Aurelangelo dans le forum OpenGL
    Réponses: 1
    Dernier message: 22/03/2008, 21h02
  4. Tracer de rayon : ray tracing
    Par mr_samurai dans le forum Algorithmes et structures de données
    Réponses: 13
    Dernier message: 04/02/2008, 08h38
  5. Tutoriel ray-tracing , pov-ray...
    Par Ghost Dog dans le forum Langages de programmation
    Réponses: 4
    Dernier message: 02/09/2005, 14h16

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