iPhone 游戏 2d 阴影
Posted
技术标签:
【中文标题】iPhone 游戏 2d 阴影【英文标题】:iPhone game 2d shadows 【发布时间】:2010-10-17 19:15:48 【问题描述】:我们正在使用cocos2d 创建一款 iPhone 游戏。我们正在尝试将多个 sprite 叠加在一起并让它们投射阴影。
现在阴影被渲染为精灵,在大多数情况下都可以正常工作。但我们只希望阴影击中最近的图层。
我制作了一张图片,希望能解释我们正在努力实现的目标:
这就是我们目前拥有的:
基本上,我们希望精灵只渲染与 z-buffer 相同深度的阴影部分。
我们尝试了glDepthFunc
和GL_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 游戏中保存高分和加载高分
当用户第二次打开 cocos2d-iphone 时,如何更改第一个场景?