我将使用什么渲染技术为卡片游戏中的卡片绘制阴影效果?

什么types的阴影algorithm可能被用来创建像这样的阴影? 在这里输入图像描述

我正在做的是类似的,但都是由OpenGL的2D绘图API,所以没有Z坐标。

此外,对于手本身,我真的想得到一个像这里看到的阴影感觉: 在这里输入图像描述

我只是不知道如何实现一个阴影看起来接近。

牌的数量必然会改变,牌被扔到桌子上,所以我不能使用任何types的光照贴图。

我应该研究哪些algorithm(除了我知道需要做的模糊处理之外)?

谢谢

更新

我在做一个2D纸牌游戏。 我想添加从卡片的偏移量,有点像:

在这里输入图像描述

我正在考虑的方式是:

  • 保持与后缓冲器大小相同的纹理。
  • 画黑色矩形作为临时卡到该纹理。

  • 模糊纹理。

  • 把我的牌画到那个纹理上。
  • 在卡上做额外的照明。
  • 将这个纹理绘制到后缓冲区。

我的问题是:

  • 这是正确的方法吗?

  • 有没有办法做到不渲染纹理(保持位图
    和backbuffer一样大)?

  • 假定纹理的最大尺寸不会是安全的
    超过缓冲器大小? (我的意思是,如果缓冲器
    是2000×3000,那么可以安全地说,我可以创建一个纹理
    video内存的大小?

谢谢

我想每个人都在为这个问题提供太复杂的解决scheme。

在这里输入图像描述

首先,我们有卡(或者任何你想绘制的),这里用(a)来描述。 接下来,我们把它的一个副本,填充黑色,运行高斯模糊(二)。 所有这一切发生在Photoshop或任何你最喜欢的艺术工具。

接下来,在游戏中,当我们想要绘制卡片时,首先绘制带有乘法(或alpha)混合的模糊的黑色图像,稍微向某个方向偏移,然后将卡片绘制在最上面。 瞧。

为了进一步欺骗,你可以在阴影和卡片渲染之间交替,以得到像(d)一样的效果,或者先画出所有的阴影,然后是卡片,就像在(e)中(我在(e)还是分开=)

最好不要使用纯黑色(或全alpha)的阴影来创建更细微,透明的阴影。

第一个不是太难。 如果你为你的手牌渲染一个alpha通道(对于一个有卡片的像素,它可以像黑色一样简单,白色是透明的),你可以在alpha通道上执行任何你想要的模糊,然后抵消它,并使用它来控制表的照明。 (大概,如果你没有Z缓冲区,你必须首先渲染掉某个地方的alpha通道,然后用掩码来做表格, 然后渲染实际的卡片。)

第二个看起来有点像SSAO(屏幕空间环境遮挡)。 该技术需要Z坐标。 然而,如果你没有卡片之间的角度(这是我猜测,如果你没有Z缓冲区),你可以做一个很好的近似,为每个渲染一个阴影(如第一个)卡。 虽然性能可能有点棘手,但是每架飞机上面的所有飞机都需要一个模糊的alpha通道,如果桌面上有一堆牌,那么可能会有不less渲染过程。

你不能做一个阴影地图吗? 将场景渲染为fbo。 只保存深度值并在着色器中进行正常的深度值检查,以查看是否应该渲染阴影。

以下过程不需要屏幕外渲染目标。 但是,这样做,就得到了先画表格的要求。 或者至less,在绘制表格之前,桌子上的像素都没有绘制。 它还要求表本身是一个单一的,不重叠的部分:一个图像。

另外,你的framebuffer需要一个alpha组件。

  1. 获取一张卡片的灰度图像。 使它在边缘模糊,可能会扩大其大小。 这是你的影子影像。 请注意,这是一个单通道图像。 在着色器中访问此纹理时,应确保将单个值放在alpha组件中。 这可以在着色器或其他地方完成。

    图像中的值为0.0意味着没有阴影。 图像中的值为1.0表示总阴影 。 就是说,完全是黑色的。 你可能需要0.5左右的颜色作为你最黑的颜色。

  2. 清除屏幕,使alpha被设置为零

  3. 在渲染任何东西之前(或者至less是在桌子下面渲染的任何东西 ),对于每张卡片,渲染模糊纹理,偏离卡片的实际位置(但是具有相同的方向)。 着色器输出的颜色应该是这样的混合configuration(在OpenGL说法中):

    glBlendEquation(GL_MAX); 

    这种混合模式用于保持重叠阴影不断增长变暗或变浅。 它只需要将最黑暗的值写入该像素。 它应该看起来不错。

    您还应该使用颜色写掩码来closures颜色写入。

  4. 渲染表格。 当这样做的时候,混合应该被设置如下:

     glBlendEquation(GL_ADD); glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ZERO); 

如果限制对您来说太严格了,那么您必须使用渲染目标。 这是如下完成的:

  1. 像以前一样创建影子卡图像。

  2. 首先,渲染阴影。 绑定阴影framebuffer(如果你的硬件可以渲染到其中的一个,那么它只需要是单通道图像)。 将其值清零。

  3. 对于每张牌,渲染阴影卡图像,如前所述。 着色器应该将相同的值写入输出颜色的所有四个分量。 混合模式应该是glBlendEquation(GL_MAX)

  4. 切换回常规的帧缓冲区。 画出你想要被遮蔽的一切。

  5. 现在绘制一个全屏幕四边形与我们渲染的阴影图像。 着色器应该将从阴影图像中提取的纹理元素存储在输出的alpha值中; RGB是不相关的。 混合模式应该是:

     glBlendEquation(GL_ADD); glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA); 

我会使用模板缓冲区。 将其清除为1(最好在清除深度的同时),绘制您的表格。 然后启用模板testing,使用模糊的矩形纹理绘制阴影,如果模板和深度通过,则递增;如果模板失败,则不执行任何操作;如果深度失败,则不执行任何操作;将模板函数设置为GL_EQUAL(ref 1,mask 0xff) 。 (我还没有完全testing这个,但它是从类似的代码派生,应该工作正常,你可能需要调整参数)。 然后画一切。

电话会是:

 glEnable (GL_STENCIL_TEST); glStencilFunc (GL_EQUAL, 1, 2); glStencilOp (GL_KEEP, GL_KEEP, GL_INCR); // draw shadow textures glDisable (GL_STENCIL_TEST); 

唯一可能造成麻烦的是如果你有两个模糊的边缘轻微重叠, 否则,除了基本的OpenGL 1.1所提供的function之外,它不需要任何特殊的function,并且可以在所有的硬件上工作(可能是旧的3DFX卡,我认为你并不担心支持…)

第二种方法是在非关键性能的游戏中运行,glCopyTexSubImage2D。 这将使用比后缓冲器更小的纹理,并且在所有硬件上都支持得很好(它是OpenGL 1.1和Doom 3的一部分,所以你可以期待支持非常好)。

基本设置将如下所示:

  • 将颜色清除为黑色。
  • 禁用深度写入(尽管此方法不需要深度缓冲区,因此您可以忽略该部分,因为您不使用深度缓冲区)。
  • 设置与您的纹理尺寸相同的视口。
  • 以白色填充几何graphics绘制卡片。
  • glCopyTexSubImage2D到你的纹理。
  • 将视口切换回完整的窗口大小。
  • 正常画表。
  • 将纹理绘制为全屏混合四边形,使用着色器将其模糊并反转颜色。
  • 画一切。

这也应该是非常好的,它比模板缓冲区方法多一点的GPU,但正确处理重叠的情况 – 就像我说的 – 我认为像你这样的游戏将有GPU的能力,即使在低端卡。