骑马与砍杀中文站论坛

 找回密码
 注册(Register!)

QQ登录

只需一步,快速开始

搜索
购买CDKEY 小黑盒加速器
查看: 1450|回复: 4

[经验与教程] 【战团教程】关于大地图和场景四季变化的实现

[复制链接]

23

主题

337

回帖

298

积分

见习骑士

Rank: 3

UID
3189500
第纳尔
2704
精华
0
互助
26
荣誉
6
贡献
20
魅力
437
注册时间
2020-6-13
鲜花(67) 鸡蛋(0)
发表于 2023-8-3 15:55:07 | 显示全部楼层 |阅读模式
本帖最后由 武安apk43 于 2023-8-6 20:22 编辑

前言:很多人问我大地图和场景的四季变化是怎么实现的,首先要明确四季变化是通过着色器实现的。由于我对着色器并不精通,其详细原理操作步骤过于复杂繁琐,加上不同大地图的话算法也需要改变,我就不发布我的着色器和季节控制代码了,这里只提供指引。
如需学习着色器语言相关,我推荐TW官方论坛上SupaNinjaMan的帖子:B - 教程 - 着色器 - 着色器 101 |故事世界论坛 (taleworlds.com)原生 - OSP - 着色器 - 战队 HLSL 着色器交换 |故事世界论坛 (taleworlds.com)
这个人很牛,这是他做的其中一个大地图效果:
1691284961586.gif

还有诸如手电筒和聚光灯等等:
屏幕截图 2023-08-03 155246.png


有条件的可以科学上网学习一下外国大佬的技术





步入正题:
我是在维京征服的着色器基础上修改的,其已经有了基础可以借鉴的模板。在维京MS源码内就有一个着色器源码mbsrc.fx,我这里打包了着色器和编译环境,方便大家:   
维京征服着色器+编译环境.zip (90.33 KB, 下载次数: 158)

其实维京征服的着色器风和四季效果也是基于TW官方论坛发布的一个OSP着色器,我想这也是维京征服着色器也开源的原因。原帖:
OSP - Shaders - Grandmasters Shaders - Basic Seasons & Wind effects (Version 1.0 RELEASED) | TaleWorlds Forums
上面这个帖子基本就告诉了原理和大体操作步骤。大体思想就是,通过MS代码控制季节的变化(我的细分到了月份),通过OP:set_shader_param_float传递参数给着色器(需要注意浮点数)。比如维京的:
        float vTimer = 0.0f;
        float vSeason = 1.0f;
//WAVE CONSTANTS
        float4 vWaveInfo = 0.0;
        float4 vWaveOrigin = 0.0;
//WIND VARIABLES
        float vWindStrength = 0.01f;
        float vWindDirection = 0.01f;
在MS里通过set_shader_param_float, <var>, <value>,来改变这些变量的值传递参数给着色器。

场景的变化主要靠的就是着色器根据参数分类判断来替换不同的纹理采样,这个比较简单。这里的纹理采样是指同一个材质material上的不同插槽slot对应的贴图,维京只分冬季和非冬季。可以打开维京征服的materials.brf仔细研究(注意维京征服之开源MS代码和着色器)。维京征服还通过OP:set_startup_sun_light、set_startup_ambient_light、set_startup_ground_ambient_light来控制环境的光照RGB,由于维京的地面着色层parallax_ground_shader有视差贴图部分(为了不用制作视差贴图,我把这部分代码注释了)和一定的反射效果,春夏秋也能明显的不同的颜色,但是我不喜欢地面反光的样子,所以就额外加了秋季贴图。

以我自己改的场景边界材质的着色层技术一部分代码为例:
        if (season < 0.5) //0= spring
        {
        tex_col = tex2D(MeshTextureSampler, In.Tex0);//第一个贴图(填充A)
        }
        else if ((season > 0.5)&&(season < 1.5)) //1= summer
        {
        tex_col = tex2D(Diffuse2Sampler, In.Tex0);//第二个贴图(填充B)
        }
        else if ((season > 1.5)&&(season < 2.5)) //2= autumn
        {
        tex_col = tex2D(EnvTextureSampler, In.Tex0);//第四张贴图(环境)
        }
        else if ((season > 2.5)) //3= winter
        {
        tex_col = tex2D(SpecularTextureSampler, In.Tex0);//最后一张贴图(Speculor)
        }
