2009-07-11 19 views
15

Tengo dos modelos, A y B, y uno ligero, L. Me gustaría que el modelo A arroje una sombra sobre el modelo B. No quiero molestarme con los volúmenes de sombra o las sombras adecuadas por el momento, solo un simple la sombra circular será suficiente. El efecto es que el modelo A se trata como una esfera para propósitos de colada en la sombra.¿Cómo creo sombras baratas en OpenGL?

Así es como puedo imaginar el algoritmo:

Para cada triángulo en el modelo B, dibujar el triángulo. Proyecta un círculo en el triángulo a lo largo de la línea de la L a la A, incrementando el tamaño del círculo dependiendo de qué tan lejos esté el triángulo. Asegúrate de que el círculo esté recortado en los límites del triángulo (usando el buffer de esténcil de alguna manera, me imagino).

estoy trabajando con OpenGL y llano C.

Cualquier punteros en algunos documentos de referencia que puedo leer? O ideas de implementación?

Respuesta

9

Creo que es realmente más fácil implementar sombras correctas porque OpenGL puede hacer el trabajo por usted.

I encontrado un código sombra de trabajo con una gran cantidad de documentación aquí: http://www.opengl.org/resources/code/samples/mjktips/TexShadowReflectLight.html

El código anterior hace que el objeto dos veces: primero normalmente luego con una matriz especial. Hace muchas cosas no relacionadas, como el control con el mouse y las reflexiones. Así que aquí están las partes interesantes.

Este calcula la matriz de la sombra:

/* Create a matrix that will project the desired shadow. */ 
void 
shadowMatrix(GLfloat shadowMat[4][4], 
    GLfloat groundplane[4], 
    GLfloat lightpos[4]) 
{ 
    GLfloat dot; 

    /* Find dot product between light position vector and ground plane normal. */ 
    dot = groundplane[X] * lightpos[X] + 
    groundplane[Y] * lightpos[Y] + 
    groundplane[Z] * lightpos[Z] + 
    groundplane[W] * lightpos[W]; 

    shadowMat[0][0] = dot - lightpos[X] * groundplane[X]; 
    shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y]; 
    shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z]; 
    shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W]; 

    shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X]; 
    shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y]; 
    shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z]; 
    shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W]; 

    shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X]; 
    shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y]; 
    shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z]; 
    shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W]; 

    shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X]; 
    shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y]; 
    shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z]; 
    shadowMat[3][3] = dot - lightpos[W] * groundplane[W]; 

} 

No pretendo entender esto por completo. lightpos es la posición de la fuente de luz. Las primeras 3 coordenadas del plano de tierra son el vector normal de la superficie del terreno. El cuarto es el desplazamiento (qué tan lejos está de 0,0,0).

Y esta parte realmente hace que la sombra:

glPushMatrix(); 
/* Project the shadow. */ 
glMultMatrixf((GLfloat *) floorShadow); 
drawDinosaur(); 
glPopMatrix(); 

Hay algunas cosas que hay que glEnable/glDisable primero para que esto funcione a fin de buscar en el enlace.

+4

Esto simplemente "aplana" el modelo en un plano ... bueno para proyectar una sombra sobre una superficie plana. El OP quiere renderizar la sombra en un objeto 3d con forma arbitraria. –

+0

Esto supuestamente puede hacer eso: http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=27 Lamentablemente no puedo compilarlo con gcc. – stribika

+0

Este método parece bueno, pero el costo de dibujar el modelo de origen una vez para cada cara en B parece alto. ¿Hay alguna manera de reducir la complejidad de este método? – Martin

0

This paper parece cubrir sus requisitos, utilizando OpenGL y aceleración de hardware para crear un mapa de sombras detallado.

Si estuviera tratando de lograr esto, me sentiría tentado a utilizar el molde de rayos. Para cada triángulo en B, crea un vector del triángulo a la luz. Si golpea algo en el camino, está en la sombra. Esto sería un poco lento a menos que estuvieras usando una estructura de aceleración decente y una prueba rápida de ataque de triángulo. Me gusta bounding volume hierarchies; muchos programas también los usan para la detección de colisiones.

Cuestiones relacionadas