创建一个动态的雾_Graveyard Keeper像素画游戏动态光照实现方法

4f2894b073c715701caa27fa9459b9e9.png

作者:Svyatoslav Cherkasov

教你画像素画编译出品。

我是游戏“ Graveyard Keeper ” 的首席程序员。我要分享像素画游戏动态光照的一些技巧和窍门。

我们对游戏美术效果充满热情,所以花费了大量时间和精力制作动态光照效果的原因,为了使像素画尽可能具有吸引力。如果你想实现同样的效果,本文会对你有所启发和帮助。

构成我们游戏视觉效果的主要内容:

  • 动态环境光:根据一天中的不同的时间改变明暗。
  • LUT色彩校正:根据时间或区域的不同改变色调。
  • 移动光源:手电筒,烤箱,灯具。
  • 法线贴图:使2D像素画看起来像3D的,尤其是在光源移动的时候。
  • 光线3D分布:以屏幕为中心的光源应正确照亮较高的物体,不应照亮下方的物体。
  • 投影精灵:它们会转动,并对光源位置作出反应。
  • 对象高度模拟:用于正确显示雾。
  • 其他的东西:雨,风,动画(包括叶子和草的着色动画)等。

动态环境光

夜间较暗,白天较亮。灯光颜色设置为渐变色。夜幕降临时,光源不仅会变暗,而且会变成蓝色。它看起来像这样

ab7c4ff3a26ba7c1a34ba8c50b1953aa.png

LUT色彩校正

LUT是一个颜色变化表。粗略地说,它是一个三维RGB阵列,其中每个元素(a)对应一个坐标为RGB值的颜色; (b)包含与元素关联的颜色应更改为的颜色值。因此,如果坐标(1,1,1)处有红点,则表示图片中的所有白色都将替换为红色。但如果在相同坐标处有白色(R = 1,G = 1,B = 1),则不会发生变化。因此,默认情况下,LUT具有与特定颜色相关联的坐标。我的意思是坐标(0.4,0.5,0.8)的点与颜色相关(R = 0.4,G = 0.5,B = 0.8)。

为方便起见,3D纹理表示为二维的。这就是默认LUT(不改变颜色)的样子:

19f5d1a24efd8d15bc8e83d17efe4ccf.png

可以从游戏中找出一个场景,告诉美术:“让它看起来像晚上”。然后应用所有颜色层加上默认的LUT。恭喜!你得到一个晚上的LUT。

我们的美术实际上非常热衷于此。他为一天中的不同时间(夜晚,黄昏,傍晚等等)创建了10种不同的LUT ......这就是最终LUT集的外观:

f33f55815c6190af1ca8678efa2ed73b.png

游戏效果

6d0a07d0a33c2cd50237c0a796925e47.png

移动光源/法线贴图

我们使用默认的Unity光源。此外,每个精灵都有自己的法线贴图。

b4ec97f829c51b403fd4233da02799c6.gif

这些法线很容易画出来。美术用刷子粗略地在四面画出光线:

09b3503dc5a32315c83d75f8b4e31bab.png

然后我们将它们与法线贴图中的脚本合并:

f66ec031704805e3973a0251a6064113.png

光线3D分布

这是开始变得复杂的地方。你不能只是点亮精灵。精灵是否在光源“后面”或“在它前面”是非常重要的。看下面的图片。

1415d34ebcbae3962f482e4708396c03.png

这两棵树与光源的距离相同,但后面的树被照亮而前面的树没有(因为相机面向它的黑暗面)。

我很容易就解决了这个问题。有一个着色器可以计算垂直轴上光源和精灵之间的距离。如果它是正的(光源在精灵前面),我们像往常一样照亮精灵,但如果它是负的(精灵阻挡了光源),那么照明的强度会根据距离的变化而变淡。非常快的速度。有一个速度,而不仅仅是“不要照亮”。因此,如果精灵后面的光源正在移动,则精灵会逐渐变黑,而不是立刻变黑。但它仍然非常快。

090ee2462ffc155b6c656b1ef454db94.gif

投影

