Unity3D

《Unity3D内建着色器源码剖析》

书籍信息 信息 详情 定价 89.00 出版社 人民邮电出版社 版次 1 出版时间 2019年08月 开本 16 装帧 平装 页数 334 ISBN编码 9787115507044 官方QQ群 群1号码:672523982 书籍配套代码 代码文件 MD5值 Unity3D内建着色器源代码 版本2017.2.0f3 MD5: 1737874a497c6fa04031af3c90ff2f99 第12章的代码工程 MD5:640938e9f1a259b7e693b1abe866f368 书中参考引用到的一些技术文章 微软网站上关于DXT及BC系列格式的详细介绍 微软MSDN上有介绍块状压缩的文章 nVidia开发者网站有一篇介绍单程立体渲染原理的文章。 Unity3D官网也有单程立体渲染的介绍 《Unity3D内建着色器源码剖析》勘误表 第1版第1刷 章节 页数 位置 错误内容 正确内容 1.2.2 正文第4页 第5段第5行 $$\left< p_1,p_2,p_3 \right>$$ 的排列顺序称为顺时针方向(clockwise,CW)。 $$ \left< p_1,p_3,p_2 \right> $$ 的排列顺序称为顺时针方向(clockwise,CW)。…… 1.2.2 正文第4页 第6段第2行 在图1-7(b)的左手坐标系下排列顺序改为 $$ \left< p_1,p_2,p_3 \right> $$ 在图1-7(b)的左手坐标系下排列顺序改为 $$ \left< p_1,p_3,p_2 \right> $$ 1.

在低版本中的XCode中使用高版本的iOS SDK

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 当iPhone或iPad的手机的iOS系统,升级到了版本,例如11.1版本时,而当前的Xcode版本,例如Xcode9,所能编译出来的软件,最多只能支持的最高版本是11.0时,就会出现以下的问题: 最好的解决的方式当然是直接升级XCode到最新版本,但有时候,升级XCode到最新的版本,需要你当前运行的MacOS的版本到某一个版本号,即还需要你首先升级操作系统,但往往有时候因为你的硬件比较陈旧,没法升级到某个新版本的MacOS了,这时候你就不得不购买新的iMac或者Mac Mini,而如果这时候你又 囊中羞涩 的话……。 为了解决这个囧况,可以通过一些hack手段,让你当前低版本的XCode,能使用上新的iOS SDK。方法如下: 1 首先下载iOS SDK 苹果网站上提供了SDK的下载,但往往在天朝内访问苹果实在太慢了,所以在 这里 有人整理出来所有的iOS SDK供下载。( 务必注意的是,因为这些SDK是非官方渠道提供的,本站不保证其安全性和有效性,所以必须要慎用,使用的话责任自负,本站将不承担任何责任 )。接着找到XCode程序的安装路径,一般是在 【/Appplications】 目录下,右键选择 【显示包内容】 打开,一路进入到 【/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport】 。把下载得到的SDK放置到这个DevicesSupport目录下,如图所示: 2 修改SDKSetting.plist文件 3 修改SDKSettings.plist文件中的版本号 进入 【/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk】 目录,打开SDKSettings.plist文件,将里面所有跟版本有关的数字都修改为填上最新的SDK版本号,例如11.1即可。运行就好可以了,如下图所示: 参考网页 解决低版本Xcode不支持高版本iOS真机调试的问题

从计算着色器到四边形【翻译】

原文地址 // input texture Texture2D<float3> _sourceTexture; // a compute buffer that we can append to for output AppendStructuredBuffer<int2> _brightPoints; 在上面的代码段中,_sourceTexture是从外部传给GPU的纹理。和在fragment shader中访问纹理不一样的是,在片元着色器中通过采样器(sampler)获取纹理,纹理坐标是浮点数,而在compute shader中,“纹理”可以视为一个二维数组,可以通过整数索引值,直接访问这“二维数组”中的元素——纹素。 AppendStructedBuffer AppendStructuredBuffer 可视为是原始缓冲区的“升级版”,即结构化缓冲区。原始缓冲区(raw buffer)只是一个字节数组,而结构化缓冲区意味着可以为缓冲区中的每个元素定义一个结构。可以用来AppendStructuredBuffer.Append()方法将元素从缓冲区的末尾加入。重AppendStructuredBuffer.Append()是一个线程安全的操作。即使有数千个线程同时尝试向缓冲区添加某些内容,也不会产生冲突。 // tell Unity that the function "FindBrights" is a compute kernel #pragma kernel FindBrights // define thread groups for the FindBrights kernel [numthreads(32, 32, 1)] pragma kernel 指令 #pragma kernel FindBrights是Unity专用的代码。用来通知Unity函数FindBrights是计算内核(compute kernel),这意味着它可以用作计算着色器,而不仅仅是一个普通函数。 numthreads指令 numthreads指令的三个输入参数分别表示该着色器在工作组(Work Group)内的线程布局。具体来说,numthreads(x, y, z)指令中xyz三个参数分别定义了在X、Y和Z三个维度上每个工作组中线程的数量。这三个参数决定了工作组内线程的总数量,例如numthreads(8, 8, 1) 就定义了一个工作组包含 8 x 8 x 1 = 64 个线程。工作组的总线程数直接影响计算的并行性,在实际调用时,通过Dispatch()函数定义工作组的分布。如下代码:

