叮当你个喵 的blog

UnityShader 提供的CG/HLSL语义

一、语义的解释

语义,其实就是一个赋给Shader输入和输出的字符串,这个字符串表达了这个参数的含义。通俗的讲这些语义可以让Shader知道从哪读取输送到哪里去,他们是在CG/HLSL的shader流水线中是不可避免。表示图元数据的含义(顶点的位置、法向量或者纹理信息),也表明这些图元数据存放的硬件资源。因为顶点着色器的输出即是片段着色器的输入,所以顶点着色器的输出必须和片段着色器的输入语义是一致的。

语义是顶点程序和片段程序之间输入\输出数据和寄存器之间的桥梁,因此语义只对这两个处理阶段有意义,并且只在入口函数才有效,在内部函数无效。语义概念的提出和图形流水线工作机制大有关系。从GPU 处理流程中可以看出,一个阶段处理数据,然后传输给下一个阶段,那么每个阶段之间的接口是如何确定的呢?

unity3D中Shader的分类和区别

Shader按管线分类一般分为固定渲染管线与可编程渲染管线

(1)固定渲染管线 ——这是标准的几何&光照(Transforming&Lighting)管线,功能是固定的,它控制着世界、视、投影变换及固定光照控 制和纹理混合。T&L管线可以被渲染状态控制,矩阵,光照和采制参数。功能比较有限。基本所有的显卡都能正常运行。

(2)可编程渲染管线——对渲染管线中的顶点运算和像素运算分别进行编程处理,而无须象固定渲染管线那样套用一些固定函数,取代设置参数来控制管线。

unity3d的三种Shader

(1)Fixed function shader 属于固定渲染管线 Shader, 基本用于高级Shader在老显卡无法显示时的Fallback(之后有详细介绍)。使用的是ShaderLab语言,语法与微软的FX files 或者NVIDIA的 CgFX类似。

(2)Vertex and Fragment Shader 最强大的Shader类型,属于可编程渲染管线. 使用的是CG/HLSL语法。

Unity架构常用的几种方式

对于初学者来说,视频《Unity项目架构设计与开发管理》(http://v.qq.com/boke/page/d/0/u/d016340mkcu.html),全是干货。简单的总结了一下,Unity的架构有如下几种常用的方式。

1、EmptyGO:

在Hierarchy上创建一个空的GameObject,然后挂上所有与GameObject无关的逻辑控制的脚本。使用GameObject.Find()访问对象数据。

缺点:逻辑代码散落在各处,不适合大型项目。

2、Simple GameManager:

所有与GameObject无关的逻辑都放在一个单例中。
缺点:单一文件过于庞大。

3、Manager Of Managers:

将不同的功能单独管理。如下:

• MainManager: 作为入口管理器。
• EventManager: 消息管理。
• GUIManager: 图形视图管理。
• AudioManager: 音效管理。
• PoolManager: GameObject管理(减少动态开辟内存消耗,减少GC)。

实现一个简单的PoolManager

unity静态批处理原理理解

1、静态批处理的时间点

1)在游戏导出的时候,在player setting中勾选static batching,这样在导出包的时候就进行批处理,导出来的包就会比较大

2 ) 在游戏场景中勾选场景物体的static选项,在加载该场景的时候,会进行一次静态批处理的合并,这样导出来的包不大,但是在加载的时候会使得内存变大。

2、静态批处理的基本原理

场景中有4个物体,ABCD,如果都勾选静态选项,在进行静态批处理的时候,引擎会判断这四个物体是否共用同一渲染材质。

如果共用同一渲染材质,则会将这四个物体视为可以批处理的对象,引擎会基于单个渲染对象的大小拷贝出3个,总共变为4个mesh,此时这4个mesh会存在一个index buffer中,此时会让资源占用的内存变大4倍。

3、为什么要用静态批处理?

在游戏的运行中,有时候CPU的瓶颈也会至关重要。如果CPU的运行速度较慢,则GPU会出现等待CPU的情况,此时游戏主要受到CPU的限制。

Unity应用架构设计(13)——日志组件的实施

对于应用程序而言,日志是非常重要的功能,通过日志,我们可以跟踪应用程序的数据状态,记录Crash的日志可以帮助我们分析应用程序崩溃的原因,我们甚至可以通过日志来进行性能的监控。总之,日志的好处很多,特别是对Release之后的线上版本进行异常的跟踪。

日志存储的分类

在平常开发时,我们通常喜欢在Debug模式下进行调试,通过断点,可以跟踪数据的变化。除了调试,另一种直观的方式是使用控制台输出,比如Java的system.out.println(),.NET的Console.WriteLine(),Swift的print()等等。在Untiy中,为我们提供了Debug.Log()方式来记录。

而对于线上的版本,上述两种调试都不行,那我们怎么来跟踪数据呢?

从日志的存储分类上来看,可以分为四类:控制台,文件系统,数据库,第三方平台

• 控制台:本地开发时使用,记录数据和跟踪执行过程,方便直观

• 文件系统:可以是一些用户行为性的日志,这些文件可以被用来监控执行时间,进行性能的分析,如果用户同意,则将这些日志传到服务器上

• 数据库:记录了一些异常日志,也就是Catch了之后的行为,每次用户登录时,传到服务器,帮助分析原因

