本帖最后由 594380389 于 2019-3-24 14:35 编辑
随着地景行业的快速发展,以及电脑硬件的跨越式升级,飞友(消费者)越来越不满足于只有地面+航站楼+卫星图的地景模式,"WE WANT MORE! "
P3Dv4版本加入了动态灯光,4.4版本升级PBR,将来V5版本将又是一个大飞跃,基于此方向,楼主在此和大家分享另一个重量级工具--LUA编程
很多大的插件商,犹如A家,F家地景中都出现了"Scripts"文件夹,这正是用来放置LUA代码的路径,宏观他们近几年的巨作:如F家的波士顿,一个地面,不仅仅是由混凝土/沥青材质完成,而是增加了许多材质包括法线贴图(Bump Map)、细节贴图(Detail Map)……等等等等,用来渲染雨天、雪天的地面变化情况,相信入手的飞友大多都能感受到非常细腻的代入感。这些贴图的变化都是由LUA编程实现的。(而这些,用SODE的更换模型的方法来说,几乎无法实现,虽然他已足够强大,小声BB……)其实P3D的Rainmaker效果也是由LUA代码实现的,神奇吧?
进入正题,LUA编程到底是什么我不在这里说了,我们今天关注点在于它到底能干什么?
首先,你需要对于他的运算法则有一定的了解,具体请移步LUA编程 。 还有,千万记得要下载LuaEdit2010这个软件,不然逻辑上有错误的txt是看不出来的,切记。
其次,我今天会以浅略的示例来教大家如何应用到实际地景制作中。
举例1. 我投入的机场,地处非寒带地区,但是也会下雪,基于这种特殊性,如果机场所在地区不下雪,那么机场周围非卫星贴图部分是不会有雪的,那这里就有难题了,如果做了四季贴图,单单通过季节变换来换贴图,机场会显得非常突兀(机场 白色,P3D贴图是夏天)。为了解决这个办法,楼主对LUA编程实现了勇敢的探索,我最初是“偷窥”F家和A家的地景LUA代码,看了半天总算有了点“门道”,开始上手自己写,这么一写,发现这事儿没这么简单,总算是通过至少100遍的“改代码-进P3D测试-改代码”的循环,总算成功。代码如下:
- !lua
- local snowing = 0x00000008
- local precipState = varget("O:Weather.AmbientPrecipState", "Mask")
- precipState = math.floor(precipState)
- local StringOld = varget("T:DiffuseTexture", "String")
- local StringNew
- if precipState == snowing then
- StringNew=string.sub(StringOld,1,7) .. "_HW.DDS"
- else
- StringNew=string.sub(StringOld,1,7) .. ".DDS"
- end
- varset("T:DiffuseTexture","String",StringNew)
复制代码
LUA代码必须由!LUA起始
- local snowing = 0x00000008
复制代码
这个代表本地下雪的状态=有,具体变量请移步P3D-SDK学习中心-LUA Scripting-Variables Overview, 这个稍微翻译一下不难懂。我们查阅关于下雪变量的代码发现这个降水量变量表达是二进制八位的,因此我们选8代表下雪的状态。
- local precipState = varget("O:Weather.AmbientPrecipState", "Mask")
- precipState = math.floor(precipState)
复制代码
这两行,是获取该物体周边降水量状态的代码,其中O,代表变量大类,Weather.AmbientPrecipState如上图,Mask是单位(千万不要错)。 - local StringOld = varget("T:DiffuseTexture", "String")
- local StringNew
复制代码 接下来的两行是获取现有贴图的代码,单位是String,下面的local StringNew接下来给新的贴图定义更换条件。 - if precipState == snowing then
- StringNew=string.sub(StringOld,1,7) .. "_HW.DDS"
- else
- StringNew=string.sub(StringOld,1,7) .. ".DDS"
- end
复制代码 代码解释:如果降水状态等于(LUA的等号是==表示)下雪,那么新的贴图=旧贴图名的1-7位字母加上“_HW.DDS",其他情况则新贴图=旧贴图名的1-7位字母(相当于没有改变),这是我的贴图名
- varset("T:DiffuseTexture","String",StringNew)
复制代码
最后,变量设置为新的String,也就是新贴图。
举例2. 我想让我的灯光在白天能见度低的时候也亮起来(不用SODE,比SODE简单快捷),怎么办?
- !lua
- local timeofday = varget("E:TIME OF DAY", "Enum")
- local visibility = varget("O:Weather.AmbientVisibility","Meters")
- if visibility < 5000 or timeofday ~= 1 then
- Texture = "sample_new.dds"
- else
- Texture = "BLACK.dds"
- end
- varset("T:DiffuseTexture", "string",Texture)
- varset("T:EmissiveTexture","string",Texture)
复制代码
前三行不说了,具体参考例子1. 从下面开始代码解释:如果能见度小于5000,或者一天中的时间段不等于1(白天,具体表达方法移步SDK学习中心),那么贴图等于“”中的,其他情况等于“”中的,结束。设置新贴图为"Texture",注意,由于我的灯光贴图的特殊性,这里需要把EmissiveTexture,也就是Nightmap也设置为新贴图,具体的,大家可以根据实际情况来发挥。
举例3.用A家的德国科隆跑道上“吹雪”效果来示例。
- !lua
- local Wind = varget("O:Weather.AmbientWindDirection", "Degrees")
- local Speed = varget("O:Weather.AmbientWindVelocity", "Knots")
- if Speed < 10 then
- Length = 22
- elseif Speed < 20 then
- Length = 16
- else
- Length = 6
- end
-
- local Time = (varget("E:ZULU TIME", "seconds")) % Length
- local Offset = -((Time * (1 / Length)) + 0.5)
- varset("T:TextureCoordRotation", "Number",Wind)
- varset("T:TextureCoordOffsetU", "Number",Offset)
复制代码
前两行是获得该模型周边的风速和风向,接下来是根据风速来决定吹雪的快慢,根据风向决定吹雪的方向。具体的表达式我也没看懂,但是大家如果要拿来用,肯定是没有太大问题的,毕竟LUA代码是活的。
收尾:
1.Script文件夹该放在哪里,如何运行?
答:Script文件夹放在地景文件的主目录,和Scenery和Texture放在一起,其中Script中还需要建立一个文件夹Texture,把需要更换的新旧贴图都放到里面才可以正常运行。
2.模型怎么识别代码?
将模型导入到MCX中,打开材质编辑器
名称要和代码文件相同,然后输出就可以了。如果模型是复合模型,材质也不一样,那么每一种材质都需要应用这个代码(重要!!!)
这次就说这么多了,具体操作方法还是需要大家动手去训练,先从最简单的材质更换开始,步步为营,我希望我的帖子能为国内地景制作带来一些改观。
|