在Unity3D中使用Visual Studio调试shader【翻译】

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 原文地址 本文主要介绍在U3D中调试shader代码的主要技术:false-color images:通过设置片元颜色中的某个分量,使得该值可视。然后根据resulting image中的颜色分量的亮度(intensity of that color component),你可以得到shader代码中的值的结论,这种技术的确是一种很原始的调试技术,但不幸的是,这在U3D中并不是不常见的。 1 顶点数据来自何方 在RGB cube一节中,你可以看到片元着色器如何通过顶点着色器输出的结构体中,获取到对应的数据。那么问现在的问题是:顶点着色器从何方拿到这些数据?在U3D环境下,答案是从绑定到game object中的Mesh Renderer组件中获取。Mesh Renderer组件将在每一帧中所有的发送网格顶点数据给OpenGL。这一步发送操作通常被称为“draw call”。必须注意的是,每一个的draw call都有一些性能耗费(performance overhead)。因而,一次性地给OpenGL发送一个大的网格数据,比分多次发送,每次发送一些较小的网格数据,要来得更高效些。这些网格数据通常由一系列的三角形组成,而每一个三角形则是以”三个顶点数据和一些其他属性数据“的方式被定义。这些属性数据将会通过”顶点输入参数(vertex input parameter)“的方式在顶点着色器中被启用。每一个顶点输入参数将会指定一系列的语义,如POSITION, NORMAL, TEXCOORD0, TEXCOORD1, TANGENT, COLOR等等。在U3D环境下的Cg语言的特定编程实现中。这些内建的顶点输入参数将会由一个特定的名字。 2 内建的顶点输入参数,以及如何使得它们可视 在U3D中的,内建的顶点输入参数不仅仅有特定的语义表示符号,还有特定的变量名字和类型,此外,他们还被包含在一个单独的结构体中,如下: struct vertexInput { float4 vertex:POSITION; // position (in object coordinates, i.e. local or model coordinates) float4 tangent:TANGENT; // vector orthogonal to the surface normal float3 normal:NORMAL; //surface normal vector (in object coordinates; usually normalized to unit //length float4 texcoord:TEXCOORD0; //0th set of texture coordinates (a.

Unity3D PlayerPrefs的存储位置

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 平台 存储位置 macOS 存储在 【~/Library/Preferences】 目录下名字为 【unity.[company name].[product name].plist】 文件中,其中的 【company name】 和 【product names】 在 【Project Settings】 面板中设置。而且这个plist文件是为编辑器版本和单独可执行版本的程序共同使用。 Windows 存在注册表中的注册项中,该注册项的路径是 【HKEY_CURRENT_USER\Software[company name][product name]】。其中的 【company name】 和 【product names】 在 【Project Settings】 面板中设置。注意编辑器版本和单独可执行版本的注册表路径是不同的,例如 【company name】 是 “TomCompany” ,例如 【product name】 是 “TomGame” 的话,在编辑器中执行程序,其注册项路径为 【计算机\HKEY_CURRENT_USER\Software\Unity\UnityEditor\TomCompany\TomGame】 Linux PlayerPrefs存储在 【~/.config/unity3d/[CompanyName]/[ProductName]】 。其中的 【company name】 和 【product names】 在 【Project Settings】 面板中设置.。 Windows Store Apps PlayerPrefs存储在 【%userprofile%\AppData\Local\Packages[ProductPackageId]\LocalState\playerprefs.dat】 文件中 Windows Phone 8 PlayerPrefs存储在应用的 “local folder” 中,可查阅Directory.

Unity3D的碰撞检测响应处理细节

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 1 对碰撞做出响应所必须的条件 要想两个物体A,B发生碰撞检测,即触发OnCollision相关事件,或者触发OnTrigger相关事件。必须: 物体A,B都挂接上了一个碰撞器组件,即Collider类(2D环境下是Collider2D类)的子类 运动着的物体,要携带一个刚体组件,即RigidBody类(2D环境下是RigidBody2D类),另一方的物体如果是静止的话,可以不用携带刚体组件。 2 碰撞时触发OnCollision相关事件的条件 在满足第1节中所提出的条件下,当两者的刚体组件(如果有的话)的Is Kinematic属性都未勾选,且两者的碰撞器组件的Is Trigger属性,都没勾选时,便会触发OnCollision相关事件。 3 碰撞时触发OnCollision相关事件的条件 在满足第1节中所提出的条件下,当两者的碰撞器组件的Is Trigger属性,其中有一个勾选时,就会触发OnTrigger相关事件。 4 响应事件的分类 响应事件分为Enter、Stay、Exit。以OnTrigger为例,就是OnTriggerEnter、OnTriggerStay、OnTriggerExit(2D环境下就是OnTriggerEnter2D,OnTriggerStay2D,OnTriggerExit2D,OnCollision事件以此类推)。 Enter事件便是两个物体碰撞的那一瞬间,此事件在碰撞过程会执行一次 Stay事件表示两个物体在持续接触时,此事件在碰撞过程会多次执行。 Exit事件便是两个物体在分开的那一瞬间,此事件在碰撞过程会执行一次

解决Unity3D在编译时出现libpng iccp警告的问题

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 项目组使用Unity3D4.6进行渠道商SDK接入,在编译Android版本时,发现部分渠道商提供的SDK包在编译时会出现如下图的问题: 经查证,新版本的Unity3D采用了较高版本的libpng库作为png格式图片的处理模块,产生此问题的原因是新版本的libpng对png的ICCP采用了更严格的约束条件,因此,我们必须使用软件对渠道商提供的这些资源png图片进行处理,以解决这个问题。开源软件 ImageMagick 提供了处理这个问题的方案。 从ImageMagick网站下载了ImageMagick Display软件包,安装后如下图: 我们使用软件包中的convert.exe程序对这些图片进行处理。convert程序是一个命令行程序,该程序有很多开关参数。我们使用-strip参数处理。命令行格式为: convert 待处理的图片的文件名 -strip 处理后输出的图片文件名 如果需要一口气处理同一文件夹下的许多png,我们可以将处理命令写成一个批处理文件,代码如下: set fn=E:\software\ImageMagick-6.9.0-Q16\convert.exe for /f "tokens=*" %%i in ('dir/s/b *.png') do "%fn%" "%%i" -strip "%%i"

在Unity3D中模型渲染时边缘抖动有杂点的问题解决方案

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 项目主美反映了一个问题,即在U3D中,给模型使用了镜面高光的材质,结果模型的边缘有很多白色的杂点,如果换用了普通漫反射材质的话,杂点的明显稍微没那么强烈,如下图,左边是使用了镜面高光材质,右边是使用了漫反射材质。 一开始,我以为是因为模型的Z-fighting问题,即两个带纹理的模型因为太靠近了,导致因渲染时的精度问题而造成模型的穿插。但后来检查了模型,并不存在“靴子里面还套着小腿”的这种情况。所以不是Z-fighting的问题。 后来google了一下,发现老外们也曾经发现过类似的问题。最终有人提出这是一个因为抗锯齿做得不好的问题,解决方案就是给摄像机加一个基于image post process机制的脚本AntialiasingAsPostEffect,然后选用FXAA反走样的着色器。加入之后,效果不错,杂点问题得到了较为明显的改善。 KlayGE引擎开发者,大神龚敏敏认为基于post process处理的技术目前已经是逐渐成为主流。nVidia等公司有很多大牛也提出了不少的算法。比如FXAA算法就是由nVidia的研究员Timothy Lottes提出的算法。所以可以预见不远的将来这项技术会逐渐普及。但目前因为硬件能力的问题,在手机移动平台上,依然要注意使用这种算法的性能问题。

Unity3D烘焙光照图在移动平台上颜色失真的分析和应对方案

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com Unity烘焙的LightMap是32bit的HDR图,而移动设备通常不支持 HDR图(32bit per channel) ,会按照 LDR图(8bit per channel) 的形式进行处理,因此会出现色偏问题。即颜色变淡,在例子中地面为绿色,因此相比于PC平台,切到移动平台如Android或者iOS上之后,黄色变淡,使得地面的绿色更加显眼。对此Unity3D技术支持人员的的建议是: 可尝试自行修改LightMap的DecodeLightmap函数,该函数可在 Unity\Editor\Data\CGIncludes\UnityCG.cginc 文件中找到。需要说明的是,这种方法也不能达到与PC端完全一致的效果。 为了避免类似问题,请不要使用过于强烈的Light进行烘焙,因为Light的强度(Intensity)越高,色偏问题会越严重。

Unity3D的渲染路径的细节一览表

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 1 功能列表 功能 Vertex Lit Rendering Path Forward Rendering Path Deferred Rendering Path 逐像素光照效果(Normal map等) N Y Y 多render pass支持 仅在一个render pass中完成光照计算 允许多render pass 允许多render pass 逐像素实时阴影 N 仅支持一盏Directional Light Y 双光照贴图(Dual Lightmaps) N N Y 深度缓冲区和法线缓冲区 N Additional Render Pass Y 软粒子(soft particle) N N Y 半透明的物体(Semitransparent objects) N Y Y 反走样(抗锯齿 anti aliasing) N Y Y 灯光剔除蒙版(Lighting Culling masks) 受限制 Y Y 光照保真度(Lighting Fidelity) 所有光照计算在顶点着色器中执行 部分光照计算在片元着色器中执行 所有光照计算在片元着色器中执行 每像素光照的性能耗费 像素数 像素数*被实时光照亮的像素数 PC上的所需的最低shader model版本 任意版本 最低2.