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 :

gl_FragCoord.z et effets d'eau [GLSL]


Sujet :

OpenGL

  1. #1
    Invité
    Invité(e)
    Par défaut gl_FragCoord.z et effets d'eau
    Bonjour et bonne année 2020. Je voudrais savoir svp quel est le lien entre gl_FragCoord.z et la profondeur à l'échelle [near ; far], car je ne parviens pas à retrouver cette profondeur dans mon fragment shader, cette formule :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    depth = (far-near)*gl_FragCoord.z + near
    Ne semble pas fonctionner. Pourtant après avoir fouillé sur Google il me semble avoir compris qu'un point ayant 0 pour valeur de Z est situé à la distance near par rapport à la caméra et qu'un point ayant 1 pour valeur de Z est situé à far (https://community.khronos.org/t/gl-fragcoord-z/54092).
    Par ailleurs, j'aimerais également savoir comment réaliser des effets de vague sur un plan, apparemment il faut jouer sur la réflexion et la réfraction, j'ai jeté un oeil mais je ne comprends pas ce qu'il faut refléter, le ciel ?

    Merci par avance pour vos éclaircissements.

    P.S : Je ne sais pas ce qu'il se passe mais je n'arrive plus à m'identifier, j'ai dû créer un nouveau compte et changer d'adresse IP pour y parvenir.
    Dernière modification par Invité ; 19/01/2020 à 19h44.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Re, j'ai décidé de changer de méthode : Je récupère les coordonnées de mon fragment et je les multiplie par l'inverse de la matrice de projection, et bien devinez quoi ça ne marche toujours pas. Quelqu'un peut-il me dire ce qui ne va pas dans ce code GLSL :

    Code GLSL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    vec4 a,b,c,d;
     
    a=vec4(1/(ratio*tan(fovy/2)),0,0,0);
    b=vec4(0,1/tan(fovy/2),0,0);
    c=vec4(0,0,-(far+near)/(far-near),-(2*far*near)/(far-near));
    d=vec4(0,0,-1,0);
     
    mat4 matriceProjection=mat4(a,b,c,d);
    mat4 inverseMatriceProjection=1/matriceProjection;
    vec4 positionEspace=inverseMatriceProjection*gl_FragCoord;
     
    depth=sqrt(pow(positionEspace.x,2)+pow(positionEspace.y,2)+pow(positionEspace.z,2));
    Dernière modification par Invité ; 19/01/2020 à 19h43. Motif: Coloration syntaxique [CODE=GLSL] … [/CODE]

  3. #3
    Invité
    Invité(e)
    Par défaut
    Bon j'ai obtenu un début de résultat mais c'est toujours pas ça, je fais un test en demandant au fragment shader de colorer en rouge ce qui est situé à une distance de la caméra supérieure à 8. Voici le code :

    Code GLSL : 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
    void main(void)
    {
        vec4 fragment=gl_FragCoord;
     
        fragment.x/=largFenetre;
        fragment.x*=2;
        fragment.x--;
     
        fragment.y/=hautFenetre;
        fragment.y*=2;
        fragment.y--;
     
        fragment.z*=2;
        fragment.z--;
     
        vec4 positionEspace=gl_ProjectionMatrixInverse*fragment;
        positionEspace/=positionEspace.w;
     
        depth=sqrt(pow(positionEspace.x,2)+pow(positionEspace.y,2)+pow(positionEspace.z,2));
     
        ...
     
        gl_FragColor=texture2D(tex,gl_TexCoord[0].st)*gl_Color;
     
        if(depth>8)
        {
    	gl_FragColor[0]=1;
    	gl_FragColor[1]=0;
    	gl_FragColor[2]=0;
    	gl_FragColor[3]=1;
        }
    }

    Et je n'obtiens qu'une mince bande rouge lorsque la caméra regarde vers le bas :

    Nom : aa.jpg
Affichages : 325
Taille : 73,4 Ko

    Bref c'est bizarre ...

    Edit : Finalement je suis parvenu à résoudre ce problème de distance.
    Dernière modification par Invité ; 19/01/2020 à 19h44.

  4. #4
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 474
    Points
    11 474
    Billets dans le blog
    11
    Par défaut
    Salut !

    Pour inverser une matrice en GLSL, on utilise l'intrinsic "inverse", et pas la division que tu as faite
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  5. #5
    Invité
    Invité(e)
    Par défaut
    Merci mais j'ai trouvé une autre solution finalement, je suis maintenant entrain de me creuser la tête pour faire des reflets, j'ai vu des tutos mais ça ne marche visiblement qu'avec des cubemaps et non des objets

  6. #6
    Invité
    Invité(e)
    Par défaut
    À défaut de reflets je suis entrain de lire des tutos sur les ombres et de découvrir au passage le concept de FBO, il y a une chose que je ne comprends pas : Il est dit qu'il faut placer la caméra à la position de la source lumineuse et regarder dans la direction de la lumière pour ensuite récupérer le contenu du tampon de profondeur dans une shadow map. Seulement voilà : Il faudrait que la caméra voit TOUTE la scène pour que que tous les points de celle-ci soient enregistrés dans la shadow map ? Et comment faire si la source lumineuse est de type ponctuelle ?

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


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    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 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    Pour les lumières ponctuelles, on peut utiliser une cubemap (un ensemble de six textures) et donc, faire que la caméra remplisse les six faces de la texture (en regardant successivement à gauche, à droite, en haut, bas, arrière, avant). Par contre, comme vous le voyez c'est lourd.
    Aussi, on peut considérer que les lumières ponctuelles ne projettent pas d'ombre (car leur lumière est souvent faible).
    Autrement, elles sont souvent implémenter à travers du deferred rendering, mais je ne me rappelle plus comment les ombres sont gérées dans ce cas.
    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.

  8. #8
    Invité
    Invité(e)
    Par défaut
    Merci pour ta réponse, et pour les lumières directionnelles comment on peut faire sachant que dans ce cas la source de lumière est située "à l'infini" ? Bref sinon j'avance, j'ai créé le FBO, récupéré la shadow map envoyée au fragment shader, j'ai ajouté dans le vertex shader le calcul de la distance entre la source de lumière et le point ainsi que les coordonnées de texture dans la shadow map, la difficulté c'est le calcul d'angle entre les vecteurs : J'utilise le produit scalaire et la fonction acos() mais celle-ci ne renvoie pas d'angle négatif.
    Je me demande aussi qu'est-ce qu'il faut utiliser comme paramètres fovy, near et far lorsqu'on positionne la caméra à la place de la source de lumière, car si la source de lumière est trop loin il n'y aura pas d'ombre.
    Dernière modification par Invité ; 16/01/2020 à 00h40.

  9. #9
    Invité
    Invité(e)
    Par défaut
    Bon ben j'ai terminé mais ça ne fonctionne absolument pas, je récupère les matrices modelview et de projection lors du premier rendu et je les envoie au vertex shader lors du deuxième rendu afin de calculer les coordonnées de texture dans la shadow map, j'ignore si qqchose cloche dans mon code :

    Vertex shader :

    Code GLSL : 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
    #version 120
     
    uniform vec4 posLight;
    uniform mat4 projectionLight;
    uniform mat4 modelviewLight;
    out float distLumPoint;		//Envoyé au fragment shader
    out vec4 coordTexShadowMap;
    uniform float fovxSM;
    uniform float fovySM;
    uniform float ratio;
     
    void main(void)
    {
    	//Rendu normal ...
     
    	vec3 vecteurLumPoint={gl_Vertex.x-posLight.x,gl_Vertex.y-posLight.y,gl_Vertex.z-posLight.z};
    	distLumPoint=length(vecteurLumPoint);		//Calcul distance lumière-point
     
    	coordTexShadowMap=projectionLight*modelviewLight*gl_Vertex;		//Calcul coordonnées de texture
     
    	coordTexShadowMap.x/=2;		//[-1 ; 1] => [0 ; 1]
    	coordTexShadowMap.x+=0.5;
     
    	coordTexShadowMap.y/=2;
    	coordTexShadowMap.y+=0.5;
    }

    Fragment shader :

    Code GLSL : 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
    #version 120
     
    uniform sampler2D tex;
     
    in float distLumPoint;		//Reçu du vertex shader
    in vec4 coordTexShadowMap;
    uniform sampler2D shadowMap;
    uniform float nearSM;
    uniform float farSM;
     
    void main(void)
    {
    	//Rendu normal ...
     
    	float couleur=texture2D(shadowMap,coordTexShadowMap.st).x;		//Détermination couleur pixel shadow map
    	float distLumPointProche=(farSM-nearSM)*couleur+nearSM;		//Calcul distance point le plus proche
     
    	if(distLumPointProche<distLumPoint)
    	{
    		gl_FragColor[0]=0.1;		//Assombrissement
    		gl_FragColor[1]=0.1;
    		gl_FragColor[2]=0.1;
    	}
    }

    Il n'y a aucun problème avec la shadow map car lorsque je l'affiche je vois bien le Z-buffer du point de vue de la source de lumière, donc aucun problème niveau FBO.

    Édit : Le problème se situerait dans le fragment shader à la ligne qui détermine la distance entre la source de lumière et le point le plus proche de celle-ci, car j'ai fait le calcul à la main après avoir affiché la shadow map et fait une capture d'écran pour récupérer la couleur sous Photoshop : 960, alors que j'ai positionné la source de lumière juste devant un obstacle, à une distance bien inférieure à 960.

    Édit 2 : J'ai enfin un début de résultat en utilisant une formule issue de l'expression que j'ai trouvée ici mais ce n'est pas encore ça :

    Nom : forum.jpg
Affichages : 301
Taille : 334,2 Ko

    Édit 3 : Impossible de venir à bout du problème, il doit encore y avoir une erreur dans le calcul de la distance entre la source de lumière et le point le plus proche, est-ce que ce code vous paraît faux :

    Code GLSL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    float c;
     
    if(coordTexShadowMap.x>=0&&coordTexShadowMap.x<=1&&coordTexShadowMap.y>=0&&coordTexShadowMap.y<=1)
    {
    	c=texture2D(shadowMap,coordTexShadowMap.st).x;
     
    	float distLumPointProche=1.0/(c*(1/farSM-1/nearSM)+1/nearSM);
     
    	if(distLumPointProche<distLumPoint)
    	{
    		gl_FragColor[0]/=2;
    		gl_FragColor[1]/=2;
    		gl_FragColor[2]/=2;
    	}
    }

    Pour le calcul de la distance je me suis basé sur cette expression :

    Nom : Screenshot_20200116-235658.jpg
Affichages : 298
Taille : 31,8 Ko
    Dernière modification par Invité ; 19/01/2020 à 19h49. Motif: Coloration syntaxique [CODE=GLSL] … [/CODE]

  10. #10
    Invité
    Invité(e)
    Par défaut
    Re, je m'aperçois que mon espèce d'ombre présente toujours le même motif et qu'il ne s'agit de rien d'autre que la shadow map elle-même (Représentée ici en haut à gauche) :

    Nom : forum-1.jpg
Affichages : 286
Taille : 257,5 Ko

    J'ai beau réfléchir dans tous les sens je ne vois vraiment pas d'où ça peut venir, je sollicite vraiment l'aide de quelqu'un, je suis complètement coincé.

  11. #11
    Invité
    Invité(e)
    Par défaut
    Bon je décèle déjà un problème de communication entre mon programme et mon shader, apparemment ce dernier ne reçoit pas les coordonnées de la source de lumière, je fais pour cela un test en colorant en rouge tous les points situés à une certaine distance de la source :

    Vertex shader :

    Code GLSL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    //...
     
    uniform vec3 posLight;
    out float distLumPoint;
     
    void main(void)
    {
    	//...
     
    	vec3 vecteurLumPoint={gl_Vertex.x-posLight.x,gl_Vertex.y-posLight.y,gl_Vertex.z-posLight.z};
    	distLumPoint=length(vecteurLumPoint);
    }

    Fragment shader :

    Code GLSL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    //...
    in float distLumPoint;
     
    void main(void)
    {
    	//...
     
    	if(distLumPoint<=50)
    	{
    		gl_FragColor[0]=1;
    		gl_FragColor[1]=0;
    		gl_FragColor[2]=0;
    	}
    }

    Si je fais ça, rien n'apparaît en rouge, si j'initialise posLight dans mon vertex shader de cette manière:

    Code GLSL : Sélectionner tout - Visualiser dans une fenêtre à part
    uniform vec4 posLight={...};

    Rien non plus ; en revanche, ça fonctionne lorsque j'initialise posLight de sorte à positionner la source de lumière près d'un sommet de la map ...
    Côté programme, voici comment j'envoie les coordonnées de la source de lumière au shader :

    Code GLSL : Sélectionner tout - Visualiser dans une fenêtre à part
    glUniform4f(glGetUniformLocation(shader,"posLight"),posLight[0],posLight[1],posLight[2],posLight[3]);

    Bref je piétine ...

    Édit : J'essaie de calculer la distance entre le point actuel et la source de lumière dans le fragment shader plutôt que dans le vertex shader et pour cela je multiplie gl_FragCoord par gl_ModelViewProjectionMatrixInverse pour avoir les coordonnées du fragment dans le repère 3D puis je calcule la distance entre le résultat obtenu et les coordonnées de la source de lumière mais là encore ça ne marche pas, ça me rend dingue !!!
    Dernière modification par Invité ; 19/01/2020 à 19h48. Motif: Coloration syntaxique [CODE=GLSL] … [/CODE]

  12. #12
    Invité
    Invité(e)
    Par défaut
    Svp que quelqu'un m'aide, je suis totalement dans l'impasse, je n'arrive même pas à réaliser la première étape : Le calcul de la distance entre le fragment et la source de lumière, donnez moi au moins un conseil sur ça

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


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    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 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    Cette réponse est simple : lorsque vous faites une shadow map, la valeur stockée dans la shadow map est une distance ... la distance entre la lumière et l'objet. Mais, dans le cas du rendu, vous avez bien une distance et vous voulez certainement la distance entre la lampe et le fragment en cours d'être rendu. Cela se calcul aisément avec la fonction GLSL : distance(). Mais si vraiment vous voulez le calcul mathématique (normalement inutile pour ce cas précis), c'est la racine carré, de la somme des carrés de la différence des points. Celle décrite ici sur Wikipedia.

    Après, la difficulté, c'est de retrouver quel point de la shadow map correspond à quel fragment en train d'être rendu. Il faut transposer les fragments (et les points de la shadow map) dans un même espace. Pour cela, il faudra utiliser la matrice de modèle view utilisée lors du rendu de la lampe (car les points de la shadowmap existent par rapport à ce référentiel) et transformer les fragments dans ce même espace monde (soit, si je me gourre pas), avant même qu'il ne soit pas transformé par la matrice modèle view utilisée lors du rendu.
    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.

  14. #14
    Invité
    Invité(e)
    Par défaut
    Merci pour ta réponse, en fait je veux calculer la distance entre la lampe et le fragment mais dans le repère 3D et non sur l'écran. Je connais les coordonnées de la source de lumière dans le repère 3D et je connais les coordonnées du fragment sur l'écran, je cherche à en déduire les coordonnées 3D équivalentes, en gros l'inverse de la projection, c'est pourquoi j'ai essayé de multiplier gl_FragCoord par l'inverse de la matrice de projection et modelview mais ça n'a rien donné, j'ai essayé de passer par un système de vecteurs mais toujours sans résultat.

  15. #15
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 474
    Points
    11 474
    Billets dans le blog
    11
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  16. #16
    Invité
    Invité(e)
    Par défaut
    Merci, le deuxième lien va sans doute m'être très utile

  17. #17
    Invité
    Invité(e)
    Par défaut
    J'ai suivi le tuto mais malheureusement aucune ombre n'apparaît ...

    Édit : J'ai résolu le problème finalement, il y avait des variables globales surchargées dans les shaders, j'ai bien des ombres mais le résultat est étrange :

    Nom : forum-2.jpg
Affichages : 262
Taille : 246,3 Ko
    Dernière modification par Invité ; 19/01/2020 à 23h36.

  18. #18
    Invité
    Invité(e)
    Par défaut
    Il y a une chose que je ne comprends pas dans le tuto :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    float CalcShadowFactor(vec4 LightSpacePos)
    {
        vec3 ProjCoords = LightSpacePos.xyz / LightSpacePos.w;
        vec2 UVCoords;
        UVCoords.x = 0.5 * ProjCoords.x + 0.5;
        UVCoords.y = 0.5 * ProjCoords.y + 0.5;
        float z = 0.5 * ProjCoords.z + 0.5;
        float Depth = texture(gShadowMap, UVCoords).x;
        if (Depth < (z + 0.00001))
             return 0.5;
        else
             return 1.0;
    }
    Je ne comprends pas pourquoi on divise les coordonnées de LightSpacePos par W, si on fait ça on aura les coordonnées du fragment dans l'intervalle [near ; far] et non [-1 ; 1], je me trompe ?

  19. #19
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 474
    Points
    11 474
    Billets dans le blog
    11
    Par défaut
    The first step is to perform perspective division - we divide the XYZ components by the W component. This transfers the vector to NDC space
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  20. #20
    Invité
    Invité(e)
    Par défaut
    Oui je viens de relire ce paragraphe. Bref quoi que je fasse j'ai des ombres surgies de nulle part, même si je ne dessine rien dans la première passe, ça défie toute logique ...

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Effet d'eau avec le GLSL
    Par Invité dans le forum Développement 2D, 3D et Jeux
    Réponses: 31
    Dernier message: 03/11/2010, 10h54
  2. Effet goutte d'eau sur une image
    Par hamska2 dans le forum Traitement d'images
    Réponses: 3
    Dernier message: 16/09/2010, 15h16
  3. Effet "eau" sur un control (picturebox)
    Par AliHome dans le forum Windows Forms
    Réponses: 12
    Dernier message: 19/08/2008, 18h05
  4. [AS3] Effet "goutte d'eau"
    Par Pill_S dans le forum ActionScript 3
    Réponses: 4
    Dernier message: 11/08/2007, 14h26
  5. [FLASH 8] Effet avec de l'Eau
    Par °°° Zen-Spirit °°° dans le forum Flash
    Réponses: 4
    Dernier message: 30/06/2006, 15h35

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