AlertNote

轻舟已过万重山

AlertNote

概述

纹理压缩是为了解决内存、带宽问题,专为在计算机图形渲染系统中存储纹理 而使用的图像压缩技术。

内存:用于存放数据的场所

带宽:数据的存取速度的体现

纹理压缩的必要性

​ 文件格式是图像为了存储信息而使用的对信息的特殊编码方式,它存储在磁盘中,或者内存中,但是并不能被GPU所识别,因为以向量计算见长的GPU对于这些复杂的计算无能为力。这些文件格式当被游戏读入后,还是需要经过CPU解压成R5G6B5,A4R4G4B4,A1R5G5B5,R8G8B8, A8R8G8B8等像素格式,再传送到GPU端进行使用。

​ 纹理格式是能被GPU所识别的像素格式,能被快速寻址并采样。

举个例子,DDS文件是游戏开发中常用的文件格式,它内部可以包含A4R4G4B4的纹理格式,也可以包含A8R8G8B8的纹理格式,甚至可以包含DXT1的纹理格式。在这里DDS文件有点容器的意味。

​ OpenGL ES 2.0 支持以上提到的R5G6B5,A4R4G4B4,A1R5G5B5,R8G8B8,A8R8G8B8等纹理格式,其中R5G6B5,A4R4G4B4,A1R5G5B5每个像素占用2个字节(BYTE),R8G8B8每个像素占用3个字节,A8R8G8B8每个像素占用4个字节。

​ 对于一张512x512的纹理,R5G6B5格式的文件需要占用512KB的容量,A8R8G8B8格式的文件需要占用1MB的容量;如果是1024*1024的纹理,则各需要2M和4M的容量,这对于动辄需要几十、几百张甚至更多纹理的游戏,上G容量的游戏在移动平台上是不容易被接受的(当然,还是有1、2G的大作的,里面包含了几千张的纹理)。

​ 那么,有没有其他办法,既能表现丰富的色彩和细节,又能是最小失真的情况下,达到更小的纹理容量呢?压缩纹理格式应运而生(并不是在移动平台后才有的产物)。

阅读全文 »

Unity 编辑器提供了强大方便的功能拓展接口,允许将开发工作流集成化。结合前一段时间研究了打表工具流,正好趁热打铁做点东西!

浅铺垫一下

优化现有的打表流程之前,先实现原先基础的打表工具。

通过创建一个新的C#控制台应用,在Unity中写一个Editor工具类,执行控制台程序输出json文件。

1
2
3
4
5
6
7
8
9
10
11
{
"name": "Items",
"data": [
{
"iId": 1,
"sDesc": "道具1",
"iType": 100
},
...
]
}

类似python工具的实现方式,这里就不详细介绍了。

实现原先的打表工具以后,也发现了一些可优化点

  • 在Editor脚本中调用python或其他外部程序,意味着需要多维护一个项目,多少有亿些繁琐;
  • json存在大量重复字段,随着数据量增长冗余量会非常大;若改用二进制存储(类似protobuf),可以解决冗余,但难以维护;
  • 测试数据的时候会更改数据,即修改表格内容,需要动到源数据且可能需要反复打表的操作;
阅读全文 »

核心 —— KISS 原则

KISS 原则是用户体验的高层境界,简单地理解这句话,就是要把一个产品做得连白痴都会用,因而也被称为“懒人原则”。如果把游戏框架看作是一个产品,那么它的用户就是程序员,框架的易用性能直接影响程序员的开发体验。

KISS 原则的核心思想就是“解耦,解耦,再解耦”,职责单一化,功能单一化,为以后的维护和重构都会带来极大的便利。

框架设计的主要原则

  1. 除了必要的启动内容,不放任何内容相关的节点到场景——场景节点是空的
  2. 既然每个场景都是空的,那么做场景切换也就没必要了,只需要在同一个场景中开发
  3. 不往节点上、预制体上手动挂代码。否则将需要一个个节点手动点开检查,难以维护
  4. 不允许将相关的节点/组件手动绑定到编辑器中,一个好用的框架应该要做到所有的逻辑可以直接通过代码搜索,并可以通过代码维护业务逻辑+视图逻辑+代码逻辑——所有的逻辑可通过代码追溯

毕业设计总是一个很好的练手途径。

今天分享一个比较经常用到的框架思路,基于喜闻乐见的**命令模式(Command Pattern)**实现按键绑定(InputHandler)的功能。

之所以喜闻乐见,是因为这个模式的通用性很强,很多需求上都能用到它。当我们正确地使用它时,可以将冗杂的代码整理得比较干净。

先来看点深奥的定义,来自GoF —《Gang of Four》:

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化; 对请求排队或记录请求日志,以及支持可撤销的操作。命令模式是一种回调的面向对象实现。

当然,这些句子有些抽象晦涩,不过啃下来以后却发现竟是很好地高度概括了。干脆直接用实例来理解!

阅读全文 »

