教程技巧 MOD制作:大航海时代

  • #1
:evil: :evil: :evil: :evil: :evil: :evil:

天下代码一大抄.(这是决定开这主题的原因,因为WT和WOT/WOTB的实现做法很像.)
我是从隔壁WOTB的MOD社区跑过来.
本人本身也算新手.
不过也不能说完全算吧.
反正,就是我打算详细分享一系列技术的底层原理,
以及如何实现某些有点sao♂操作.:evil::evil::evil:
就是要把MOD制作技术从原本的定性
(比如我在站内看到的"描述8888不显示缩略图,不压缩"之类的话语) 推向定量(从数学角度解释)
所以特此开辟了这个主题.
之后这个主题下的内容将会探讨一些MOD的本质.对学习的基础有要求,
如果你完全没有计算机基础也不用担心,我会专门在这主题下的帖子从0开始讲解的.
 

  • #2

工欲善其事必先利其器

在学习如何制作,安装mod之前,应该先学会几个概念.
  1. 电子游戏
  2. 文件和文件路径
  3. 文件内容和文件名
:evil: :evil: :evil: :evil: 滑稽分割线 :evil: :evil: :evil: :evil:
  1. 电子游戏:
    是指电子游戏,是指所有依托于电子设备平台而运行的交互游戏。
    其构成是由游戏素材(大大小小的各种音视频媒体文件)加上程序代码逻辑。
    程序代码逻辑负责指挥音视频文件对游戏设定上的内容进行演绎。同时监听用户输入的信息并指挥游戏素材进行反馈。
    游戏素材则是那些媒体文件,这里不可避免地就得了解文件相关的知识。
  2. 文件和文件路径。
    计算机文件的定义:
    文件属于文件的一种,与普通文件载体不同,文件是以硬盘为载体存储在计算机上的信息集合。文件可以是文本文档、图片、程序等等。文件通常具有点+三个字母的文件扩展名,用于指示文件类型(例如,图片文件常常以JPEG格式保存并且文件扩展名为.jpg)。(摘自百度百科。假的别信,信了你就是笨铋)
    光看百度百科那文件属于文件的一种这种“搁这搁这”的语法就明显是废话
    那么到底什么是文件?关于文件你可以看成是你的计算机操作系统对你的硬盘进行格式化后划分出来的若干块的连续储存的硬盘空间。
    至于文件路径自然是指文件到底是存放哪咯。而文件路径则是分为绝对路径和相对路径。
    绝对路径是指相对于整个储存设备来说,他存放的位置。而相对路径是指相对于某个文件或者当前的路径来说的。
    比如:
    E:\SteamLibrary\steamapps\common\War Thunder;这就是绝对路径
    Android\data\com.neteasy.wotb;这个就是相对路径。是相对于安卓手机的内部储存来说。
    其中的SteamLibrary等等都是文件夹​
  3. 文件内容和文件名
    说完了文件和文件路径,接下来说说文件内容和文件名。
    文件内容是指文件所对应的硬盘的若干块连续的真实物理空间里所记录的内容。
    考虑到计算机并不识字,只认识高低电位,也就是说是,文件的内容无非是若干1和0以不同的顺序连在一起。计算机前辈们把1个二进制数位表示为1bit,也就是1比特。但是考虑到1bit能储存的信息量实在有限,所以前辈们又规定连续8个bit为1Byte(字节),并且计算机中最小的储存单位是字节。(可能又会有人来刚什么JAVA里的Bool变量只占1bit,对此我只能说你太天真了。考虑一下JAVA虚拟机还有8位对齐,怎么可能只占1bit呢?)
    也就是说文件内容都可以直接用连续的8位二进制数字去看待。
    再说说文件名。
    文件名就是你给文件取的名字,就这么简单。
    你肯定要问文件后缀,也就是扩展名的事情。然而文件的后缀的其实和文件的内容关系不大。
    而文件后缀本身隶属文件名的一部分。同时并不像百度上说的那样是点加上三个字母作为文件扩展名。(你让我 哔哩.html;HelloWorld.c,,stdio.h,碧蓝欧根.webp,IS-7.hd.adreno.dds.dvpl 情何以堪?)
    另外,文件的后缀只是用来提醒用户这是一个什么文件,同时方便操作系统来分类的。
    就好比你把png文件重命名为jpg文件,你手机图库依旧可以图片的形式正常打开,但是他读取的方式是png的读取方式,或者你直接删掉后缀,你依旧可以手动指定以图片的形式正常打开它。​

所以到底什么是MOD​

科普了这么多你大概也能明白了游戏开发过程。
就是先设定好是什么样的游戏,然后寻找,制作,收集整理游戏素材,然后编写代码或者脚本指挥游戏正常与玩家交互。
那么在这过程之中,玩家对游戏素材的修改,或者对代码逻辑的更改就是MOD了。
对于战雷来说:
他绝大多数的mod的原理都是对游戏素材的修改。
而对于挂狗来说,他开的外挂也算MOD。
而对游戏的代码逻辑的更改更多通常倾向于作弊。
 
