iPhone 游戏 2d 阴影

Posted

技术标签:

【中文标题】iPhone 游戏 2d 阴影【英文标题】:iPhone game 2d shadows 【发布时间】:2010-10-17 19:15:48 【问题描述】:

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

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

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

这就是我们目前拥有的:

基本上,我们希望精灵只渲染与 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 ),我们正在清除每一帧的深度缓冲区。

任何帮助将不胜感激!

【问题讨论】:

【参考方案1】:
glDepthFunc(GL_LESS)

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

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

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

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

您在某种程度上将深度缓冲区用作替代模板,旧 iPhone 不支持。

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

【讨论】:

谢谢!使用您的方法,我能够得到我们正在寻找的结果,不幸的是以帧速率为代价。现在它按预期工作了,我可以开始寻找优化性能的方法。

以上是关于iPhone 游戏 2d 阴影的主要内容,如果未能解决你的问题,请参考以下文章

如何在 cocos2d iphone 游戏中保存高分和加载高分

iPhone:Quartz2d 与 OpenGL ES

在 Iphone 中实现 MVC

当用户第二次打开 cocos2d-iphone 时,如何更改第一个场景?

Cocos2d iphone 应用程序在实际 iphone 上运行异常

Cocos2d-iphone - Sphero 集成