类型

  • 在控制结构的条件中除了falsenil为假,其他值都为真(0的值为真);
  • 函数可以存储在变量中;
  • ..在Lua中是字符串连接符,当在一个数字后面写..时,必须加上空格以防止被解释错;
  • pairs: 迭代 table,可以遍历表中所有的 key 可以返回 nil,
    ipairs: 迭代数组,不能返回 nil,如果遇到 nil 则退出;
阅读全文 »

strcpy() - 字符串拷贝

函数作用:将源字符串内容拷贝给目的字符串。函数返回指针,指向拷贝的字符串首地址。

  • pSrc:源字符串
  • pDest:目的字符串
1
2
3
4
5
6
7
8
9
10
char* strcpy(char* pDst, const char* pSrc) //源字符串参数用const修饰,防止修改源字符串。
{
assert(pDst != NULL && pSrc != NULL); //对源地址和目的地址做非空断言

char* pTemp = pDst; //由于pDst位置将要移动,使用指针记录字符串开头位置

while ((*pDst++=*pSrc++)!='\0'); //[4]

return pTemp; //为实现链式操作,将目的地址返回
}

注意事项

  1. 空指针检查

    1. 如果不检查指针的有效性,说明答题者不注重代码的健壮性。

    2. 如果检查指针的有效性时使用assert(!pDst && !pSrc);char*转换为bool即是类型隐式转换,这种功能虽然灵活,但更多的是导致出错概率增大和维护成本升高。

    3. 检查指针的有效性时使用assert(pDst != 0 && pSrc != 0);会减少程序的可维护性。而使用NULL代替0,如果出现拼写错误,编译器就会检查出来。

  2. ‘\0’

    1. 循环写成while (*pDst++ = *pSrc++);明显是错误的。
    2. 如果循环写成while (*pSrc !='\0') *pDst++ = *pSrc++;,循环体结束后,pDst字符串的末尾没有正确地加上'\0'
  3. 返回值使函数能够支持链式表达式。

    链式表达式的形式如:

1
char* pStrA = strcpy(new char[10], strB);
阅读全文 »

又到了如何把代码写爽的环节了XD

之前在做毕业设计的过程中,遇到了大多数同学都遇到的一座粪山:角色的动作逻辑全都写在Player.ts里面(我猜八成是叫这个名字,光是想到,脸上就已经浮现出了痛苦的神情。)

当一个玩家脚本需要同时执行多个逻辑的时候(移动控制,动画播放,按键管理等等等等等),无一例外地出现了这样的局面:

我们优雅地判断了按键输入,希望在WASD的按键驱动下,让我们的主人公顺理成章地旋转跳跃翻飞升华,于是在判断按键输入的代码块里改变了角色的动作播放,又设置了移动速度,还在某个update里面不停地设置他的方向……

港真的,说的我都要吐了。

于是我捂着翻滚的胃部在网上搜索着各种资料,在不懈的努力下最终摸索出了一套方案,思想基于游戏编程模式中的状态模式(State Pattern)

阅读全文 »

你永远也不知道明天和意外哪一个先来,但你至少能够未雨绸缪,灵活变通,将损失减少到最小。

——学习动态规划有感

动态规划算法(Dynamic Programming)是计算机中解决最优化问题的一种方法,特点是效率高,计算速度快。

假设给你1元,2元,5元的硬币,每种硬币的数量无限,你需要在商店买27元的商品,请以最少的硬币数量拼凑出27元,并输出最少硬币的数量。

这是一道经典的动态规划类问题。动态规划类问题已经是科技公司面试的必考算法,对于刚接触的人来说可以说是学得一脸懵逼。它的题目类型多,没有固定的解题模板难度中上,基本成为了应聘者能否冲击offer的最后一道关卡,且出题率越来越高,内卷得厉害。

这里整理我自己的学习经验,以供参考。

阅读全文 »

高低频磨皮技法

作用:将皮肤的纹理和光影分开,皮肤纹理的信息储存在高频的图层中,皮肤光影的信息储存在低频的图层中,进而达到快速修复皮肤的效果。

步骤讲解

  1. 选中要磨皮的图层,复制2个新图层;
  2. 下面图层为低频光影图层,执行高斯模糊,数值以模糊掉画面细节为准;
  3. 上面图层为高频细节图层,执行图像-应用图像:
    • 通道:RGB
    • 混合模式:减去
    • 缩放:2
    • 补偿值:128
  4. 上面图层混合模式改为线性光
  5. 创建观察图层:黑白图层和曲线图层,把画面压暗突出细节;
  6. 选择低频图层,使用图章工具或者混合器画笔工具处理光影:
    • 图章工具修复方法:吸取正常光影皮肤涂抹不规则光影皮肤;
    • 混合画笔工具修复方法:**潮湿30%,载入90%,混合60%,流量90%**。顺着面部光影分布修饰。

增强照片清晰度

  1. 养成好习惯,Ctrl + j 复制图层;
  2. 选择复制的图层,Ctrl + I 反相,透明度调整至50%;
  3. 滤镜-模糊-表面模糊:
    • 半径:19
    • 阈值:68
  4. 将原图层与该图层复制一份,合并图层;
  5. 隐藏原先处理的图层,将合并好的图层模式改为叠加/柔光;
  6. 复制多层,修改透明度调整最终效果