2 评论
Neons
Neons 已评论
真的是从零开始:tieba-30:
 
Ougein Eufiryajs
Ougein Eufiryajs 已评论

没错是从0开始的建立一个用数学描述的体系
:evil: :evil: :evil:
也就相当于从中世纪推进到航海时代
 
  • #4

数学基础​

进制:表示进位计数制这种计数方法;
这种计数方法由数字符号和数位组成;
判断是几进制,只需要看他有多少个数字符号即可;
几进制也表示低1位数位逢几进就向高1位+1表示低1位的几.
例子比如十进制:
可用的数字符号一共十个(0到9);
每一位上的值达到10就会向高一位上的数字+1;
十六进制通常用0x____;表示____上填对应的十六进制数位及对应的数字.
关于进制如何转换这里提供一个快速的办法:使用你的设备里的计算机找到程序员这一选项.


ppOO1OI.md.png

万物的基础:二进制​

在现代电子计算机中,电子计算机只认识2进制,当然有人会拿USSR的三进制计算机.(可其实那是一个平衡三进制的计算机,实际上是利用二进制改的并不是真实意义上的三进制)
关于二进制,有几个概念要弄清楚:


  1. 原码反码补码
  2. 字节与整数(int)
  3. 文件的内容
  4. 字符编码和字符集

1.原码反码补码

  1. (0bXXX表示这是一个二进制数,XXX就是这个二进制数的每一位内容,而0b只是个标志符.如果没有标识符则认为他是一个十进制数,以下同)
  2. 首先我们来谈谈十进制到二进制,这里只讨论自然数.
  3. (自然数在数学上可以说是构成任何实数的公里,就和直线就是直线一样,不需要定义,只需要约定,约定:表示物体个数的数就是自然数)
  4. 这里随便举个114为例子:那么114对应的二进制: 0b01110010正常来说已经解决自然数的二进制化问题了.也就是说是此时我们已经得到二进制的原码
  5. 于是来了个问题,负数怎么办? 一种比较笨的方法我们可以规定用第一位二进制来表示符号位,如果是1就是负数,0就是正数,于是-2可以表示为0b10000010.也就是反码
  6. 那么这时候-2(0b10000010)与2(0b00000010)相加,得到:(10000100)也就是-4.明显,反码并不是一个正确的解决方案.
  7. 于是我们可以用小学4年纪的方程思维,设一个正数a的负数为n,并且他们在有限的二进制位内相加为0;
  8. 于是不难发现,存在这么一个公式:~a+1=n; ~n+1=a; "~"是位逻辑操作符,是对后面的数的每一位进行操作,原位置上是1则结果是0,如果结果是0原位置就是1
  9. 比如2(0b00000010)的负数:~2=(0b11111101);~2+1=(0b11111110);
  10. 然后再和2相加验算:刚好在8位二进制的情况下相加为0.(因为多出进位溢出了.)
  11. 于是这种表示负数的做法被称为二进制补码
    (0b...表示二进制,0x表示16进制。)
    设数字A = 0b1 1100 0000;
    设数字B = 0b1001 1111;
    设数字C =0b1101 1101;
    设数字D=0b11 1001;
    其中B,C的大小(也就是说他们数据占的位数,占了8个2进制。)是1Byte(字节)。
    A的大小是1+1/8字节,D的大小是7/8字节。
    现在你也应该明白1字节到底是什么意思了。
    当然值的注意是,在电子计算机中,字节是最小的储存单位,所以如果A和D这两个二进制数要存在计算机里,是会进行8位补齐,于是A就是占了2字节,D占1字节。
