如何在OpenGL中创建廉价阴影?

时间:2009-07-11 21:57:57

标签: c opengl 3d shadow

我有两个型号,A和B,还有一个灯,L。我想模型A在模型B上投下阴影。我不想打扰阴影卷或适当的阴影,只是一个简单的圆形阴影就足够了。结果是模型A被视为用于阴影投射目的的球体。

以下是我设想算法的方法:

对于模型B中的每个三角形,绘制三角形。沿着从L到A的直线在三角形上投影圆,根据三角形的距离增加圆的大小。确保将圆圈剪切到三角形的边界(我想,以某种方式使用模板缓冲区)。

我正在使用OpenGL和普通的C。

我可以阅读一些参考文档的指针吗?还是提出想法?

2 个答案:

答案 0 :(得分:9)

我认为实现正确的阴影实际上更容易,因为OpenGL可以为你完成工作。

我在这里找到了一个包含大量文档的工作影子代码:http://www.opengl.org/resources/code/samples/mjktips/TexShadowReflectLight.html

上面的代码将对象呈现两次:首先通常使用特殊矩阵。它做了很多不相关的事情,比如用鼠标控制和反射。所以这是有趣的部分。

这会计算阴影矩阵:

/* 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];

}

我并没有假装完全理解这一点。 lightpos是光源的位置。地平面的前3个坐标是地面的法向矢量。第四个是偏移量(距离0,0,0有多远)。

这部分实际上呈现了阴影:

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

首先需要glEnable / glDisable来实现这一点,所以请看链接。

答案 1 :(得分:0)

This paper似乎涵盖了您的要求,使用OpenGL和硬件加速来创建详细的阴影贴图。

如果我试图做到这一点,我会很想使用光线投射。对于B中的每个三角形,创建一个从三角形到光的矢量。如果它沿途遇到任何东西,那就是阴影。除非你使用一个不错的加速结构和一个快速的三角形击中测试,否则这将会很慢。我喜欢bounding volume hierarchies;许多程序也使用它们进行碰撞检测。