Focus on game develepment

游戏技术资料,游戏技术文档

Unity 5.x Shaders and Effects Cookbook中文版翻译(第二版)

​ 我打算试着翻译这本技术书,目的又两个,1.希望自己能帮助英文不太好的朋友,2.希望自己也学到这些知识,顺便帮助自己提升英语水平。我英语水平不是很好,接下来如果有什么错误的地方,有看到的朋友还请帮忙纠正。我不会web前端技术,我想试着学学markdown语法,尽量让页面好看些但是最重要的还是内容。 Unity 5.x Shaders and Effects Cookbook中文版(第二版) 目录表 鸣谢 关于作者 www.PacktPub.com 电子书, 优惠, 还有其他 为什么需要订阅? 前言 这本书包含哪些内容 学习的过程中你需要准备的 本书的适合人群 内容结构 始前准备 操作步骤 原理介绍 额外内容 相关补充 本书的一些文体说明 读者反馈 客户支持 示例代码下载 本书一些彩图的下载 勘误表 盗版声明 本书有问题请联系 1.创建你的第一个着色器 介绍 创建一个基本的标准着色器 始前准备 操作步骤 原理介绍 相关补充 如何把Unity 4的旧着色器迁移至Unity 5 始前准备 操作步骤 着色器版本的自动升级 使用标准着色器 迁移用户自定义的着色器 原理介绍 相关补充 给着色器添加属性 始前准备 操作步骤 原理介绍 相关补充 使用表面着色器的属性 操作步骤 原理介绍 额外内容 相关补充 2.表面着色器和纹理贴图 介绍 漫反射的着色处理 始前准备 操作步骤 原理介绍 使用包组 操作步骤 压缩矩阵 相关补充 向着色器添加纹理...

June 26, 2023 · 2 min · 282 words · Link

修改代码换行符

Windows中换行符转换 1.使用到的工具dos2unix 工具的下载地址dos2unix 下载完后解压到一个目录中,并且把该目录设置到path中去。 2.新建一个bat文件,将下面的批处理代码复制进去 @echo off setlocal enabledelayedexpansion chcp 65001 set "CURRENT_DIR=%~dp0" set "CURRENT_DIR=%CURRENT_DIR:~0,-1%" echo %CURRENT_DIR% cd %CURRENT_DIR% echo 当前CMD默认目录:"%cd%" ::下面的地址换成自己对应的地址 cd ..\..\..\Assets for /R %%G in (*.cs) do dos2unix "%%G" echo 当前CMD默认目录:"%cd%" echo "转换完毕" PAUSE 双击运行bat文件,就会把Assets目录下所有的.cs文件转换成LF换行符,如果要包含其他类型的文件,则把for /R %%G in (*.cs) do dos2unix "%%G" 这行代码的 (*.cs) 改成想要的文件类型即可。比如 for /R %%G in (*.cs *.lua *.html) do dos2unix "%%G" 则会把目录下所有的.cs,.lua,.html都转换成LF。 如果是想把LF转换成CRLF,则把for /R %%G in (*.cs) do dos2unix "%%G" 中的 dos2unix 改成 unix2dos 即可:...

June 17, 2024 · 1 min · 102 words · LINK

Cpp模板学习

CPP模板学习 1.C++ 模板,模板的声明和定义都放在同一个.h文件中,不然会出现undefined reference to。因为模板类它是一个模板,只有应用了具体的类型之后,才会实例化。如果分开在.h和.cpp两个文件中,在编译器编译cpp文件的时候,因为也是以template <typename T> 开头,这不是具体的实例,不会有具体的代码生成。所以还是没有定义。 2.当有多个重载模板对一个调用提供同样好的匹配时,应选择最特例化的版本。 3.对于一个调用,如果一个非函数模板与一个函数模板提供同样好的匹配,则选择非模板版本 4.在定义任何函数之前,记得声明所有重载的函数版本。这样就不必担心编译器由于未遇到你希望调用的函数而实例化一个并非你所需的版本。 **5.—————–

April 3, 2024 · 1 min · 12 words · Link

Unity的Addressables学习日志

