如何在 OpenGL 中创建廉价的阴影? [英] How Do I Create Cheap Shadows In OpenGL?

查看:25
本文介绍了如何在 OpenGL 中创建廉价的阴影?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个模型 A 和 B,一个灯 L.我希望模型 A 在模型 B 上投下阴影.我暂时不想打扰阴影体积或适当的阴影,只是一个简单的圆形阴影就足够了.效果是模型 A 被视为用于投射阴影的球体.

I have two models, A and B, and one light, L. I would like model A to cast a shadow on model B. I don't want to bother with shadow volumes or proper shadows for the moment, just a simple circle shadow will suffice. The effect is that model A is treated as a sphere for shadow casting purposes.

这是我设想的算法:

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

For each triangle in model B, draw the triangle. Project a circle onto the triangle along the line from L to A, increasing the size of the circle depending on how far away the triangle is. Ensure the circle is clipped to the triangle's boundaries (using the stencil buffer in some way, I imagine).

我正在使用 OpenGL 和普通 C.

I'm working with OpenGL and plain C.

关于我可以阅读的一些参考文档的任何指示?还是实施思路?

Any pointers on some reference documentation I can read? Or implmentation ideas?

推荐答案

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

I think it is actually easier to implement correct shadows because OpenGL can do the work for you.

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

I found a working shadow code with lots of documentation here: http://www.opengl.org/resources/code/samples/mjktips/TexShadowReflectLight.html

上面的代码对对象进行了两次渲染:第一次是正常的,然后是一个特殊的矩阵.它做了很多不相关的事情,比如用鼠标和反射进行控制.所以这里是有趣的部分.

The code above renders the object twice: first normally then with a special matrix. It does a lot of unrelated things such as control with mouse and reflections. So here are the interesting parts.

计算阴影矩阵:

/* 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多远).

I do not pretend to understand this completely. lightpos is the position of the light source. The first 3 coordinates of groundplane are the normal vector of the ground surface. The fourth is the offset (how far is it from 0,0,0).

这部分实际上渲染了阴影:

And this part actually renders the shadow:

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

有些事情你需要先glEnable/glDisable才能工作,所以看看链接.

There are some things you need to glEnable/glDisable first for this to work so look at the link.

这篇关于如何在 OpenGL 中创建廉价的阴影?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