Unity应用架构设计(12)——AOP思想的实践

想象一下,当程序所有的业务逻辑都完成的时候,你可能还来不及喘口气,紧张的测试即将来临。你的Boss告诉你,虽然程序没问题,但某些方法为什么执行这么慢,性能堪忧。领会了Boss的意图之后,漫长的排查问题开始了。你会写日志,或者是其他工具来追踪原因。那么如何以一种优雅的形式,并且不侵入业务代码的形式来跟踪呢?这正是本文的内容。
上一篇:Unity应用架构设计(11)——一个网络层的构建

跟踪问题

通过观察,你发现方法Do执行缓慢,可能有性能问题,因为这是一个线上的版本,你无法进行Debug,所以你通过日志的形式来追踪执行步骤:

class Foo1
{
    void Do()
    {
        //日志记录开始
        //性能监控开始
        DoSomething();
        //日志记录结束
        //性能监控结束
    }
}

看起来不错,解决问题之后,测试又发现另一个方法Handle貌似也有问题,然后你一样画葫芦,虽然麻烦了一点,但总归是有解决方案:

Unity应用架构设计(11)——一个网络层的构建

对于客户端应用程序,免不了和远程服务打交道。设计一个良好的『服务层』能帮我们规范和分离业务代码,提高生产效率。服务层最核心的模块一定是怎样发送请求,虽然Mono提供了很多C#网络请求类,诸如WebClient,HttpWebRequest,但考虑到跨平台,这些类不一定适用。不过不用担心,Unity 5.x提供了新的与网络相关类UnityWebRequest用来替代原先的WWW,这是官方推荐的,也是最佳选择。

上一篇:Unity应用架构设计(10)——绕不开的协程和多线程

使用Token进行身份验证

首先我们必须要考虑的是,怎样和Web服务安全的通信。没错,肯定是身份验证(Authentication)。对于像WebClient这些类,它们会提供一个属性,比如Credentials,可以在此属性设置一些身份验证信息,比如用户名,密码,域。这是一个很『重』的解决方案,且不论是否能在Unity中实现,单从密码这个角度,很多游戏根本不需要密码。所以,我们需要一种『轻』量级的身份验证机制,这就是Token,中文翻译叫『令牌』。

Token有两个重要的特点:

Unity应用架构设计(10)——绕不开的协程和多线程(Part 2)

上一篇《Unity应用架构设计(10)——绕不开的协程和多线程(Part 1)》谈到,客户端应用程序的所有操作都在主线程上进行,所以一些比较耗时的操作可以在异步线程上去进行,充分利用CPU的性能来达到程序的最佳性能。对于Unity而言,又提供了另外一种『异步』的概念,就是协程(Coroutine),通过反编译,它本质上还是在主线程上的优化手段,并不属于真正的多线程(Thread)。那么问题来了,怎样在Unity中使用多线程呢?

Thread 初步认识

虽然这不是什么难点,但我觉得还是有必要提一下多线程编程几个值得注意的事项:

• 线程启动
在Unity中创建一个异步线程是非常简单的,直接使用类System.Threading.Thread就可以创建一个线程,线程启动之后毕竟要帮我们去完成某件事情。在编程领域,这件事就可以描述了一个方法,所以需要在构造函数中传入一个方法的名称。

Worker workerObject = new Worker();
Thread workerThread = new Thread(workerObject.DoWork)

Unity应用架构设计(10)——绕不开的协程和多线程(Part 1)

在进入本章主题之前,我们必须要了解客户端应用程序都是单线程模型,即只有一个主线程(Main Thread),或者叫做UI线程,即所有的UI控件的创建和操作都是在主线程上完成的。而服务器端应用程序,也就是我们常见的Web应用程序往往是多线程的,故用户A访问势必不会影响用户B的访问过程。所以对于Web应用而言,多线程的数据同步和并发的管理往往是个头疼的问题。那么对于客户端应用程序而言,就一个人使用,还要需要考虑多线程吗?

上一篇:Unity应用架构设计(9)——构建统一的 Repository

是否需要多线程?

这是个好问题,从设备的硬件上,这已不是瓶颈:

学过操作系统的同学肯定知道CPU是真正的处理大脑,在单核的CPU年代,在某一时刻CPU只能处理一个线程,通过CPU的调度来实现在不同线程间切换工作。由于CPU调度的时间很快,所以给人造成并发的假象。
随着硬件的提升,多核CPU已经是常态化了。比如双核CPU而言,某一时刻可以有2个线程并行计算。

所以,是否需要在客户端使用多线程技术,还是取决于你的应用的复杂度:

Unity应用架构设计(9)——构建统一的 Repository

谈到 『Repository』 仓储模式,第一映像就是封装了对数据的访问和持久化。Repository 模式的理念核心是定义了一个规范,即接口『Interface』,在这个规范里面定义了访问以及持久化数据的行为。开发者只要对接口进行特定的实现就可以满足对不同存储介质的访问,比如存储在Database,File System,Cache等等。软件开发领域有非常多类似的想法,比如JDBC就是定义了一套规范,而具体的厂商MySql,Oracle根据此开发对应的驱动。

上一篇:Unity应用架构设计(8)——使用ServiceLocator实现对象的注入

Unity 中的Repository模式

同步内容
--电子创新网--
粤ICP备12070055号