1.构建Player的时候,项目的资产数据是如何放进Player中的 由下图可以看出来Unity中的资产分成了4个主要类别: 1.被场景引用的资源 2.放在Resources文件夹中的资源 3.标记为了Addressables Group的资源 4.放在了StreamingAssets文件夹中的资源 2.如果同一个资产被划分到了不止一个类别上,那么该资产在构建的时候就会产生重复,划分了多少个就会复制多少个 3.Addressables Groups中的共享资产 对于一个标记为非Adressables的资产,如果有不止一个Adressablees的资产引用了它,那么它会在每个引用了它的Addressables的bundle中都复制一份。如下图所示: 为了消除这种复制,那么可以将这个共有的资产也标记为Addressables。然后把它引入到一个已存在的bundle中就可以了。如果此时一个bundle要引用它,那么必须在该bundle实例化前,将引入了共有资产的bundle先加载才可以。 4.Sprite的依赖 图集的引用跟其他资产不一样。 情形一 三张纹理,分别在三个不同的group中,它们会分别进入三个不同的ab包,彼此之间没有依赖,每个ab中图片的大小是500KB 情形二 还是这三张图片,它们被放进了一个图集,这个图集没有被标记为Addressables。那么包含这个图集的ab包将有图集的1500KB的大小。而另外两个ab包则只包含Sprite的元数据(只有很小的几KB),并且将包含图集的ab包列为自己的依赖。无论是哪个ab包包含这个图集,在重新构建之后都是跟前面一样的结果,这个过程由Unity控制,用户决定不了。这是跟标准的处理依赖重复资源过程的最大不同。Sprites的加载依赖它的图集,而图集的加载只依赖包含它的ab包的加载。 情形三 在上面的情形二的基础上,图集被标记成了Addressables并且单独放在它自己的图集中。这时候就会创建4个ab包。如果使用的是Unity2020.x或者更新的版本,那么在构建之后,4个ab包之间的依赖关系会和期待的一样,即图集资源在图集的这个ab包,有1500KB。另外三个ab包把图集的ab包作为依赖,只有几KB的引用数据而已。如果使用的是Unity2019.x或者更旧的版本,那么纹理资源就可能存在于这4个ab包中的某一个。另外三个ab包依然把图集所在的ab包作为依赖。然而此时图集所在的ab包可能仅仅只包含了图集的一些元数据,而真正的纹理资源可能在其他的另外3个ab包中。 5.Addressable预制体跟Sprite的依赖 情形一 跟三个标记为Addressables的纹理不同的是,这里是三个标记为Addressables的Sprite的预制体。每个预制体包含它独自的Sprite。在构建之后,三个ab包的大小如期望的那样,都是500KB。 情形二 跟情形一类似,3个预制体分别引用不同的Sprite,只不过所有的3个Sprite添加到一个图集中,但是这个图集没有标记为Addressables。在这种情形下,图集的纹理机会产生重复。在构建之后,三个ab包都大概有1500KB。这个重复资源的规则类似于一般的Addressables重复资源规则,但是跟前面介绍的 Sprite的依赖 中的情形二又不一样。 情形三 基于上面的情形二的预制体,纹理和图集,不过这里把图集标记为Addressables。此时图集纹理就仅仅只存在在包含图集的ab包中。另外的三个预制体的ab包就把这个图集的ab包作为依赖。 6.ab包的分包规则 1.可以将一个group中所有Addressables的资源都打进一个ab包中 2.可以将一个group中的每个Addressables资源分别打进它独自的ab包中 3.可以将使用同一个label的所有的Addressables资源打包进一个ab包中 7.同一个group中的场景资源会跟其他的Addressables资源分开打包 也就是说一个group中如果含有场景资源和其他非场景资源,那么构建之后,至少会得到两个bundle,一个包含场景资源,一个是除了场景外的其他资源。

August 29, 2023 · 1 min · 35 words · LINK

Ubuntu22.04运行unity2020.3.xx报错unity_csc.sh_Aborted

