Essayer de comprendre la lumière sur Opengl, comment simuler une lumière solaire réaliste?

13

Je ne sais pas si je fais quelque chose de mal ou si je manque quelque chose, mais je veux simuler la lumière du soleil, comme par temps ensoleillé.

Lorsque l'objet fait face à la lumière directionnelle, il est bien éclairé et il n'y a aucun problème. Si je contourne l'objet et que je le regarde, il fait noir. Ce n'est pas trop sombre parce que j'utilise GL_AMBIENTmais c'est encore trop sombre pour une journée ensoleillée. Si j'augmente la valeur, elle n'aura jamais meilleure apparence car le côté de l'objet faisant face à la lumière sera trop lumineux.

Et il y a un autre problème gênant avec la lumière ambiante, lorsque je regarde l'arrière de l'objet, je ne vois aucune forme, seulement une couleur unie. Difficile à expliquer, voici quelques photos:

Face de l'objet: http://i.stack.imgur.com/YW53X.png Face de l'
objet: http://i.stack.imgur.com/Qufha.png

Comme vous pouvez facilement le voir, la face avant a l'air bien, vous pouvez voir la forme de cette chose rouge. Au dos, c'est simple, on ne voit pas la même forme.

Maintenant, je sais que je regarde à l'arrière d'un objet et que je regarde dans le sens de la lumière et qu'il devrait être plus sombre que la face avant. Mais cela ne devrait pas ressembler à ça. Ce n'est pas ce que nous voyons quand nous allons contre la lumière du soleil en regardant un objet, nous voyons que les objets forment une forme.

Comment puis-je avoir le même effet (ou similaire) sur OpenGL?

Ma lumière est actuellement définie comme ceci:

float posLight0[4] = {-1.0f, 1.0f, 1.0f, 0.0f};
float ambLight0[4] = {0.5f, 0.5f, 0.5f, 0.5f};

glLightfv(GL_LIGHT0, GL_POSITION, posLight0);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambLight0);
rfgamaral
la source
Je suggère que vous envisagiez d'utiliser des shaders, si possible. Le pipeline à fonction fixe OpenGL utilise un modèle d'éclairage assez simple, tandis que les shaders vous donnent un contrôle total sur les mathématiques.
Incredulous Monk

Réponses:

11

Avec la lumière ambiante, vos objets apparaissent trop brillants car la lumière diffuse est ajoutée à la lumière ambiante et la lumière diffuse par défaut à 1,0. Cela s'ajoute à 1,5, et tout ce qui est supérieur à 1,0 est limité. Réglez la lumière diffuse sur 0,5:

float difLight0[4] = {0.5f, 0.5f, 0.5f, 1.0f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, difLight0);

Le deuxième problème est plus difficile à résoudre. Vous pouvez essayer d'ajouter quelques détails fins à la surface tels que la texture ou la texture de relief. Dans OpenGL, la lumière ambiante est constante, mais dans le monde réel, ce n'est jamais le cas. Pour simuler le monde réel, une certaine forme de solution d' éclairage global est nécessaire. L'occlusion ambiante aide beaucoup ici, mais est plus difficile à mettre en œuvre que la simple définition d'états OpenGL. Vous pouvez cuire l'occlusion ambiante aux sommets de votre modèle dans votre logiciel de modélisation 3D ou utiliser SSAO , mais je ne vais pas dans les détails.

Ce que vous pouvez facilement faire, c'est ajouter une autre source de lumière à variateur provenant d'une autre direction (par exemple une direction opposée). Ce ne sera pas réaliste, mais au moins cela donnera également une certaine forme à l'arrière de vos objets.

Pensez également à ajouter des reflets spéculaires à votre application. Cela rendra les objets brillants.

float specLight0[4] = {0.5f, 0.5f, 0.5f, 1.0f};
glLightfv(GL_LIGHT0, GL_SPECULAR, specLight0);
glMaterialfv(GL_FRONT, GL_SHININESS, 10.0f); // Shininess between 0 and 128

Vous pouvez également spécifier séparément les couleurs de lumière et de matériau, surtout si les valeurs par défaut ne vous conviennent pas.

msell
la source
Il n'y a donc pas de moyen simple et direct de faire ce que je veux dans OpengGL ... Dommage. J'essaierai peut-être d'ajouter une autre source de lumière, mais comment spécifier exactement l'intensité lumineuse?
rfgamaral
Le GL_SPECULARet GL_SHININESSne semble pas produire d'effet cependant ... J'ai changé glMaterialfven glMaterialicar il ne compilait pas. Et aussi essayé une valeur plus grande comme 128. Il me semble la même chose ... Peut-être que le problème est sur mon modèle chargé (obj / mtl), devra y jeter un œil.
rfgamaral
1
@Nazgulled Je viens de vérifier que le spéculaire light0 par défaut est 1.0, mais que le spéculaire matériel par défaut est 0.0. Modifiez donc glLightfv (GL_LIGHT0, GL_SPECULAR, specLight0); à glMaterialfv (GL_FRONT, GL_SPECULAR, specLight0); Il est également bon de définir glLightModeli (GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); ou le spéculaire peut être calculé incorrectement lorsque la caméra tourne.
msell
1
@Nazgulled Pour la lumière secondaire, réglez l'ambiant et le spéculaire sur zéro et une petite valeur comme 0,2 pour le diffus. Vous pouvez également définir la température ambiante de toutes les lumières sur zéro et utiliser la température ambiante globale avec GL_LIGHT_MODEL_AMBIENT à la place.
msell
2

La lumière ambiante d'OpenGL est une seule couleur, mais la lumière ambiante dans le monde réel est généralement plus claire d'en haut et plus sombre d'en bas. Vous pouvez approximer cela dans OpenGL en réglant la lumière ambiante sur un bleu très foncé et en ajoutant une lumière directionnelle bleu foncé pointant vers le bas. Cela, plus une lumière directionnelle blanche brillante provenant de partout où le soleil est, peut approximativement assez bien la lumière extérieure.

Ce que vous devez vraiment faire, c'est écrire un shader qui calcule la lumière par pixel, mais y arriver à partir de là va prendre un peu de temps.

bmcnett
la source
1

La réponse que vous avez obtenue est plutôt bonne. Un seul ajout. Une fois que vous voudrez le rendre plus agréable, essayez de mettre en œuvre la diffusion atmosphérique

Notabene
la source