2.字节与整数(int)
  1. 什么是字节;字节就是一种衡量二进制数位的单位,用来表述这个二进制数是多少位数,计算机科学的前辈规定 1字节 表示 8位二进制数
  2. 你肯定会问为什么是8位,因为8位二进制的最大值是255(0b11111111);(最接近100的2的2的次数幂:即2^(2³)
  3. 计算机科学的前辈另一个规定,在电子计算机中字节是最小的数据储存单位
  4. 关于MiB,KiB,与MB,KB的计算,如果我们遵守IEEE(电气电子工程师学会)的规定应该这样描述.MiB表示使用2的十次方作为进制换算单位.而MB直接使用1000;
  5. 整数(int)在C标准中最小的整数是unsigned/signed Char(有无符号1字节整数).之后个人可以使用short long 然后加上Int来修饰最后决定其长度,通常有1,2,4,8,16字节(分别是byte,int16,int32,int64,int128)
  6. 整数的补码依旧遵循前文所提到的规则
3.文件内容
  1. 上期已经提到了,文件其实就像计算机操作系统(OS)对你的硬盘进行格式化,然后划分出若干等份,用来永久储存数据.
  2. (并且会用EOF标记文件结束,同时文件名和文件路径也在文件系统的调度下分走一部分硬盘容量,所以1GB大小的游戏存下来需要的大小不止1GB)
  3. 所以文件内容就是指文件在对应硬盘的物理空间上对应字节的值.
  4. 使用010Editor或者WinHex这类工具可以直接查看文件的内容(为了方便查看,都是使用16进制,不过每2位16进制等于1字节)
1681270431799.png


4.字符编码和字符集

  • 到这里我们才只是解决了如何教计算机认识数,还没解决教计算机认识字.​
  • 首先我们先引入一个抽象概念"类型"用来表述是什么样的数据​
  • 因为计算机中所有数据都是用字节来储存,所以,不同类型的数据在计算机储存的结果都必定会以字节的形式存储.​
  • 然后再说说字符编码和字符集:​
  • 字符编码:一句话概括:当你以字符形式看待某个int变量时采用的一种规则.​
  • 在这基础上,我们可以制定一张表格,他们分别用不同的数字表示不同的字符,当我们以字符的方式读取int或者char后,计算机会根据预先制定好的这张表格,找到对应的字符,然后把他打印到你的屏幕,窗口,或者是控制台上,甚至是更早计算机的纸张上。(早期计算机确实是这样)
  • 当然早期计算机肯定不是普通人能玩的起的​
  • 美国国家标准学会(American National Standard Institute , ANSI )制定了一套ASCII编码 (American Standard Code for Information Interchange,美国信息交换标准编码);

  • ppX9jmQ.md.png
  • ASCII是基于拉丁字母的一套电脑编码系统;
  • 当然ASCII的缺点也显而易见,就是每个字符只占1个字节,这套编码能最多只能容纳下256个不同的字符。(其最后一次更新之后,一共128个字符,0x0-0x7F。当然在这之后又有以此为基础扩展的ISO-8859-1编码(欧盟国家扩展的),依旧是只占1字节,其最后是0-255一共256个字符全部占满了。)
  • 这套编码对于使用拉丁字母相关语言的国家肯定是最优解,但是其他语系的国家肯定就不干了,于是就有后来的多字节字符编码。(比如日本Shift_JIS、EUC-JP、ISO-2022-JP。国内的GBK,(港澳台地区)的Big-5等)
  • 但是无论是哪一个多字节字符编码都不得不去兼容Ascii,原因很简单,美国有先发优势,如果不去兼容无异于自绝于当下计算机体系。
  • 在之后就是Unicode,最后是UTF-8。
  • 这里就不再细说了,当然现在来看,国际上通用的应该是UTF-8。
  • 这当然也决定了在大多数计算机程序环境中绝对行得通并且通用的字符ASCII。
  • 这也是我为什么不推荐使用WordPad打开Blk而是使用记事本打开Blk,因为WordPad可能会因为萌新的某些操作(比如插入某些对象)引入一些不是Ascii,而是WordPad自定义的字符最后导致文件出错。
  • 而记事本只是纯粹的以默认字符集使用字符的形式读取文件内容。并且记事本在Windows组件中是为数不多不开源的组件(并且还是无数开发者想实现的,因为他完全满足你能找到的绝大多数标准字符集的所有字符的正确显示)。
 
2 评论
Ougein Eufiryajs
Ougein Eufiryajs 已评论
有一点忘记说,使用WordPad甚至是可能因为设置换行符的不对导致BLK引入其他特殊字符。
 
Ougein Eufiryajs
Ougein Eufiryajs 已评论
总之就是不推荐
 
  • #5

涂装MOD的原理

在谈论这个之前,我觉得得先说说3D引擎的渲染的原理。
这里不会细讲多少代码。
3D模型的构成的基础:网格
就直接讲讲3D模型是如何来到你的屏幕上的。
首先是3D模型的的底层数据构成。
C:
//首先要想要有,3D模型的构成应该是要有一个最基础的结构.Vector3
struct Vector3{
  float* x;
  float* y;
  float* z;
  //x y z 分别表示对应的3维的值.
  //而float表示单精度浮点数.(简单的说就是32位,小数点位置可以变动的数字)
}

//有了三维向量这一个最基础的结构体,才能接着编写你的模型.
//要明白,在计算机中,你的模型都是网格
//然后是网格结构体.

struct Mesh{
  Vector3* vertexs;
  int* lines;
  int* planes;
  //vertexs表示你这个模型对应的顶点的数组集合.
  //而linse则是表示你模型对应的所有的线,然后每2个为一组,每组的2个值表示这个线的两个顶点在vertexs数组中的下标(序号)
  //planes和lines类似,他是每3个一组,然后每组的3个值表示这个平面/三角形的三条线分别对应lines数组中的第几组.
  //在计算机中,一个模型的面通常是说这个模型由多少个大小角度各异的三角形拼接而成.
  //当然计算机中,是可以存在四边形的平面,但是这在大多数设备上都是虚拟化的,实际上在绝大多数3d引擎里都会被拓扑成3角形拼接而成.
}

纯粹的高二数学
现在你有了3D模型对应的尺寸
然后你需要调用不同的计算机绘图API(比如OpenGL,Vulkan,dx11等等,然后WT在pc端似乎是dx11,欢迎打脸...不过都差不多...)根据你的模型尺寸,然后根据你的相机以及视锥.
加上一系列的3d矩阵变换.
才能变成画面,然后保存到你显卡的显存内.
在之后你的显卡根据显存还后推流渲染到你的计算机显示器上.
这里涉及到的操作非常多且复杂,至少是需要有大三的数学系的代数和几何学水平你才能弄清楚.
这里就不细说了

这时候绘制出来的只有你的模型的边框,那么解下来就是解决你的模型的每一个面到底是怎样的色彩.
这是就得引入着色器(Shader)这一概念.
在不同的3d引擎所引用的api中,甚至是不同的3d引擎中,他们使用不同的语言.
有的是汇编语言,有的是比较高级的自定义的某种计算机语言之后编译成字节码.
着色器设有一些参数.以及表面的颜色的一些光照反射折射相关的计算公式.
最后,你设定好这一切后,然后你需要将着色器编译为你的计算机设备(主要是显卡)能读懂的二进制指令集合.(即使是编译为字节码,也会有对应的程序进行翻译,然后交给显卡运算)
但是着色器只是一个程序,他必定只能输出同样的结果,
所以我们会给这个程序加个输入的变量,然后让输出的结果与输入的结果通过某种计算来实现一一对应
(到这里已经说明着色器本身在数学上也就是一种函数了)
这时侯我们就定义这个这个储存输入到着色器的变量的类型叫做材质(Materials)
材质是一个类型是着色器的函数的参数
即一个材质通常会和一个着色器对应;
更举个不恰当的比喻:
着色器就像一把枪,
这只枪可以有不同的弹药,
材质就相当于这些各异的弹药.
也就是说一个着色器可以使用多个材质,但是一个材质绑定上一个着色器
材质里主要存放着他对应的着色器渲染的公式需要运用的各项参数
好,现在这些你做完了,你的模型也开始渲染了.
这时候,你的显卡会根据你材质的参数,然后带入到着色器的公式里去计算.
别问cpu在干嘛,这中途大量重复的简单的运算自然是交给你的显卡,你的cpu还要执行你的游戏逻辑运算呢.
到这里,你的模型的每一面都会有他该有的颜色.
但是现在问题来了,
不同的坦克,比如88卡
13852


他必定不同部位(面)上的具体画面是不同的
于是会套用各种不同的材质,而这些材质可能会套用不同的着色器,
显卡的计算量肯定要上去.
对于纯粹美术的工作场景是可以满足,
但从游戏优化的角度,来看,
也不可能让你的显卡实时渲染计算你的模型.
所以这是肯定要思考,既然画面能提前渲染出来了,那么能不能先以图片的形式存下来?
然后以数据包的形式存在你的设备里,当你开始游戏的时候,就不需要在进行重复的大量实时运算,而是直接读取早前计算好的图片呢?
然后交给一个通用着色器去让显卡直接渲染,从而代替材质的作用呢?
答案是肯定的,这是我们就要引入两个个概念--UV映射和材质贴图.

UV映射


什么是UV映射呢?

其实很简单,

你先看看你上小学时,对正方体沿着边线剪开,然后展开.

和这个类似,UV映射是将你的模型的点线面之间的位置关系映射在

2D平面上.

UV映射和你小学时剪开的正方体展开图的最大区别是:

而你的正方体展开图不能重叠而且需要连起来.而且必须要是对应形状,大小比例,
而UV映射与之不同,UV映射可以根据模型需要渲染细节的权重去
分配调节对应的面在这一块2D平面中所占的比例.
而且可以重叠重复甚至不一定要表现成原来的形状.
这也是我反对你们把坦克的UV映射称为坦克的展开图,或者模板的原因,
所谓”展开图“,就是将制件的表面按一定顺序而连续地摊平在一个平面上所得到的图样。
因此UV映射从根本上来看他就不完全算是坦克的展开图
这里虽然用的是隔壁WOTB的模型和贴图,但是没什么区别但是根据天下代码一大抄的说法,(同一图形接口库)的原因实际上大差不差

ppXZdO0.md.png



材质贴图
现在有了UV映射了,那么通过显卡实时先运算一次,然后按照UV映射对应的位置依次渲染保存到对应长宽比例的图片上.
着色器并不会把材质贴图上不在UV上的位置的图像渲染到模型上
这一过程称为烘焙.
而这保存出来的图片就叫材质贴图.
包括材质不同的参数还有:高光贴图,法线贴图,糙度贴图,遮罩贴图,基础色贴图等等.
看到这里你也就明白了涂装MOD的原理到底是什么了,
就是你去修改材质贴图,从而实现你给坦克贴花,甚至喷漆等一些列的效果.
 
评论
  • #7
仔细构思了一下


这系列的教程的主旨用一句话可以描述:



大力引进WOTB的涂装MOD先进经验,多快好省地建设战雷涂装MOD生产线.
 
评论
  • #9
色彩数据相关的知识


色彩视觉
首先说说人眼为什么能看到五颜六色.
你的眼球中存在视锥细胞和视杆细胞
你的视杆细胞负责暗视觉,对色彩几乎没有分辨能力.
你的视锥细胞对明光非常敏感,而且有很高的空间分辨率,同时对色彩比较敏感.
你的视锥细胞分为三种分别对绿光线非常敏感的视锥细胞。
(这里是视觉三原色的学说.应该是高中生物选修的范畴当然这一学说据说也有漏洞,他无法解释白光有两种:一种是由三原色混合成白光,一种是波长在380—780nm的可见光; 更不要说人眼对亮度越高的物体,分辨其对比度会下降)
另外光的本质是电磁波,所谓的色光则是指某一频率/波长的电磁波.
(这里是高二选修物理)

ppXuQ3Q.png

换句话说,你的眼睛只能直接看到红绿蓝三种不同的颜色的色光
而当色光进入你眼睛里时,
你的大脑就会认为,哦,这是一种介于红色和绿色之间的颜色的色光
也就是说:色彩并不是上天赐予的,而是你的大脑脑补出来的.
红绿蓝三原色只是说你的眼睛只能直接看到红绿蓝这三种颜色的色光
而不是说这三种颜色的色光是构成其他的颜色的色光.
要知道黄色光对于拥有四色视觉的人来说,也算是一种原色.



色域
说完了色彩视觉再来说说色域.
色域你可以看成是一种标准,
常见的比如有纯粹的灰度
或者RGB
或者是CYMK这类
这里就以RGB来举例,
对RGB三种原色分别给定一个数值范围,就能得到他该有的色彩范围.这一个范围就叫色域.
比如RGB565和RGB888
分别表示RGB对应最大值能占的二进制位数
比如RGB565表示
R值(红色):范围是0-31;(0-0x1f)(5位二进制)
B值(绿色):范围是0-63;(0-0x3f)(6位二进制)
G值(蓝色):范围是0-31;(0-0x1f)(5位二进制)
色彩数据结构
说完了这,就来说说色彩数据结构
这里就拿Google的提供的某块API为例子吧.
Java:
//这里默认一下提前地说一下哈,这里的代码块默认的是
//colorspace是RGBA8888
//你可能不知道int是啥意思,在这段java代码中,int表示int32(或者说4字节有符号整数)
//换句话说他是一个4字节的整数
//如果你不懂字节
//这里也给你简单说一下,
//你通常会说百千万亿这些计数单位来表示十进制数到底站了几位十进制
//如亿表示这个数字站了9位十进制.
//然后这些计数单位他并不影响你的这每一位上的具体数字
//那么字节和这些计数单位差不多,他也是一个计数单位,但是字节表示的是8位二进制或者2位16进制.
//4字节就表示他是一个32位的二进制数或者8位16进制.
//然后计算机里字节是最小的单位,所以你只能用整数字节去描述数据大小


int color;

char getRed(int color)
{
  return (color>>24)&0xFF;
  //这个算式的意思是对color的中属于Red值的那八位进行取值.并返回给调用方
}

char getGreen(int color)
{
  return (color>>16)&0xFF;
  //这个算式的意思是对color的中属于Green值的那八位进行取值.并返回给调用方
}

char getBlue(int color)
{
  return (color>>8)&0xFF;
  //这个算式的意思是对color的中属于Blue值的那八位进行取值.并返回给调用方
}

char getAlpha(int color)
{
  return (color>>0)&0xFF;
  //这个算式的意思是对color的中属于Alpha值的那八位进行取值.并返回给调用方
}



//RGBA中,A:Alpha表示透明度.

然后就是你可以将图片的R,G,B,A值分别拆分编辑.
而他们对应的内容就对应叫做R,G,B,A通道.



伽马矫正与线性非线性RGB
天下代码一大抄
容我先讲一下什么是线性,什么是非线性。
关于y和x两种变量,他们具有,形如y=kx+b的图像的关系时,
我们就说他们呈线性关系。
典型的有加速度和所受合外力。
好说完什么是线性什么是非线性,
就说说什么是线性RGB什么是非线性RGB以及伽马矫正。
当然这得追溯当上个世纪末,本世纪初。
CRT显示器(学名为“阴极射线显像管”)流行的那个时代。
CRT中的用于显示TV信号的荧光材料对其输入电压的响应是非线性的。
眼而是一个类似幂律(pow-law)曲线的关系,而这个关系又恰好跟人眼对光的敏感度是相反的。
电压V和其产生的亮度Y间的关系是由称作"gamma(γ)"的数刻画的,其幂函数公式粗略为
Y=(V+e)^γ
(当然CRT高中物理有说过,就是通过阴极射线管发射出的电子轰击荧光材料使其发光。毕竟我不是教你物理的,所以这里就不会去赘述。)
当然也有人认为问题出在CRT上而不是人眼上 。:evil::evil:
(当然我也相信这种说法,毕竟正常人的眼睛是不会出错,但是机械是会的。何况后来的液晶显示器就已经说明了出问题的大概率是CRT,而不是人眼。):evil::evil:

所有CRT显示设备都有幂-律转换特性,如果生产厂家不加说明,那么它的γ 值大约等于2.5。用户对发光的磷光材料的特性可能无能为力去改变,因而也很难改变它的γ值。为使整个系统的γ 值接近于使用所要求的γ 值,就要有一个能够提供γ 校正的非线性部件,用来补偿CRT的非线性特性。
要重现摄像机拍摄的画面,电视和监视器必须进行伽玛补偿。
当然,这种伽玛校正可以由摄像机完成。
即使是在数字信号早已代替模拟信号的现在,计算机中依旧带有γ=0.5的矫正。
当然你也别小看,稍微出错,都会使你感觉你的画面过于明亮或者过于暗淡。
伽马矫正只适用于非线性的RGB
而线性RGB则与之相反,他本身就是线性关系,所以是不需要伽马矫正的。
至于sRGB只是一种标准色彩语言协议罢了。
说到这里,也算是给你打下了全部扎实的材质贴图需要用到的基础知识.
然后接下来的内容就是对不同类型的材质贴图的介绍.
 
最后编辑:
评论
不管你如何地想反驳,你都无法反驳这么一个事实:
至少战雷的贴图都可以使用数学量化
(这里R G B A 分别表示Red Green Blue Alpha通道)




材质贴图介绍:
(目前WT并不像隔壁WOTB那么开放所以部分说明
可能会有错误,欢迎回复指正,隔壁WOTB引擎的源码都泄露了 :evil: :evil: :evil: )

基础色贴图:
实例:

1681290513193.jpeg
他决定的是UV对应的点的进行光反射计算时的基础颜色


法线贴图
示例:


1681290561995.jpeg

我始终坚信量化是检验真理的唯一标准.
至少目前量化的结果表明:
如果按照站长大人的教程的说明:
A通道表示是光滑程度:
1681290764319.png
1681290844704.png

这是R B 通道都拉满↑和GB拉满↓的情况对比:
1681290992088.png

还有R通道拉满,其他通道全部为0:1681291066341.png

对应通道
1681291080773.png


再对比隔壁WOTB:
1681291124477.png

以及查到的资料:
实验结果证明了一件非常单纯的事情:
1681291600221.png
1681291625451.png
并且法线贴图的R G B通道分别表示:
UV对应位置的X,Y,Z轴上的分量,
而A通道的值并无意义
或许这就是https://gamemodels3d.com/上下载的模型的贴图是不带透明通道值的jpg的原因
粗糙程度的贴图或许有其他方式的去控制.
(如果有说明办法能获取着色器文件就好了.)
至少目前来看应该_s*应该是粗糙程度或者是阴影贴图


环境光遮罩贴图
随便找个例子了(我还没装战雷CDK)


v2-e88122d95aad274df9201a7fa2b74589_720w.webp

用来计算其本身是对于环境光强度的一种控制。
AO描述了表面上的任何一点所接受到的环境光被周围几何体所遮蔽的百分比,
使得环境光渲染的结果变得正确,。




:evil::evil::evil::evil::evil:滑稽分界线:evil::evil::evil::evil::evil:
至少目前来看有争议的地方是在法线贴图.
我的建议是参考:

 
评论

对战雷涂装MOD的核打击:​

首先谈谈什么是位图(bitmap):
类似于png,dds,pvr,jpg,bmp
通过对图像进行采样,然后在一个固定长宽比例的画布上绘制对应颜色的图片称之为位图.
而这个画布的长宽比例确定,而长宽的具体值有一个固定的最小单位--像素
像素的格式就是这张图片的色域
再来说说为什么直接使用

DDS 编程指南 - Win32 apps :
(DWORD)DDS_HEADER.dwMipMapCount;
与(enum)DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM = 87;
的DDS是,没有压缩的
因为这是规范中规定了:
如果像素格式直接采用是(enum)DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM = 87;
并且没有勾选压缩

则DDS的纹理数据块将直接以长*宽*每像素(四字节)存放
而还有一种你可能不太清楚的是,色深(色彩占用的总二进制位)位数达到24位的色彩就可以称为真彩了
(因为通常认为人眼能分辨的颜色接近于2的24次方)
再来说说PVR,PVR和DDS是同样类型的图片,他的作用在移动端
当其直接不压缩采用RGBA8888的通道时,
他的纹理数据块也将直接以长*宽*每像素(四字节)存放


浅谈战雷的材质贴图的分辨率的选取.

这项核打击技术来自于隔壁WOTB的研究发现

首先我动用了特殊手段生成了一张神奇的pvr(隔壁WOTB的贴图的文件)
这种贴图的具体表现:

e4d02f0df9d5d9458988d3c49b149ab35b56848e[1].gif

ppO2swn.md.png

之后我暴力地修改了pvr的文件头使其直接变为dds
( :evil: :evil: :evil: 这也是为什么前文要提一下pvr是啥免得有些人听的云里雾里 :evil: :evil: :evil: )
这是原先的文件头
1681295013883.png
这是我暴力改成dds的文件头
1681294949941.png

然后再对像素格式进行换算:
我分别得到了我设置的这张神奇的dds(他会在引擎渲染精度变化时改变自己的颜色)
每一级精度下的色彩:
(不要在意左下角,因为左下角是我最开始改错文件头产生的结果)

最好的精度4096*4096的颜色:

1681295214438.png

次级精度2048*2048的颜色:
1681295295952.png
标准的精度1024*1024的颜色:
1681295358652.png
更差的精度512*512的颜色:
1681295382931.png
极度糟糕的精度 低于256*256:
1681295485845.png
最后我们结合我分享的塞博虎式2077的预览图片
13862

13863

13865


:evil::evil::evil:最后对比说明画面渲染甚至不如隔壁WOTB:evil::evil::evil:
好歹隔壁WOTB是这样的
(考虑颜色变换,WOTB的绘制精度越高,颜色越蓝,精度越低颜色越红,如果是十分糟糕则是紫红)

ppXoZpn.md.jpg
e4d02f0df9d5d9458988d3c49b149ab35b56848e[1].gif

当然我们还是得避免捧一踩一的这种做法,
:evil::evil::evil:我这里纯属是想骂BWD飞马:evil::evil::evil:
尽想着骗氪而不是搞更多好东西

综上所述:
大致可以得出这么一个结论:
材质贴图的尺寸不是越大越好,相反太大了,反而吹嘘意义大于实际意义.
材质贴图的最佳尺寸选择应该是1024或者2048

:evil::evil::evil:都看到这里了也就没必要说我为什么老提WOTB了:evil::evil::evil:
可以看看这系列教程的主旨是什么:
:evil::evil::evil:大力引进WOTB涂装MOD先进经验,多快好省地建设战雷涂装MOD生产线.:evil::evil:
:evil:
 
评论
这套系列教程的目标就是要把战雷涂装MOD的生产线从中世纪的那种定性的操作,推到航海时代的定量描述 :evil: :evil: :evil: :evil: :evil:
还是那句话:
:evil::evil::evil:大力引进WOTB涂装MOD先进经验,多快好省地建设战雷涂装MOD生产线.:evil::evil::evil:
 
评论

:evil::evil::evil:战雷涂装MOD生产线的第一次工业革命:evil::evil::evil:

看到这里你可能会说我还是没教怎么用涂装,也没说用什么工具
没错之前就是没说,
因为这是前面的是理论基础
就好比牛顿提出完整的力学体系,
后来的人们才发明了内外燃机
我前面提出的理论基础只是为了使后面的教程里
使你明白其工作原理
:evil::evil::evil:这里就不多废话了,直接开始教程:evil::evil::evil:

工具准备阶段
你只需要准备一个这个网站的账号:
gamemodels
还有一个Blender就行了
什么?
你肯定要问我:
“难道不要PhotoShop吗?我看站内其他教程里还要PhotoShop这些,还有插件什么的啊?”
1681365586155.png


1681365694402.png
1681365717123.png
我的回答是:
“如果这系列的教程还和WT中文社区能看到的传统教程的涂装MOD制作的那种纯手工绘制没什么区别的话,为什么我还要出一个教程,顺带哗众取宠地高调发言要把WT涂装MOD生产线推进到航海时代?甚至是大吼一句工业革命?”

“而且纯手工绘制贴图的效率实在太低,而咱的这系列的教程无论是做旧,
还是细节,还是绘制基础色贴图,或者法线贴图的教程都是其他教程无可比拟的。”

“因为这系列教程对于计算机图形学和数学理论具有一定的要求,
并且使用的方法的生产里速度比传统教手绘效率高的不是一星半点。
和历史上西欧从中世纪跃进航海时代极度相似,所以我愿称之为:
WT涂装MOD生产的大航海时代,和WT涂装MOD生产线的第一次工业革命”

还是那句主旨
:evil::evil::evil:大力引进WOTB涂装MOD先进经验,多快好省地建设战雷涂装MOD生产线.:evil::evil::evil:


 
评论

Blender默认快捷键大全

BlenderKeys

基础按键篇
shift功能键1
ctrl功能键2
alt功能键3
左键点击
右键菜单
Tab物体/编辑模式切换
功能键1+左键多选
功能键2+左键选择前后两次点击的物体
A全选

视角操作篇
按住鼠标中键视角旋转
功能键1+按住鼠标中键
视角平移
鼠标中键视角缩放

网格/物体操作篇
R网格:旋转G网格:缩放
S网格:缩放(RSG)+X,Y,Z指定轴向
F根据所选网格项生成网格项H隐藏
功能键3+H恢复当前所有隐藏项目L网格:选择所链接项目
功能键1+功能键2+A环选E网格:挤出
功能键1+N重新计算面的法线朝向功能键1+A新建


:evil::evil::evil:理论上,Blender的所有操作都可以使用鼠标实现,:evil::evil::evil:
但是那样实在太低效了所以我推荐稍微记一下
当然你可能会说这个太麻烦了不如PS自己手绘.
我的回答是:
纯手艺人到第一次工业革命以后的生产线去一趟
他也会觉得麻烦.
就随便举个造兵器例子.
一次工业革命以前,
人们打造盔甲,刀剑,只需要烧炉火炼钢
然后锤子敲打就行了.
而到一次工业革命以后呢?
人们造兵器:
烧炉火炼钢
启动蒸汽机,蒸汽机为动力的机床
钻,铣,镗,锯床还有轧制.哪个不麻烦?
但是确确实实工业革命提高了生产力.
 
最后编辑:
2 评论
Neons
Neons 已评论
懂了 事Blender教学:tieba-25:
 
Ougein Eufiryajs
Ougein Eufiryajs 已评论
:evil::evil::evil:算半个Blender的教程。
还算是引进WOTB的先进技术罢了.
 
:evil: :evil: :evil:接下来就是一系列的操作教学了.就不会太过注重文本格式什么的了.
(并且按键和操作我都是混着写,有不懂啥意思地点击这里跳转到)

跳转至快捷键


首先去gamemodels下载一个你想要制作涂装的模型
我这里就以黑豹D为例子了
1681368642881.png
然后我们打开Blender
进入这样一个界面直接点击常规或者点击背景就能进入了
1681368850278.png


此时还是空荡荡的一片,一个摄像机以及一个光源

1681369002550.png



然后我们左键全部框选.然后右键删除

之后如图所示导入我们下载好的Obj模型
1681369174146.png




此时我们点击右上角,进入渲染模式预览材质

1681369917414.png


1681369932247.png
1681369970028.png

然后我们来个最基础的操作,给战车换个迷彩

点击上方,然后进入着色进入预设的着色器编辑界面
然后下方就是我们编辑对应的材质的着色器
1681370027680.png



注意看好尽量对比一下其他的物体确定你要编辑的着色器是这个物体自己的,而不是和其他物体公用的1681370104593.png

然后我们在下方新建一个颜色渐变:
并将他的颜色连给基础色.
我随随便便调了防磁装甲的迷彩效果欢迎照抄
1681370793253.png

这时候你要说原有的细节丢失了
其实没要担心
我们另外新建一个混合颜色的节点
然后把这个颜色渐变和原有的图像纹理相连
最后把结果传递给基础色
然后正片叠加
之后调节系数,使得原有的做旧效果保留
1681371209953.png

1681371286881.png







:evil::evil::evil:到这里你已经学会如何通过Blender的着色器的节点实现生成贴图了:evil::evil::evil:
下一节将教你如何实时计算一次并且以图片的形式保存下来;也就是烘焙
















关于中文设置:
1681369066407.png

1681369110915.png
 
评论
首先选中你要烘焙的部件
然后点击左上角的选择然后有一个反转
1681371595120.png

这样你就选中了不需要的物体,然后按H将他们隐藏
1681371615889.png
然后选择你要烘焙的物体并且在下方的槽选择到你要烘焙的材质
1681371677407.png

然后新建一个图像纹理,同时新建一张图像
我前面提到了贴图的最佳的尺寸是1k到2k所以我这里就选了一个1k的
1681371805856.png
然后点击切换到渲染属性
1681371851303.png

选择渲染引擎为Cycles1681371893968.png
然后自己调节采样率这些的.
我的显卡性能不高,所以我就调节的是1281681372000668.png


然后下方找到烘焙:
并且将类型改为漫射,同时只勾选颜色(基础色)
1681371962091.png

1681372048213.png
烘焙前确保你选中的活动的图像纹理是你新建的那份
然后并且你选中的物体也是对的
然后点击烘培
然后下方就有一个进度条
1681372207454.png

然后烘焙完毕的左边就会自动跳转到对应的图像
然后出错了透明的
1681372310654.png

不过你也不要着急,因为这是UV没有对上的原因我们点击UV编辑
1681372401395.png

点击右边的窗口然后我们全选
然后左边就给我们汇报UV的错位情况

1681372504498.png
:evil::evil:然后我们切换到原有的贴图然后发现原来是UV向下偏移了1单位:evil::evil:
1681372567767.png
于是我们点击左边的窗口,然后全选
然后移动
1681372684265.png
就这样UV工工整整地对齐了
然后我再次重复之前的步骤烘焙一次1681372822799.png
之后烘焙的时间取决于你的设备的算力与你当前选择的精度
1681374022766.png
渲染完毕以后就是这个效果,
然后我们发现出现了个缺点,就是一些没有上迷彩的地方和其他物件公用了,
对此,我们有两种做法,
1.选择其他的公用物体,然后在他们的材质着色器编辑界面新建图像纹理,并且选中我们新建的这张图片,然后关闭清理图像,并且烘焙一遍1681375980492.png

然后你也可以像这样再创建一个平面然后新建材质,1681375924657.png并着色器节点作无损的数学图片叠加
然后另外新建一张图片,和添加一个图像纹理
然后烘焙另外新建的图片上
最后烘焙
 

附件

  • 1681372419846.png
    1681372419846.png
    527.4 KB · 查看: 3
评论
顶部