在Ubuntu22.04中出现,而且出现这个错误的版本是低于Unity2022.x的版本。自己测试了Unity2020.x和Unity2021.x都会出现这个错误。 重现的步骤也很简单,创建一个空项目并进入就会报错,然后提示进入safety mode。 这个错误会在Unity的Editor.log中留下线索,不过在打开项目前,记得先把Editor.log先删除,这样在报错的时候会生成一个新的Editor.log文件。也可以不用这样做,这样做的主要目的是日志少检查起来比较简单。 打开Unity编辑器的日志:Editor.log。发现以下关键信息 -----CompilerOutput:-stderr---------- No usable version of the libssl was found /home/eyap/Unity/Hub/Editor/2020.3.33f1/Editor/Data/Tools/RoslynScripts/unity_csc.sh: line 3: 25959 Aborted (core dumped) "/home/eyap/Unity/Hub/Editor/2020.3.33f1/Editor/Data/Tools/RoslynScripts/../../Tools/Roslyn/csc" /shared /noconfig @temp/UnityTempFi -----EndCompilerOutput--------------- 从 No usable version of the libssl was found 可以看出是缺少了 libssl库导致的。用下面的命令安装一个就行了: echo "deb http://security.ubuntu.com/ubuntu focal-security main" | sudo tee /etc/apt/sources.list.d/focal-security.list sudo apt-get update sudo apt-get install libssl1.1 相关的讨论连接: https://forum.unity.com/threads/unity2020-3-doesnt-works-on-linux.1338869/

August 29, 2023 · 1 min · 55 words · LINK

Xlua集成第三方库

XLua集成第三方库(Rapidjson举例) 参考教程:https://zhuanlan.zhihu.com/p/389424029 1.环境准备 (1)cmake的安装 https://cmake.org/download/ (2)安装Visual Studio最新版(2017,2019,2022)都行,去微软官网下载 (3)安卓的话,下载Android Studio,然后安装好Android SDK,NDK,并且配置好ANDROID_SDK和ANDROID_NDK 2.将XLua克隆到本地 xlua的地址 https://github.com/Tencent/xLua 进入到拉取下来的xlua文件夹, 在build文件夹中新建lua-rapidjson文件夹,并在该文件夹下新建include和source文件夹 4.拉取lua-rapidjson的项目到本地 这里需要说明一下,lua-rapidjson两个版本: 一个是原作者的最新版 https://github.com/xpol/lua-rapidjson 另一个是XLua的做过兼容的版本: https://github.com/chexiongsheng/build_xlua_with_libs 新版肯定是更新,但是再编译的过程中会遇到很多错误,非常的麻烦浪费时间,所以我们还是选择XLua做过兼容的版本,节省时间,并且也能满足要求。 将build_xlua_with_libs克隆到本地。 5,直接将build_xlua_with_libs中build文件夹下的lua-rapidjson文件夹复制到自己的xlua的build文件夹下面。 6.修改xlua/build/CMakeList.txt文件,在头部加入如下代码 #begin lua-rapidjson set (RAPIDJSON_SRC lua-rapidjson/source/rapidjson.cpp ) set_property( SOURCE ${RAPIDJSON_SRC} APPEND PROPERTY COMPILE_DEFINITIONS LUA_LIB ) list(APPEND THIRDPART_INC lua-rapidjson/include) set (THIRDPART_SRC ${THIRDPART_SRC} ${RAPIDJSON_SRC}) #end lua-rapidjson 并且把头部的VERSION 改成自己的cmake版本(在控制台输入cmake –version),我这里是cmake_minimum_required(VERSION 3.26.4) 6.编译windows的xlua.dll 这里我们选择lua54版本 所有编译脚本都是按这个方式命名:make_平台_lua版本.后缀。 比如windows 64位lua53版本是make_win64_lua53.bat,android的luajit版本是make_android_luajit.sh,要编译哪个版本就执行相应的脚本即可。 执行完编译脚本会自动拷贝到plugin_lua53或者plugin_luajit目录,前者是lua53版本放置路径,后者是luajit。 用代码编辑器打开这个bat文件,将Visual Studio版本改成自己安装的对应版本, 如果不知道就打开 Developer Command Prompt这个控制台,里面会有如图所示 修改完后如下所示 然后运行这个bat文件,注意看控制台输出日志,如果没有什么错误,并且有如下图中的第三库编译的输出,那就说明成功了 跟据日志可以知道,下图的文件夹是临时生成的,每次编译记得先把这两个文件夹删除,不同的平台的编译,这两个文件夹的名字会不一样,编译前记得删除 7.编译成功后,记得查看日志 生成的xlua.dll会复制到 build/plugin_lua54/Plugins文件夹中, 将其中的文件全部复制到Unity的Plugins文件夹下面即可...

