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 :

Shadow Mapping : Reprise de zéro


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Par défaut Shadow Mapping : Reprise de zéro
    Bonjour à tous.

    J'ai décidé de revoir mon approche depuis le début et d'y allez pas à pas pour implémenter avec succèes un algo de shadow mapping. Cette fois je veux être sur de comprendre chaque étape et en pas avoir de surprise à la fin.

    J'ai décidé de repartir sur des bases plus "saines", à base de FBO et de Shader.
    Pour le moment, je suis en train de paramétrer ma première phase : la création de ma depth-map. ma phase d'initialisation est a peu près bonne :

    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
     
    	m_WindowWidth = Application::Instance().m_Settings.m_ScreenWidth ;
    	m_WindowHeight = Application::Instance().m_Settings.m_ScreenHeight ;
     
    	//Check for necessary extensions
    	if ( !glewIsSupported("GL_ARB_depth_texture"))
    		std::cout << "ARB texture *not* supported" << std::endl ;
     
    	if ( !glewIsSupported("GL_ARB_shadow"))
    		std::cout << "Shadow *not* supported" << std::endl ;
     
    	if ( !glewIsSupported("GL_EXT_framebuffer_object"))
    		std::cout << "FBO *not* supported" << std::endl ;
     
    	// Creation  of a depth-texture
    	glActiveTexture(GL_TEXTURE1);
    	glEnable(GL_TEXTURE_2D);
    	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    	glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
    	glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
     
    	glGenTextures(1, &m_ShadowMapTexture);
    	glBindTexture(GL_TEXTURE_2D, m_ShadowMapTexture);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    	glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, m_ShadowMapSize, m_ShadowMapSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
     
    	// Creation of a fbo to get the depth
    	glGenFramebuffersEXT(1, &m_ShadowMapFBO);
    	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_ShadowMapFBO);
    	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, m_ShadowMapTexture, 0);
    	// No color buffer to draw to or read from
    	glDrawBuffer(GL_NONE);
    	glReadBuffer(GL_NONE);
     
    	// Check framebuffer completeness at the end of initialization.
    	CHECK_FBO_STATUS() ;
     
    	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    	glBindTexture(GL_TEXTURE_2D, 0);
    	glActiveTexture(GL_TEXTURE0);
    Je suis en train de faire ma fonction, qui doit se charger de récupérer ma depth-map (celle qui met oepngl dans les bon états, juste avant un premier appel à ma fonction draw() sur les objets de ma scène ).

    Je vois le déroulement comme ceci :
    -je précise à opengl de ne faire le rendu que de la profondeur, et uniquement dans mon fbo qui va me stocker ça dans ma texture de profondeur.
    -je me place du point de vue de la caméra

    J'en suis à ce second point, et je me demande comment choisir une matrice de projection qui va bien? Je n'arrive pas à voir pourquoi on devrait prendre autre-chose que celle courante et si l'on doit, comment bien la choisir ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    	// Set up opengl to render only a depth-map
     
    	// 1 - Use our special FBO
    	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_ShadowMapFBO);
    	glClear(GL_DEPTH_BUFFER_BIT);
     
    	// 2 - Position the camera at the light PoV
    	glMatrixMode(GL_PROJECTION);
    	//gluPerspective?
    	//glOrhto?
    	glMatrixMode(GL_MODELVIEW);
    	// ...
    Ci-dessus le début de ma fonction .

    EDIT : Quelques question que je viens de mailez à un amis et qui montre où j'en suis et ce qu'il me reste à trouvez :

    1) La taille que l'on donne à notre texture de profondeur dépend de celle du viewport exclusivement c'est bien ca? Elle peut-être supérieur ou cela n'aura aucun intérêt et il faut qu'elle soit de même taille ?

    2) Lors de la phase de récupération de la texture de profondeur, on doit se placer du point de vue de la lumière, pour cela il faut modifier les matrice modelview et projection mais comment.?
    2-a) Pour la projection, j'ai cru comprendre qu'il fallait du gluOrtho pour une lumière omnidirectionelle (comme le soleil) mais j'ai du mal à voir les paramètres (left, right, top, bottom, near, far) qu'il faut utiliser et pourquoi? Pour un spot, je supose que l'on va utiliser du gluPerspective ; l'angle doit représenter l'angle d'ouverture du spot, mais j'ai du mla à voir quel ratio et quel "znear et zfar" lui passer en paramètre ... j'ai lu sur le web un ratio de 1 et un znear et zfar faible et proche (2 et 8) mais je ne comprend pas la logique derrière cela.
    2 -b) Pour la modelview, si j'ai un spot , il me faut un gluLookAt avec la position de la lumière, la direction dans laqeulle elle est orientée et enfin le vecteur normal à son orientation, non? Pour une lumière omnidirectionel, a part la position de la lumière, je ne sais pas trop quoi mettre comme 2 et 3eme paramètres.
    EDIT2 : J'ai réflécit et suis arrivé à la conclusion que dans le cas d'un spot et de la matrice de projection, le znear et zfar doivent correspondre à la portée de la lumière, non? SI c'est ça, j'en déduis qu'en glOrtho le near et far sont pareil Ca avance ...( enfin j'espère ^^)

    EDIT3: (oui je raconte ma vie ) Mon cerveau se réveil et me rappel que le 3ème paramètres du glulookAt n'est pas le vectur normal à la direction mais le vecteur "up" de l'origine, donc du (0,1,0) en général

  2. #2
    Membre Expert
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 583
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 583
    Par défaut
    Citation Envoyé par Clad3 Voir le message
    Je vois le déroulement comme ceci :
    -je précise à opengl de ne faire le rendu que de la profondeur, et uniquement dans mon fbo qui va me stocker ça dans ma texture de profondeur.
    -je me place du point de vue de la caméra
    tu te places du point de vue de la lumière
    d'ailleurs tu le fait bien dans le code

    Citation Envoyé par Clad3 Voir le message
    EDIT2 : J'ai réflécit et suis arrivé à la conclusion que dans le cas d'un spot et de la matrice de projection, le znear et zfar doivent correspondre à la portée de la lumière, non? SI c'est ça, j'en déduis qu'en glOrtho le near et far sont pareil Ca avance ...( enfin j'espère ^^)
    dans tous les cas sauf si c'est pour simuler un éclairage par le soleil le zfar doit correspondre à la portée de la lumière

    par contre, jamais ton znear et ton zfar ne doivent etre identique
    peu importe le mode de projection
    en ortho, ton znear et ton zfar ne sont pas identiques
    d'ailleurs, dans la doc de glOrtho :
    GL_INVALID_VALUE is generated if left = right, or bottom = top, or near = far.
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  3. #3
    Membre éclairé
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Par défaut
    Oula il devait être tard , je me suis mal exprimé

    Effectivement, simple faute de frappe caméra/lumière.

    Pour le zfar != znear, aussi . j'ai voulu dire que le principe du far et near était identique en gluperspective et GlOrhto , enfin que le raisonement était sensiblement le même et que donc si j'avais compris le premier, j'avais compris le second !

    Allez, j'entame l'application de ma texture de profondeur sur m a scène avec mes shaders ...miam !

  4. #4
    Membre éclairé
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Par défaut
    En fait, je remarque que ce qui me pose problème c'est d'avoir du mal à savoir si ce que je code est bon où pas, avant de déchanter devant le résultat final :/

    J'ai codé jusqu'au bout et à la vue des maigres résultats, je vais tenter de suivre pas à pas si ce que je fais est bon.

    1- afficher ma texture de profondeur : Je l'ai fait, juste après l'avoir calculé, sur un quad simple. Ca m'a l'air k, mais qu'en pensez-vous? Je plaque ma texture sur le seul objet qui gène, puis , une fois mon programme lancé, je navigue avec ma caméra pour me mettre à la place de lalumière pour voir si de ce point de vue c'est bien bon. Ca donne le screenshot en annexe. On dirait bien du sombre pour le quad qui gène la vue et une ombre plus légère dans l'angle de direction de la lumière, ca me semble OK.
    (sur le screen, ma caméra regarde aussi ou est dirigée la lumière).

    2- Tester si ma matrice de texture que je passe à mon shader est bonne.
    La je nai aucune idée de comment faire et j'ai d'ailleurs de gros doutes sur ce que j'ai fait comme calcul.

    - Je me me en mode GL_TEXTURE
    - Je charge l'identité
    - Je multiplie par la matrice de bias qui fait passer nos valeurs de -1,1 en 0,1
    - je multiplie par la mtrice de projection de ma lumière ( la même que lros de la phase de récupération de la texture de profondeur)
    - je multiplie par la matrice de modelview de ma lumière ( la même que lors de la phase de récupération de la texture de profondeur)
    -fin

    Si je ne me suis pas tropé jusqu'e là, je pourrais passer à la suite Mais j'ai de gros doutes ;o)
    Images attachées Images attachées  

  5. #5
    Membre éclairé
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Par défaut
    J'ai simplfié au possible le code, et totu regroupé pour y voir plus clair :

    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
     
    void ShadowMappingManager::All()
    {
    	// 1 - Set up opengl to render only a depth-map
    	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_ShadowMapFBO);
    	glClear(GL_DEPTH_BUFFER_BIT);
    	glEnable(GL_DEPTH_TEST);
    	glMatrixMode(GL_PROJECTION);
    	glPushMatrix();
    	glLoadIdentity();
    	gluPerspective(45.0f, 1.0f, 1.0f, 10.0f);
    	glMatrixMode(GL_MODELVIEW);
    	gluLookAt(m_LightPos.x, m_LightPos.y,m_LightPos.z,   0.0, 0.0, 0.0,         0.0, 1.0, 0.0 );
    	glGetFloatv(GL_MODELVIEW_MATRIX, Light_M);
    	glGetFloatv(GL_PROJECTION_MATRIX, Light_P);
    	glPushAttrib(GL_VIEWPORT_BIT);
    	glViewport(0,0,m_ShadowMapSize,m_ShadowMapSize);
    	glEnable(GL_POLYGON_OFFSET_FILL);
    	Draw();
    	glDisable(GL_POLYGON_OFFSET_FILL);
    	glPopAttrib();
    	glMatrixMode(GL_PROJECTION);
    	glPopMatrix();
    	glMatrixMode(GL_MODELVIEW);
    	glPopMatrix();
     
    	// 2 - Apply the depth map
    	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    	glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
    	gluPerspective(45.0,(float) m_WindowWidth/m_WindowHeight,0.1,100.);
    	glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    	Application::Instance().m_RenderTask.Cam.Focalize();
     
    	glMatrixMode(GL_TEXTURE);
    	glActiveTexture(GL_TEXTURE1);
    	glLoadIdentity();
    	float M[16] = 
    	{
    		0.5f, 0.0f, 0.0f, 0.0f,
    		0.0f, 0.5f, 0.0f, 0.0f,
    		0.0f, 0.0f, 0.5f, 0.0f,
    		0.5f, 0.5f, 0.5f, 1.0f,
    	};
    	glLoadMatrixf(M);
    	glMultMatrixf(Light_P);
    	glMultMatrixf(Light_M);
     
    	glActiveTexture(GL_TEXTURE1);
    	glEnable(GL_TEXTURE_2D);
    	glBindTexture(GL_TEXTURE_2D, m_ShadowMapTexture);
    	ShaderManager::Instance().UseShader("ShadowMapping");
    	Draw();
    	ShaderManager::Instance().UseShader(0);
    	glBindTexture(GL_TEXTURE_2D, 0);
    	glDisable(GL_TEXTURE_2D);
    }
    mon vertex prog :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    varying vec4 projCoord;
     
    void main(void)
    {
    	projCoord = gl_TextureMatrix[1] * gl_ModelViewMatrix * gl_Vertex;
     
    	gl_Position = ftransform();
    }
    mon frag prog ( une version simpliste pour tester si ca marche)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    uniform sampler2DShadow shadow0;
    varying vec4 projCoord;
     
    void main(void)
    {
    	vec4 s = shadow2DProj(shadow0, projCoord);
     
    	gl_FragColor = vec4(1.0,0.0,0.0,1.0)*s;
    }
    Il m'affiche tout en rouge, je dois oublier quelquchose ...
    (je remet au cas ou ma fonction d'init )

    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
     
    void ShadowMappingManager::Init()
    {
    	m_WindowWidth = Application::Instance().m_Settings.m_ScreenWidth ;
    	m_WindowHeight = Application::Instance().m_Settings.m_ScreenHeight ;
     
    	//Check for necessary extensions
    	if ( !glewIsSupported("GL_ARB_depth_texture"))
    		std::cout << "ARB texture *not* supported" << std::endl ;
     
    	if ( !glewIsSupported("GL_ARB_shadow"))
    		std::cout << "Shadow *not* supported" << std::endl ;
     
    	if ( !glewIsSupported("GL_EXT_framebuffer_object"))
    		std::cout << "FBO *not* supported" << std::endl ;
     
    	// Creation  of a depth-texture
    	glActiveTexture(GL_TEXTURE1);
    	glEnable(GL_TEXTURE_2D);
    	//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    	//glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
    	//glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
     
    	glGenTextures(1, &m_ShadowMapTexture);
    	glBindTexture(GL_TEXTURE_2D, m_ShadowMapTexture);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,     GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,     GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
    	glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, m_ShadowMapSize, m_ShadowMapSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
     
    	// Creation of a fbo to get the depth
    	glGenFramebuffersEXT(1, &m_ShadowMapFBO);
    	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_ShadowMapFBO);
    	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, m_ShadowMapTexture, 0);
    	// No color buffer to draw to or read from
    	glDrawBuffer(GL_NONE);
    	glReadBuffer(GL_NONE);
     
    	// Check framebuffer completeness at the end of initialization.
    	CHECK_FBO_STATUS() ;
     
    	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    	glBindTexture(GL_TEXTURE_2D, 0);
    	glActiveTexture(GL_TEXTURE0);
     
    	GLfloat white[]= { 1.0f, 1.0f, 1.0f, 1.0f };
    	Vector3D<float> LightPos = Vector3D<float>(1.0f, 1.0f,1.0f);
    	float LP[3];
    	LP[0] = LightPos.x ;
    	LP[1] = LightPos.y ;
    	LP[2] = LightPos.z ;
    	glLightfv(GL_LIGHT0, GL_POSITION, LP);
    	glLightfv(GL_LIGHT0, GL_SPECULAR,white);
    	glLightfv(GL_LIGHT0, GL_AMBIENT,white);
    	glLightfv(GL_LIGHT0, GL_DIFFUSE,white); 
     
    	// Load the shader
    	ShaderManager::Instance().LoadShaders("ShadowMapping","sm.vert","sm.frag");
    	Loc_Dif = ShaderManager::Instance().AddUniformVariable("ShadowMapping","diffuse");
    	Loc_Shad = ShaderManager::Instance().AddUniformVariable("ShadowMapping","shadow0");
    	ShaderManager::Instance().SetUniformVariableValue1i("ShadowMapping",Loc_Dif,0);
    	ShaderManager::Instance().SetUniformVariableValue1i("ShadowMapping",Loc_Shad,1);
    }
    Je ne sais pas trop quoi tester pour trouvé le "hic".

Discussions similaires

  1. [Direct3D] Shadow Mapping
    Par razmott dans le forum DirectX
    Réponses: 10
    Dernier message: 24/03/2008, 12h45
  2. Questions sur les Shadow Maps
    Par funkydata dans le forum DirectX
    Réponses: 4
    Dernier message: 25/10/2007, 13h58
  3. Shadow volume ou shadow mapping ?
    Par zenux dans le forum Moteurs 3D
    Réponses: 8
    Dernier message: 14/03/2007, 12h34
  4. Shadow map
    Par Wyatt dans le forum OpenGL
    Réponses: 4
    Dernier message: 19/01/2006, 17h48
  5. Shadow mapping
    Par Pen² dans le forum OpenGL
    Réponses: 4
    Dernier message: 22/04/2005, 14h35

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