什么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组件。
获取一张卡片的灰度图像。 使它在边缘模糊,可能会扩大其大小。 这是你的影子影像。 请注意,这是一个单通道图像。 在着色器中访问此纹理时,应确保将单个值放在alpha组件中。 这可以在着色器或其他地方完成。
图像中的值为0.0意味着没有阴影。 图像中的值为1.0表示总阴影 。 就是说,完全是黑色的。 你可能需要0.5左右的颜色作为你最黑的颜色。
清除屏幕,使alpha被设置为零 。
在渲染任何东西之前(或者至less是在桌子下面渲染的任何东西 ),对于每张卡片,渲染模糊纹理,偏离卡片的实际位置(但是具有相同的方向)。 着色器输出的颜色应该是这样的混合configuration(在OpenGL说法中):
glBlendEquation(GL_MAX);
这种混合模式用于保持重叠阴影不断增长变暗或变浅。 它只需要将最黑暗的值写入该像素。 它应该看起来不错。
您还应该使用颜色写掩码来closures颜色写入。
渲染表格。 当这样做的时候,混合应该被设置如下:
glBlendEquation(GL_ADD); glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ZERO);
如果限制对您来说太严格了,那么您必须使用渲染目标。 这是如下完成的:
像以前一样创建影子卡图像。
首先,渲染阴影。 绑定阴影framebuffer(如果你的硬件可以渲染到其中的一个,那么它只需要是单通道图像)。 将其值清零。
对于每张牌,渲染阴影卡图像,如前所述。 着色器应该将相同的值写入输出颜色的所有四个分量。 混合模式应该是glBlendEquation(GL_MAX)
。
切换回常规的帧缓冲区。 画出你想要被遮蔽的一切。
现在绘制一个全屏幕四边形与我们渲染的阴影图像。 着色器应该将从阴影图像中提取的纹理元素存储在输出的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的一部分,所以你可以期待支持非常好)。
基本设置将如下所示:
这也应该是非常好的,它比模板缓冲区方法多一点的GPU,但正确处理重叠的情况 – 就像我说的 – 我认为像你这样的游戏将有GPU的能力,即使在低端卡。