July 13, 2023 · 1 min · 211 words · Link

Unity编辑器为切换平台,工程加载完成事件添加自动处理

有时候我们在Unity项目中,需要在切换平台后,或者项目加载完后,做一些自动化的处理,比如项目加载完后检测一些配置,或者检测项目版本。或者在切换项目平台的时候,需要跟据不同的平台设置不同的字体移除不属于该平台的一些资源等等。下面记录一下如何添加对这两个事件的处理。 1.Unity切换平台事件的处理 要处理这个事件,我们需要将类实现 IActiveBuildTargetChanged 接口,并重写该接口的 OnActiveBuildTargetChanged方法。那么当切换平台的时候,就会执行这个类的 OnActiveBuildTargetChanged 方法。在这个方法中,我们就可以添加自定义的一些处理逻辑了。代码如下: /// <summary> /// 切换平台后,对一些资源的处理 /// 有些资源只有再特定的平台才会使用,再切换平添后,不要的资源要移除或者移动到别的地方 /// </summary> public class BuildTargetChangedTool : IActiveBuildTargetChanged { public int callbackOrder { get; } public void OnActiveBuildTargetChanged(BuildTarget previousTarget, BuildTarget newTarget) { //切换平台后的一些处理 PlatformResTool.ProcessFonts(newTarget); PlatformResTool.ProcessThirdSDK(newTarget); LinkXmlBuildProcessor.LinkXmlOp(newTarget); AssetDatabase.Refresh(); } } 2.Unity项目加载完事件的处理 项目加载完成的事件跟切换平台的事件的处理方式不一样,这里需要使用 InitializeOnLoad 这个特性来实现。我们需要给类添加这个特性,同时它需要一个静态构造方法,当项目加载完成后,Unity编辑器就会调用这个静态构造方法,然后在这个静态构造方法中我们就可以添加一些自己的处理逻辑了。代码如下: /// <summary> /// 工程加载完,要处理这些跟平台相关的资源 /// </summary> [InitializeOnLoad] public class StartUpTools { static StartUpTools() { if (!EditorApplication.isPlayingOrWillChangePlaymode) { BuildTarget buildTarget = Packager.GetBuildTarget(); PlatformResTool.ProcessFonts(buildTarget); PlatformResTool.ProcessThirdSDK(buildTarget); LinkXmlBuildProcessor.LinkXmlOp(buildTarget); AssetDatabase....

June 26, 2023 · 1 min · 74 words · Link

水的智慧

水它蕴含很多智慧, 它的智慧在于总能适应。 若寒,则成冰。 若温,则成水。 若火,则成汽。 把水放在不同的容器里,水会变成不同的形状。 好比一桶水, 你静,它静。 你去搅拌,它也跟着流动起来。 你若拍打,它就溅起水花。 放入不同的颜料,则成不同色彩。 它总会让自己放低,总会找到一条路,流向大海。 它并不会消失,所见蒸发,流失,那不过在循环。 它能包容。 你会看见水有色彩,有泥沙,会浑浊,那不过是掺和进来的颜料,杂质。 水的本质并没有变,它还是水。 水流不息,生命不止

May 17, 2023 · 1 min · 17 words · Link

用数组来实现热度图

