Unity3D

The Universal Additional Camera Data component

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com URP版本:8.2.0 源参考网页 通用附加相机数据组件(Universal Addtional Camera Data Component) 是通用渲染管线(URP)用于内部数据存储的组件。通用附加相机数据组件使URP可以扩展和覆盖Unity标准相机组件的功能和外观。 在URP中,具有Camera组件的GameObject还必须具有通用附加摄影机数据组件。如果您的项目使用URP,则在创建Camera GameObject时,Unity会自动添加通用附加相机数据组件。您不能从带有Camera组件的game object中删除通用附加相机数据组件。 如果您使用脚本来控制和自定义URP,则可以通过以下脚本访问摄像机的通用附加摄像机数据组件: var cameraData = camera.GetUniversalAdditionalCameraData(); 有关更多信息,请参见UniversalAdditionalCameraData API文档。如果需要通过脚本频繁访问通用附加摄像机数据组件,则应缓存对其的引用,以避免不必要的CPU工作。

Universal Render Pipeline

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 1 URP的常见问题回答 URP和HDRP(High Definition Render Pipeline)不能混用。 可以从内建render pipeline转到URP。可以用升级器(upgrade)升级内建shader到URP shader。如果自定义的shader的话,需要手动去upgrade。 不能在运行期换pipeline asset。 URP和HDRP之间不能换用。 通过Package Manager获取URP的package 在URP Asset的【Player Setting】界面上可以找到Dynamic Batching的checkbox 选中材质球时,在Inspector面板中,找到Render Face选项,选择Both选项,即可开启Double Sided Global Illumination。 URP适用于各种平台,包括PC和mobile 在Built-in RP和URP功能对照表中,标识为Not Supported的功能,表示没有且不会在后续版本中实现。 如果在build URP工程时很慢,检查以下shader stripping是否设置对,要strip掉可以strip掉的shader。 缺省地,URP是在linear space中工作,可以在Player Setting中将其设置为在gamma space中工作。 通过创建ScriptableRendererFeature脚本,使用scriptable render pass可以扩展URP的功能。 2 URP Asset URP版本:8.2.0 源网页 要使用URP asset,需要创建一个URP asset,并在【Graphic settings】界面将其赋值使用。URP asset控制图形渲染的功能,设置图形渲染的质量等级。URP asset本身是一个scriptable object。它继承自RenderPipelineAsset类。在一个工程中可以使用多个URP asset,并且可以在它们之间切换使用,比如有个URP asset是启用了阴影,另一个URP asset关闭了阴影。 URP有以下几大类的控制选项,如下: General Quality Lighting Shadows Post-processing Advanced 下面的图显示了这几个控制选项的UI: 2.1 General 这是一些用于控制管道渲染框架的核心部分常规设置 属性名 描述 对应的编辑器变量名称 Depth Texture 当在一个摄像机对象的inspector界面上启用此项时,URP将会在shader中创建一个深度纹理_CameraDepthTexture。缺省地URP将把这个深度纹理交给你场景中的所有的摄像机去使用之。 m_RequireDepthTextureProp Opaque Texture 当在一个摄像机对象的inspector界面上启用此项时,URP将会在shader中创建一个不透明的深度纹理_CameraOpaqueTexture。缺省地,URP将这个深度纹理交给你场景中的所有的摄像机使用。这个深度纹理起的作用,就很类似于built-in render pipeline中的GrabPass。在URP渲染任意的透明状网格(transparent mesh)时,该纹理将会提供一个当前场景的一个快照(snapshot) m_RequireOpaqueTextureProp Opaque Downsampling 设置Opaque Texture属性的降采样方式,有None(不采样)、2倍线性过滤(2x Bilinear),、4倍线性过滤(4x Bilinear),、4倍盒状过滤(4x Bilinear),其中4倍盒状过滤产生一种轻柔羽化的效果 m_OpaqueDownsamplingProp Terrain Holes 禁用此项的话,在build包的时候,URP将会移出所有的Terrain hole shader变体,将会减少build包的时间 – 2.

