2

我们正在使用cocos2d创建一个 iPhone 游戏。我们正在尝试将多个精灵层叠在一起并让它们投射阴影。

现在阴影被渲染为精灵,在大多数情况下都可以正常工作。但我们只希望阴影击中最近的图层。

我制作了一张图片,希望能解释我们正在努力实现的目标:

这就是我们目前所拥有的:

基本上我们希望精灵只渲染与 z-buffer 相同深度的阴影部分。

我们玩过glDepthFuncGL_DEPTH_TEST但似乎没有任何效果。

下面是我们如何渲染阴影精灵(CCSprite 的子类):

- (void)draw {

    glDisable( GL_BLEND );

    glEnable( GL_DEPTH_TEST );
    glDepthFunc( GL_LESS );

    glDepthMask( GL_FALSE );
    [super draw];
    glDepthMask( GL_TRUE );

    glDisable( GL_DEPTH_TEST );

    glEnable( GL_BLEND );
}

调用只是在GL_BLEND那里,所以我们可以随时看到精灵。

所有不是阴影的精灵都使用glDepthMask( GL_TRUE ),我们正在清除每一帧的深度缓冲区。

任何帮助将非常感激!

4

1 回答 1

1
glDepthFunc(GL_LESS)

实际上是默认值;它的意思是“仅当当前在深度缓冲区中的东西更远时才绘制像素”。如果你想要完全相等,你会使用 glDepthFunc(GL_EQUAL),但在实践中,如果你这样做,你会得到各种各样的舍入奇怪。

假设您能够为此目的使用深度值,如果您有十个对象,那么我建议您:

  1. 在 glClear 之前将 glClearDepth 设置为 0;这将用最接近的可存储值填充深度缓冲区,以便使用正常的深度缓冲不会绘制任何其他内容。
  2. 禁用深度并绘制阴影,例如它们应该落在背板上;此时,您的深度缓冲区仍将充满最接近的可能值。
  3. 启用深度测试,但将 glDepthFunc 设置为 GL_ALWAYS。然后按照从后到前的顺序绘制所有实心矩形,并适当设置它们的深度值。
  4. 将 glDepthFunc 设置为 GL_LESS 并绘制打算落在其他精灵上的阴影,每个精灵的位置都比它们关联的精灵更靠后,但在后面的精灵前面。

到第 4 步时,您将在每个绘制精灵的地方都获得正确的深度信息,并且无论背景平面在哪里,您都将设置最接近的可能值。因此,正常的深度测试将对中间阴影起作用——它们将绘制在步骤 3 中绘制的任何内容之上,但不会绘制在步骤 2 中绘制的任何内容之上。

您有点使用深度缓冲区作为替代模板,旧 iPhone 不支持。

如果您不能为此任务使用深度缓冲区,那么我所能想到的就是将阴影投影为第二个纹理单元中的纹理,使用第一个作为蒙版纹理(或者如果您实际上正在绘制矩形,则不使用,但我猜你可能不是)并且每个精灵每个落在它上面的阴影都进行一次渲染。这是一个可以接受的解决方案吗?

于 2010-10-17T23:58:52.940 回答