Tratando de entender la luz en Opengl, ¿cómo simular una luz solar realista?


13

No sé si estoy haciendo algo mal o me falta algo, pero quiero simular la luz del sol, como en un día soleado.

Cuando el objeto se enfrenta a la luz direccional, está bien iluminado y no hay problemas allí. Si rodeo el objeto y lo miro, está oscuro. No está demasiado oscuro porque lo estoy usando, GL_AMBIENTpero todavía está demasiado oscuro para un día soleado. Si aumento el valor, nunca se verá mejor porque el lado del objeto que mira hacia la luz será demasiado brillante.

Y hay otro problema molesto con la luz ambiental, al mirar la parte posterior del objeto, no puedo ver ninguna forma, solo un color liso. Difícil de explicar, aquí hay algunas fotos:

Parte delantera del objeto: http://i.stack.imgur.com/YW53X.png
Parte posterior del objeto: http://i.stack.imgur.com/Qufha.png

Como puede ver fácilmente, la parte frontal se ve bien, puede ver la forma de esa cosa roja. En la parte posterior, es simple, no puedes ver la misma forma.

Ahora, sé que estoy mirando la parte posterior de un objeto y estoy mirando en la dirección de la luz y debería ser más oscura que la parte frontal. Pero no debería verse así de claro. Eso no es lo que vemos cuando vamos contra la luz del sol mirando algún objeto, vemos que los objetos tienen alguna forma.

¿Cómo puedo tener el mismo efecto (o similar) en OpenGL?

Mi luz actualmente se define así:

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);

Sugiero que considere usar sombreadores, si es posible. La tubería de función fija OpenGL utiliza un modelo de iluminación bastante simple, mientras que los sombreadores le dan control total sobre las matemáticas.
Monje

Respuestas:


11

Con la luz ambiental, sus objetos aparecen demasiado brillantes porque la luz difusa se agrega a la luz ambiental y la luz difusa se establece de manera predeterminada en 1.0. Esto suma hasta 1.5, y todo lo que está por encima de 1.0 está sujeto. Establezca la luz difusa en 0.5:

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

El segundo problema es más difícil de resolver. Puede intentar agregar algunos detalles finos a la superficie, como la textura o el mapa de relieve. En OpenGL la luz ambiental es constante, pero en el mundo real ese nunca es el caso. Para simular el mundo real, se necesita alguna forma de solución de iluminación global . La oclusión ambiental ayuda mucho aquí, pero es más difícil de implementar que solo establecer los estados de OpenGL. Puede hornear la oclusión ambiental a los vértices de su modelo en su software de modelado 3D o usar SSAO , pero no voy a los detalles.

Lo que puede hacer fácilmente es agregar otra fuente de luz más tenue desde otra dirección (por ejemplo, dirección opuesta). Esto no será realista, pero al menos también dará cierta forma a la parte posterior de sus objetos.

También considere agregar aspectos destacados especulares a su aplicación. Hará que los objetos brillen.

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

También puede especificar colores de luz y materiales por separado, especialmente si los valores predeterminados no son adecuados para usted.


Así que no hay una manera simple y directa de hacer lo que quiero en OpengGL ... Lástima. Tal vez intente agregar otra fuente de luz, pero ¿cómo especifico exactamente la intensidad de la luz?
rfgamaral 05 de

El GL_SPECULARy GL_SHININESSno parecen producir ningún efecto, aunque ... que hice el cambio glMaterialfva glMaterialiporque no estaba compilando. Y también probé un valor mayor como 128. A mí me parece lo mismo ... Tal vez el problema esté en mi modelo cargado (obj / mtl), tendré que echarle un vistazo.
rfgamaral

1
@Nazgulled Acabo de comprobar que la especularidad light0 tiene un valor predeterminado de 1.0, pero la especularidad del material tiene un valor predeterminado de 0.0. Entonces cambie glLightfv (GL_LIGHT0, GL_SPECULAR, specLight0); a glMaterialfv (GL_FRONT, GL_SPECULAR, specLight0); También es bueno establecer glLightModeli (GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); o el especular podría calcularse incorrectamente cuando la cámara está girando.
msell

1
@ Nazgulled Para la luz secundaria, configure el ambiente y especular a cero y algún valor pequeño como 0.2 para el difuso. También puede establecer el ambiente de todas las luces en cero y utilizar el ambiente global con GL_LIGHT_MODEL_AMBIENT en su lugar.
msell

2

La luz ambiental de OpenGL es de un solo color, pero la luz ambiental en el mundo real suele ser más brillante desde arriba y más oscura desde abajo. Puede aproximar esto en OpenGL configurando la luz ambiental en azul muy oscuro y agregando una luz direccional azul oscuro que apunta hacia abajo. Eso, más una luz direccional blanca brillante que viene de donde sea que esté el sol, puede aproximarse bastante bien a la luz exterior.

Lo que realmente debería hacer es escribir un sombreador que calcule la luz por píxel, pero llegar desde donde se va a tomar un poco de tiempo.


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.