阴影是用一个旋转的精灵做的。每个对象最多可以有4个阴影。太阳的阴影和动态光源3个。下图显示了这个概念:

0f935b8377320c400913f25b551b3024.png

问题:“如何找到最近的3个光源并计算距离和角度,并在运行的脚本Update()循环中解决。

如果今天编程,我会使用Unity Jobs系统。但当时我不得不优化常规脚本。最重要的是我做了精灵旋转而没有在顶点着色器中修改。只需要给精灵一个参数(我使用颜色通道,所有的阴影都是黑色的),而着色器负责精灵旋转。事实证明它更快 - 不必使用Unity几何体。

对每个对象分别调整(有时是绘制)阴影。我们使用了大约10种不同的通用精灵(薄,厚,椭圆等)

下一个问题:难以为沿一个轴拉伸的对象制作阴影。例如,看看栅栏阴影:

0b7405e8cf7e9691417905eee413e454.gif

雾和高度模拟

游戏中有雾。它看起来像这样(上面的常规版本和极端的100%雾来展示效果)。

93af2c98d8d38ba90c319c15b3f57e92.png

从雾中可以看到房屋和树木的顶部。事实上,这种效果很容易实现。雾包含了遍布所有图片的大量水平云。因此,所有精灵的上半部分都覆盖了较少量的雾精灵:

3b96ad99f4b4df9b11e8c283e28908b2.png

像素画里面的风没有太多选择。只能制作动画或制作变形着色器,不做任何动画,画面看起来会静止而且毫无生气。我们使用了变形着色器。

f7a433f2747472fdf2af2858d2c13593.gif

将着色器应用于方格纹理

29f10cd841528b4cc95e7cbe1e0601f3.gif

我们不会为树的整个树冠制作动画,而是为某些特定的树叶制作动画:

0705b64670c830b0f500974bab384337.png

还有麦田摇动动画,这也很简单。改变顶点着色器,考虑y坐标的x坐标的形状。最高点摇动最强烈。麦子上半部分应该摇动,而根部不应该摇动。另外,摇动的阶段根据x / y坐标而变化,以使不同的精灵分开移动。

当玩家经过小麦或草地时,着色器还用于创建摆动效果

b0f63b4f5d11ff8d9b76bd700464a38e.gif

完。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于javaweb墓地管理系统,我可以为您提供一些介绍和演示。 墓地管理系统是一个用于管理和维护墓地信息的系统。它可以帮助管理者记录和查询墓地的基本信息,包括墓地位置、墓主人信息、墓地状态等。此外,墓地管理系统还可以提供一些额外的功能,如墓地预订、墓地维护、墓地费用管理等。 在JavaWeb开发中,可以使用Java语言和相关的技术来实现墓地管理系统。以下是一个简单的演示示例: 1. 数据库设计:首先,需要设计一个数据库来存储墓地信息。可以创建一个名为"graveyard"的数据库,并在其中创建一个名为"grave"的表,用于存储墓地信息。 2. 后端开发:使用Java语言和JavaWeb框架(如Spring MVC)来开发后端代码。可以创建一个名为"GraveController"的控制器类,用于处理墓地相关的请求。在该控制器中,可以实现一些方法,如添加墓地、查询墓地、修改墓地信息等。 3. 前端开发:使用HTML、CSS和JavaScript等前端技术来开发用户界面。可以创建一个名为"grave.jsp"的JSP页面,用于展示墓地信息和提供相关操作。在该页面中,可以使用表格来展示墓地列表,并提供一些按钮和表单来进行墓地的添加、查询和修改等操作。 4. 数据库连接:使用JDBC或者ORM框架(如MyBatis)来连接数据库,并实现数据的增删改查操作。可以在后端代码中编写相应的数据库连接和操作代码,以实现与数据库的交互。 5. 部署和测试:将开发好的代码部署到JavaWeb服务器(如Tomcat)上,并进行测试。可以通过访问相应的URL来测试墓地管理系统的功能,如添加墓地、查询墓地等。 这只是一个简单的示例,实际的墓地管理系统可能还涉及到其他功能和技术。希望这个演示能够帮助您对javaweb墓地管理系统有一个初步的了解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值