Unity的multi_compile和shader_feature编译指示符、shader variant和asset bundle

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com multi_compile编译指示符 multi_compile编译指示符的文档在这里。假如有以下的shader示例语句: #pragma multi_compile _USE_SEMITRANSPARENT _USE_OPAQUE #pragma multi_compile _MULTI_RED _MULTI_GREEN _MULTI_BLU ... fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv); #if _MULTI_RED col = col * fixed4(1,0,0,1); #elif _MULTI_GREEN col = col * fixed4(0,1,0,1); #elif _MULTI_BLUE col = col * fixed4(0,0,1,1); #endif #if _USE_SEMITRANSPARENT col.a = 0.5; #elif _USE_OPAQUE col.a = 1.0; #endif return col; } 那么根据排列组合,就会有 $ 2 \times 3 = 6 $ 种代码段的组合,即分别是 _USE_SEMITRANSPARENT与_MULTI_RED , _USE_SEMITRANSPARENT与_MULTI_GREEN , _USE_SEMITRANSPARENT与_MULTI_BLUE , _USE_OPAQUE与_MULTI_RED , _USE_OPAQUE与_MULTI_GREEN , _USE_OPAQUE与_MULTI_BLUE。总得来说,就是各种排列组合对应编译生成的变体, $\color{#FF0000}{无论有没有被使用上,都会被编译打包到游戏包或者资源包中}$ 。所以 在运行时 ,可以使用 Material.

Unity3D的Model Import Settings window - Model tab

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 1 Model tab 当选中模型文件时,Inspector窗口就会显现出Import Settings窗口,且定位到Model页。可以通过在此页中调整参数控制模型导入的细节。 Model页上的各种属性可以分为三个区,分别是: 分区 细节 (A) Scene 和关卡场景相关的,比如光源和摄像机的导入,还有scale factor的设置 (B) Meshes. 和网格导入相关的属性 (C) Geometry 和网格拓扑相关的户型,比如的顶点的纹理UV,法线等等 2 Scene分区的属性描述表格 属性 功能 Scale Factor 在导入的原始模型文件的比例值,不适合项目中的预期比例时,设置此值,可作为一个全局的对原始模型的缩放比例值。 Unity的物理系统,期望游戏世界中的1米,就对应于原始模型文件的1个单位。 Convert Units 启用此选项,可将导入的原始模型文件的比例值。转换为Unity的比例。导入BlendShapes时,启用此属性可允许Unity导入网格物体的混合形状。 Import BlendShapes Enable this property to allow Unity to import blend shapes with your Mesh. See Importing blend shapes below for details.Note: Importing blend shape normals requires smoothing groups in the FBX file Import Visibility 导入FBX设置,这些设置将会确定是否启用MeshRenderer组件,当启用时改mesh可见 Import Cameras 从.FBX文件中导入在这些文件中定义的camera Import Lights 从.

