找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1029|回复: 0

关于环境光照变化动作的研究

[复制链接]
发表于 2024-7-6 19:53:41 | 显示全部楼层 |阅读模式
  为了优化我的昼夜交替脚本,我在diy、modenc和ppm论坛翻了个遍,发现关于光照变化的动作脚本叙述得非常潦草,几乎没有人对其特性进行仔细考察。所幸在一个12年的帖子[1]中,有对71、72号动作的参数的较详细解释,在这基础上我在原装YR平台上进行了一些测试,有所收获,特此分享。
  帖子中的结论仅为基于个人实验所得现象的推测,未必代表真实本质,若在实际操作中遇到错误或异常的情况欢迎回帖讨论。

正文
  YR的地图文件中与光照改变有关的动作(Actions)有三个,包括71、72和73号。其中:
  • 71号用于设置每一步光照变化幅度,相当于AmbientChangeStep=的功能(是否完全等价尚未研究);
  • 72号用于设置每一步光照变化的时间间隔,相当于AmbientChangeRate=的功能(是否完全等价尚未研究);
  • 73号为从此动作激活开始,按照71和72所决定的变化率、向所设定的光照等级改变。

  它们在.yrm地图文件中的代码格式为:
71,0,a,0,0,0,0,A
72,0,b,0,0,0,0,A
73,0,c,0,0,0,0,A
  其中的a b c 是这三个动作各自可以设置的唯一变量。

- 光照等级
  光照等级的实际取值范围是0~200的整数。其中100为默认亮度,200效果类似核爆,0则会导致绝大部分像素变为纯黑无法分辨。
  在地图编辑器中设置光照等级时,显示的数字是这个值/100所得到的小数,即1.0000000为默认亮度,2.0000000为核爆亮度。
  实际有效的光照等级并不是201个。从0逐渐提升至200的过程中,肉眼可见的存在51次跃变,就是大约只有52个档位。如此算来,平均每改变约4的光照值才能看到画面跃变为下一个档位。
  也就是说,完全平滑的环境光照变化在原装YR平台上是无法实现的。
  对光照等级部分的测试结果是,0~3,4~6,81~84,85~88、89~92、93~96、97~99各自等价,目前没有发现什么规律,可能是硬编码。
  虽然显示上的档位较少,但是对光照等级来说0~200的取值都是有效的,不会被自动取整到附近档位所对应的整数。
  动作73的功能就是设定下一个目标的光照值,以当前的实际光照值为起点开始变化。也就是说,如果上一步73的动作因为变化速率慢还没有变到目标值也不会继续变了,而是会直接从当前值开始往目标值变化。

- 地图文件中浮点值的存储方式

  动作71和72的变量a b 是一种非常别扭的值,它在地图文件中是一串10位的十进制数,但它实际表示的值需要经过如下转化:
[10位十进制数]→[8位16进制数]→[浮点数]→[我们正常人所理解的小数]

  例如数值1020000000,转化为16进制后变为3CCBF700,它实际上表示0x3CCBF700所储存的浮点数(不带符号,只有正数),最终转化为小数的数值是0.0248981。
  在后文中,这种特殊浮点数我都会用洋红色字体表示,并用括号括起来,紧接在它代表的10进制小数后。
  我很久没有搞mod了,不确定这种特殊浮点数是否还运用在其他的事件或动作中,如果有发现的欢迎回帖补充。

- 71号动作
  71号动作的作用是定义每一“步”改变的光照等级为100a
  变量a 的有效下限为0.01(1008981771),可以让每一“步”改变1的光照等级。在正常情况下,如果没有非常快速的光照变化需求,这个数值较为推荐,方便后续进行计算。
  如果变量a 填入比0.01(1008981771)还小的数字就会因为向下取整为0导致光照无法改变;
  虽然a 可能没有上限,但是有意义的最大取值是2(1073741824),毕竟在这个取值下,一“步”就能从0变到200。
  由于光照等级平均每改变4才会有视觉上的实际变化,所以在有需要快速变化光照的情况下,也可以使用0.04(1025758986)这个取值。

- 72号动作
  72号动作的作用是定义每隔b 游戏分钟光照变化一“步”,也就是说变量b越小。再次强调,并不是每一“步”的光照变化都会导致显示结果会有变化,一定要等光照等级的变化积累到跨过下一个阈值的时候,显示的效果才有不同。
  变量b 的有效下限似乎为1帧,即0.0011111游戏分钟(0982622900),填入比它更低的值的效果与之相同,并不能让变化更快。
  只要时间长度在在1帧以上,似乎变量b 填入任何符合常理的值都是有效的,不一定需要是0.0011111分钟的整数倍。

  因为13号事件“流逝时间”的单位为游戏秒,有时候会需要让光照变化与时间流逝事件同步起来,所以这里给出以下计算方法:
  先将71号动作的变量a 固定为0.01(1008981771),那么要让光照在t 游戏秒之内改变l ,只需要将变量b 对应的实际值b设定为:
b = t ÷ 60l

  例如如果需要需要在15秒之内让光照从75降低至25,那么实际值b就等于15/(60*50)=0.005
  计算出实际值b后利用[2]将其转化为浮点数的十六进制形式。例如0.005转化为0x3ba3d70a
  最后将浮点数的十六进制形式用系统自带的计算器换算成十位数10进制,即为地图文件的动作中需要填写的变量b。例如3ba3d70a转化为1000593162。如果得到的数字为九位数,则在开头需要用0补充到十位。
  根据这些结论就可以相对有的放矢地设置71~73号事件了。

  在最后我也附一份常用的实际值与特殊浮点数对照表,以便使用
71号动作常用实际值 特殊浮点数 72号动作常用实际值 特殊浮点数
2 10737418240.166667(10秒)1042983595
1 10653532160.0833333(5秒)
1034594987
0.5 10569646080.0333333(2秒)1023969408
0.25 10485760000.0166667(1秒)1015580809
0.2 10452205570.00833333(1/2秒)1007192201
0.1 1036831949 0.00555556(1/3秒,5帧)1001786209
0.08 10341475940.00444444(4帧)0999400116
0.04 10257589860.00333333(3帧)0995783694
0.02 10173703780.00222222(2帧)
0991011508
0.01 10089817710.00111111(1帧)0982622900


[1] Day Night Loop settings | Project Perfect Mod (ppmforums.com)
[2] Floating Point to Hex Converter (gregstoll.dyndns.org)

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|Archiver|手机版|管理员邮箱|红警DIY论坛

GMT+8, 2025-4-25 16:38 , Processed in 0.021107 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表