用数组来实现热度图 着色器难以掌握的一个典型的原因就是缺少合适的文档。许多开发者在学习着色器的时候被代码搞得一团糟,原因就是他们没有很深的知识来解释眼前到底发生了什么。事实上 Cg/HLSL 中有着大量的臆断,这些臆断又没有被正确的证明过,这就让问题变得更加的突出。Unity3d允许C#脚本使用诸如 SetFloat,SetInt,SetVector 等之类的方法来跟着色器通信。遗憾的是,Unity3D没有类似 SetArray 的方法,也正因如此导致很多开发者们以为 Cg/HLSL 不支持 数组(arrays)。但事实并非如此,这篇文章将会给你展示向着色器传递数组的可能性。需要注意的是GPU为并行计算进行了高度的优化,所以如果在着色器中使用 循环结构(loops) 将会极大的降低它的性能。 在这个知识点中,我们将会实现一个热度图,看起来大概跟下图一样: 始前准备 这个知识点中介绍的效果是从一些设置好的点中创建一个热度图。这个热度图将会覆盖在另外一张图片的上面,就像一张前置图片。下面是必要的步骤: 1.在Unity中使用一张纹理创建一个 quad,这张纹理就是用来创建热度图的那张纹理。在我们的例子中,使用了一张伦敦地图的纹理。 2.创建另外一个 quad,并且把它放在前面创建的那个quad的上面。我们的热度图将会在这个quad上产生。 3.创建一个对应的材质,并且把材质和着色器都应用到第二个quad上。 操作步骤 这个着色器跟我们之前创建的着色器还是有很大不同,当然它也相对较短。因此,下面的步骤中直接提供了着色器完整代码: 1.将下面的的着色器代码整个复制到新创建的着色器中: // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' shader "Custom/Heatmap" { Properties { _HeatTex ("Texture", 2D) = "white" {} } Subshader { Tags {"Queue"="Transparent"} Blend SrcAlpha OneMinusSrcAlpha // Alpha blend Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag struct vertInput { float4 pos : POSITION; }; struct vertOutput { float4 pos : POSITION; fixed3 worldPos : TEXCOORD1; }; vertOutput vert(vertInput input) { vertOutput o; o....

May 4, 2023 · 2 min · 372 words · Link

实现一个毛皮效果的着色器

实现一个毛皮效果的着色器 材质的外观取决于它的物理结构。着色器试图去模拟它们,但在那样做的过程中,它们都把光的行为方式过度的简化了。因为材质有肉眼可见的复杂结构所以渲染起来尤其的难。比如大多数的纺织布料和动物的毛皮。在这个知识点中将会展示去模拟皮毛和其他材质(比如草)的可能性,而不仅仅是限于那些平坦的的表面模拟。为了完成这些,同样的材质将会被一遍又一遍的进行多次绘制,每一次都会增加它的大小。因此创造了皮毛的假象。 这里着色器所呈现出的效果基于了 Jonathan Czeck 和 Aras Pranckevičius 的工作成果: 始前准备 为了让这个知识点能起效果,你需要准备两样东西。首先是一张皮毛的纹理因为它要呈现外观。其次是另外一张用来表示皮毛分布的纹理,并且它要跟前一张纹理高度匹配。下面的图片展示的是美洲豹的毛皮纹理(左)和它可能的控制遮罩纹理(右): 白像素的控制遮罩将从原始的材质挤压而来,模拟了一张毛皮。那些白像素分布稀疏程度非常的重要,因为它能给我们一种材料是由很多细小的毛发构成的假象。创建一张那样的纹理的简单方式如下: 1.给你的原始纹理设置一个阈值,好让原始纹理失去毛皮厚度的时候截取斑点纹理。 2.添加一个噪音过滤器让图像像素画。噪音的RGB通道一定去掉关联从而获得黑白的结果。 3.为了看起来真实一点,覆盖一个 Perlin 噪音过滤器来给毛皮添加一些变化。 4.最后,再应用一个阈值过滤器让纹理的像素更好的分离。 跟其他着色器开始前一样,你需要创建一个新的 标准着色器(standard shader) 和材质来容纳它们。 操作步骤 对于这个知识点,我们能开始修改我们的 标准着色器(standard shader) 了: 1.在着色器的 属性(Properties) 上添加下面的代码: Properties { _Color ("Main Color", Color) = (1,1,1,1) _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {} _Glossiness ("Smoothness", Range(0,1)) = 0.5 _Metallic ("Metallic", Range(0,1)) = 0.0 _FurLength ("Fur Length", Range (.0002, 1)) = .25 _Cutoff ("Alpha cutoff", Range(0,1)) = 0....

May 3, 2023 · 5 min · 907 words · Link