Update、FixedUpdate、LateUpdate函数,定时器和帧速率

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 1 Update、LateUpdate、FixedUpdate函数 Unity将每帧调用一次 Update() 函数。这意味着,如果你以60fps的速度运行,那意味着每秒调用60次 Update() 函数。如果以50fps的速度运行,则每秒调用50次Update函数。这也就是说。每两次执行update函数之间的时间间隔,其实是变化不定的。正是由于这一点,使用 Update() 函数的最大问题是它可能与物理引擎不同步。调用行为可以改变,因为它可以结束更快或更慢,这取决于您的图形在渲染的硬件上放置了多少负载,使用物理更新可能会导致完全错误的反应。 Unity确实会尝试以项目所指定的速率调用FixedUpdate()函数。但是,这些调用也需要根据当前实际的帧速率去确定。这意味着虽然任何给定帧上可能有零次,一次甚至超过100次对FixedUpdate()函数的调用,但Unity会动态调整到实际帧速率。通过深入挖掘,我们逐渐意识到,这也意味着对FixedUpdate()的所有调用都不一定在指定的时间间隔内。下面举例说明下这种情况: 默认情况下 FixedUpdate() 函数的更新频率是50FPS(0.02s),如果当游戏的更新频率为60FPS时,那么FixedUpdate有固定的更新速率是很好理解的,因为这种绝对可以保证到,每执行一次 FixedUpdate() 函数,就至少执行了一帧,但是如果游戏本身的更新频率就很低,例如为30FPS时,每一帧的时间间隔明显大于0.02秒的,那么这时候在每两次 Update() 函数的调用之间。 FixedUpdate() 函数就被调用了多次。 通常 FixedUpdate() 函数比 Update() 函数更频繁地被调用。 FixedUpdate() 函数可以在一帧内被调用多次,如果帧速率很低,则根本不能在帧之间调用。 如果帧速率很高,也可能不会调用 FixedUpdate() 。 在 FixedUpdate() 函数被调用之后立即进行所有物理计算和更新。 作用力,扭矩或其他与物理相关的函数时,应使用FixedUpdate函数。 FixedUpdate() 函数由一个准确可信的计时器调用,而与实际的帧速率无关,因此在 FixedUpdate() 中应用移动计算时,您不需要将您的值乘以Time.deltaTime。 Update() 函数是每一帧中执行更新操作的主要(入口)函数。 Update() 函数中用来移动非物理系统驱动的物体。 Update() 函数用来接受用户输入。 Update() 函数可用来实现简单的计时器。 由于 Update() 的执行方式,与物理引擎的执行步调不同,即可能在一帧中, FixedUpdate() 函数执行了多次,而Update函数则只执行了一次。这取决于渲染器在渲染图形时的负载量,以及所耗费的CPU时间。如果在 Update() 函数中执行物理运算时,会导致未知的结果。同时也可以看到: 函数的执行间隔,未必就是TimeManager界面中Fixed TimeStep项中所指定的值。 LateUpdate() 函数每帧会被调用一次,在 Update() 函数结束后调用 所有在 Update() 函数中执行的计算,将会在 LateUpdate() 函数调用之前完成执行。 如果实现一个跟随式的第三视角摄像机,则摄像机的状态更新放在 LateUpdate() 函数中执行是一个通用的做法。 因为你的角色是在 Update() 函数里面执行移动和转向的操作。所以在 LateUpdate() 函数执行摄像机的位置和旋转度计算,可以确保在计算时,角色已经全部完成了位置计算,摄像机可以正确地跟踪到角色的正确位置。

Unity3D shader优化技巧集合

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 一些优化的tips,基于2019.3版本 只做需要的计算,比如一直在shader设置某个固定颜色,就等于白做计算 能给vs做的,就不要给fs做,能在脚本设置的,就不要在shader里做,比如在shader代码里面用 if-else ,就不如在脚本中用 keyword 优化surface shader:启用 approxview 编译指示符,在光照计算时,在vs中而不是在fs中做视线向量的规格化 优化surface shader:启用 halfasview 编译指示符,在光照计算时,使用半角向量做光照计算,且半角向量的计算在vs中执行 优化surface shader:启用 noforwardadd 编译指示符,确保在 Forward rendering 模式中, 只使用一个有向平行光光源 在fs中执行光照计算,其他的实时光源都只在vs中进行计算,此指示符确保只在一个pass中执行渲染操作 优化surface shader:编译指令 noambient 禁用着色器上的环境照明和球谐光。这样可以使性能稍快一些。 数据精度的优化:世界坐标系下的坐标值,纹理映射坐标值,用 float 数据精度的优化:除了HDR颜色之外的数据,使用 half 数据精度的优化:纹理数据的相关的一些简单操作用 fixed 各种GPU的区别: 桌面GPU ,内部都会统一用 float 计算 各种GPU的区别: 移动GPU 内部能真正支持half精度,大胆地使用它 各种GPU的区别: 老旧的GPU 才内部实现了 fixed , OpenGL ES3 及后续的都内部把 fixed 处理为 half 了 Alpha Testing :在iOS等等使用了PowerVR芯片的平台,表现不佳。 ColorMask :在某些平台上(大多数是在iOS和Android设备的移动GPU),使用 ColorMask 忽略某些通道(例如 ColorMask RGB )可能会占用大量资源,因此仅在确实需要时才使用它。 参考网页: https://docs.unity3d.com/Manual/SL-ShaderPerformance.html https://www.cnblogs.com/sifenkesi/p/4716791.html

《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.