屏幕截图 2023-08-06 174113.png


除了地面,我还给植物、建筑都做了这样的效果,至于材质和着色层技术的代码,我是通过对照已有材质和代码来创建新的带季节变化的着色层和技术,实现全景四季变化


而大地图的变化则是通过对纹理的坐标来计算来改变纹理的颜色,实现雪地效果。维京征服的是判断为冬季时,就计算海拔z来改变颜色,而没有四季的变化。为了模拟骑砍2的四季动态变化,我加上了纬度y,综合海拔z和月份的变化来计算改变颜色,最终实现大地图每个月都有不同的雪地覆盖范围,如图:

至于具体算法,我就不献丑了,因为我也是琢磨不断测试出来的,对于不同的大地图或则不同的需求代码就不适用了。

至于如何同步大地图和场景,就需要在MS代码里通过每次加载场景前获取当前大地图位置坐标,通过类似算法计算得到当前位置的场景对应季节变量,非雪地就应该是大地图的季节,雪地就是冬季变量。这里只能做一个粗略的计算,同理具体算法我也不便展示。

帖子篇幅有限,暂时就想到这些,如有问题欢迎大家回帖讨论,我会尽量解惑。










评分

参与人数 1第纳尔 +10 魅力 +2 收起 理由
agjib + 10 + 2 您的帖子很有价值!

查看全部评分

鲜花鸡蛋

ggfgfgf  在2023-8-3 15:59  送朵鲜花  并说:期待
B站个人空间:https://b23.tv/rZhCYpH

31

主题

209

回帖

187

积分

见习骑士

Rank: 3

UID
2462463
第纳尔
1582
精华
0
互助
23
荣誉
0
贡献
0
魅力
83
注册时间
2015-3-3
鲜花(57) 鸡蛋(0)
发表于 2023-8-5 12:32:43 | 显示全部楼层
高度贴图部分(为了不用制作高度贴图,我把这部分代码注释了),这个是指材质B吗

23

主题

337

回帖

298

积分

见习骑士

Rank: 3

UID
3189500
第纳尔
2704
精华
0
互助
26
荣誉
6
贡献
20
魅力
437
注册时间
2020-6-13
鲜花(67) 鸡蛋(0)
 楼主| 发表于 2023-8-5 12:53:41 来自手机 | 显示全部楼层
战争傀儡阿格兰 发表于 2023-8-5 12:32
高度贴图部分(为了不用制作高度贴图,我把这部分代码注释了),这个是指材质B吗

你看看维京的材质就知道了,它放在最后一个槽位,着色器也是读取那个来自: Android客户端

23

主题

337

回帖

298

积分

见习骑士

Rank: 3

UID
3189500
第纳尔
2704
精华
0
互助
26
荣誉
6
贡献
20
魅力
437
注册时间
2020-6-13
鲜花(67) 鸡蛋(0)
 楼主| 发表于 2023-8-6 09:24:04 | 显示全部楼层
自顶
B站个人空间:https://b23.tv/rZhCYpH

23

主题

337

回帖

298

积分

见习骑士

Rank: 3

UID
3189500
第纳尔
2704
精华
0
互助
26
荣誉
6
贡献
20
魅力
437
注册时间
2020-6-13
鲜花(67) 鸡蛋(0)
 楼主| 发表于 2023-8-6 20:21:38 | 显示全部楼层
战争傀儡阿格兰 发表于 2023-8-5 12:32
高度贴图部分(为了不用制作高度贴图,我把这部分代码注释了),这个是指材质B吗

我说错了,应该是视差贴图
B站个人空间:https://b23.tv/rZhCYpH
您需要登录后才可以回帖 登录 | 注册(Register!)

本版积分规则

Archiver|手机版|小黑屋|骑马与砍杀中文站

GMT+8, 2024-11-19 10:33 , Processed in 0.129606 second(s), 27 queries , Gzip On, MemCached On.

Powered by Discuz! X3.4 Licensed

© 2001-2023 Discuz! Team.

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