关于《Thinking in Unity3D

笔者在研究和使用Unity3D的过程中,获得了一些Unity3D方面的信息,同时也感叹Unity3D设计之精妙。不得不说,笔者最近几年的引擎研发工作中,早已习惯性的从Unity3D中寻找解决方案。

Unity3D虽比不上UE那么老练沉稳,气势磅礴。也比不上CE那样炫丽多姿,盛气凌人。但它的发展势如破竹,早已遍地生花!故而在此记录一些自己的心得体会,供大家参详交流。若有欠妥之处,还望各位及时指正。
 
Thinking in Unity3D由一系列文章组成,文章列表地址:http://www.cnblogs.com/geniusalex/p/5321545.html
 

什么是材质?


材质是一个相对广泛的概念,不同的专业领域有不同的定义。 在此也不一一举例说明了,我们只说在3D游戏引擎中,材质的定义。

材质的本质定义,是指能够描述一个物体的显示外观的一系列数据。它包括几个方面

1、渲染状态

渲染状态是指早期的setRenderState那一套东西。比如,前后面裁剪,是否开启混合,混合因子等等。

2、着色方式

着色方式,在固定管线年代,是通过一系列的API进设置。 在可编程管线年代。就对应的是我们的着色器代码。

3、参数

不管是固定管线还是非固定管线,我们都可以设置一些参数用于着色计算。比如颜色,光源信息等等

4、纹理贴图

纹理贴图是表现一个物体表现的颜色细节的必不可少的东西。就是一张张图片。

有了上面的这些数据后,我们就可以根据一定的运算规则,将一个几何体的质感显示为我们想要的样子。

材质、Shader、模型关系图

材质系统的常见需求


一个工具或者系统的设计不可能是凭空而出的。 一定是根据需求和经验的积累,才形成了我们今天这种“材质系统”的概念。 说到这里,那么我们常见的材质系统需要做到什么样子呢。

一、模板 + 实例

材质是一个模板,通过对某一个材质进行实例化,指定不同的数据和贴图,就可以让物体表现出不同的显示效果。 和Class + Object的关系很像。

二、多Pass

有时候,我们为了实现一个绘制效果,靠单次绘制是无法实现的。比如描边效果。 这就要求我们单个物体能够在进行绘制的时候,多次提交材质并绘制。

三、多Technique

多Technique是指一个材质中,应该包含不只一个实现方案。 这样当我们进行材质更替,或者进行高中低端机适配的时候。 就不会那么麻烦。 同时在数据管理上,也显得更为规范。

四、高中低端机适配

高中低端机适配是一个很重要的特性,因为玩家的机型不可能是一样的。 在需要保证效率的情况下,我们很多时候需要降低物体渲染的复杂度。在《3D游戏中的画质与效率适配》一文中。笔者也描述过,有两种方案。 一种是通过宏定义,一种是动态切换Technique。

总结下来,就是说一个材质模板文件应该像这样的一个结构

MaterialTemplate
{
Technique
{
Pass{}
Pass{}
}
Technique
{
Pass{}
Pass{}
}
}

Unity3D中的材质系统


在说到Unity3D中的材质系统的时候,我们先来看一下我们创建一个材质需要做的事情。

一、创建一个Shader并编写出自己想要的效果

二、创建一个Material并将这个Material的Shader指定为自己的材质

三、为这个Material设置参数,赋上贴图等

四、将创建好的Material拖到对象上

我们再来看一个典型的Shader应该具备的内容

Shader "MyShader" {
Properties {
_MyTexture ("My Texture", 2D) = "white" { }
// other properties like colors or vectors go here as well
}
SubShader { LOD
// here goes the 'meat' of your
// - surface shader or
// - vertex and program shader or
// - fixed function shader Pass{} Pass{} }
SubShader { LOD
// here goes a simpler version of the SubShader
// above than can run on older graphics cards Pass{} Pass{}
}
}

我们可以看到。 每一个Shader有多个SubShader,每一个SubShader有多个Pass。 这样看起来和我们前面提到的MaterialTemplate结构几乎一致。

而在Unity3D中。Shader就是材质模版。 Material就是一个材质实例。 每一个Material你可以认为是一个材质实例的序列化存储。

Unity3D中的材质LOD


那对于前面提到的 高中低端机适配。 有两种方法解决。一是通过宏定义,这个并不是Unity3D的推荐方式,且需要Shader编写的相关知识,在这里不作详细讨论。 如果有兴趣的朋友,可以访问括号中的链接(http://docs.unity3d.com/Manual/SL-MultipleProgramVariants.html),以后的文章在涉及Unity3D的Shader编写方面的内容时,再进行讨论。 在此主要讨论Unity3D中通过材质LOD进行画质控制。

在Unity3D的Shader中,可以为每一个SubShader指定一个LOD值,这个LOD值可以通过设置Shader.globalMaximumLODShader.maximumLOD来实现SubShader的切换。所有的SubShader按顺序进行判定,当一个SubShader满足下面两个条件时,才表明可用。

1、SubShaderLOD值小于设定的值。(你可以把LOD看作是开销,开销越大的SubShader指定越高的LOD值)

2、SubShader所有Pass使用到的显卡特性被当前设备支持。

:Shader API文档地址:http://docs.unity3d.com/ScriptReference/Shader.html

:Shader LOD文档地址:http://docs.unity3d.com/Manual/SL-ShaderLOD.html

:Unity3D为每一档的内置Shader都设置了一个默认值,在LOD文档中有

:如果不指定LOD值,那LOD=infinite 。 你可以当它是一个小于0的值。

:这个值除了可以自己给以外,还可以在Edit->Project Settings->Quality面板中指定,如下图

设置面板

Unity3D中的材质替换


官方文档地址http://docs.unity3d.com/Manual/SL-ShaderReplacement.html

夜视效果

有时候,我们希望能够进行一些特殊操作。将场景物体的按另一种渲染方式渲染到RT中。 比如,仅渲染物体的深度,把物体渲染成纯白,把物体渲染成红绿热成像模式等等。但是,我们的材质在一开始就指定好了。如果要替换的话,就需要遍历所有对像,为它们重新指定材质。渲染完毕后,再切换回来。Unity3D为我们提供了更直接的方式。Camera.RenderWithShaderCamera.SetReplacementShader。前者是仅作用一次,后者是一直生效,如果想取消设置。 使用Camera.ResetReplacementShader即可


那么问题来了,我们有时候只想渲染一些特殊的物体。比如,我们想处理除主角以外的内容。 这就需要对主角进行剔除。 那上面两个函数的第二个参数replacementTag就起作用了。如果设置了它,在进行材质替换时,它会和SubShader中的 RenderType的值 进行比对。 比如,我们即将替换的材质如下。

Shader "EffectShader" {
SubShader {
Tags { "RenderType"="Opaque" }
Pass {
...
}
}
SubShader {
Tags { "RenderType"="SomethingElse" }
Pass {
...
}
}
... }

如果我们调用了camera.SetReplacementShader (EffectShader, "RenderType");那么,一个物体在被渲染时,会产生以下几种结果。

1、如果物体当前激活的SubShader的RenderType是Opaque,那么将会采用EffectShader的第一个SubShader。

2、如果物体当前激活的SubShader的RenderType是SomethingElse,那么将会采用EffectShader的第二个SubShader。

3、如果物体当前激活的SubShader的RenderType在EffectShader中没有与之对应的项,此物体将会在渲染中被忽略。

4、如果物体当前激活的SubShader没有RenderType这个Tag,此物体将会在渲染中被忽略。

结束语


Unity3D拥有着一个灵活的渲染管线和自由的材质系统。与其它图形引擎不一样的是,Unity3D针对游戏需求所留出来的接口非常好用。

而本文仅仅是对Unity3D的材质系统进行初步的描述。要想完全把Unity3D的材质系统总结出来,不是一两篇文章可以搞定的。Unity3D文档中的 Shader Reference可以作为一个十分不错的开始http://docs.unity3d.com/Manual/SL-Reference.html

Thinking in Unity3D:材质系统概览的更多相关文章

  1. Thinking in Unity3D:基于物理着色(PBS)的材质系统

    关于<Thinking in Unity3D> 笔者在研究和使用Unity3D的过程中,获得了一些Unity3D方面的信息,同时也感叹Unity3D设计之精妙.不得不说,笔者最近几年的引擎 ...

  2. Unity3D 装备系统学习Inventory Pro 2.1.2 基础篇

    前言 前一篇 Unity3D 装备系统学习Inventory Pro 2.1.2 总结 基本泛泛的对于Inventory Pro 这个插件进行了讲解,主要是想提炼下通用装备系统结构和类体系.前两天又读 ...

  3. atitit 点播系统 概览 v2 qb1.docx

    atitit 点播系统 概览 v2 qb1.docx 1.1. 多界面(可以挂载多个不同的界面主题)1 1.2. 独立的选片模块(跨设备,跨平台)2 1.3. 跨设备平台(android安卓盒子,pc ...

  4. lumion材质系统室内渲染6.3

    材质系统是对于导入的模型,而不对自带的模型起作用.自带的模型有的能改变属性. 点击“材质”点击墙,出来材质库.为墙体赋予一种材质, 完成后点击保存,就可以保存了.然后给窗户添加玻璃材质. 可以看到墙, ...

  5. 【转载】iPhone系统概览

    iPhone OS OverviewiPhone系统概览iPhone OS comprises the operating system and technologies that you use t ...

  6. 【转】Android系统概览

    这篇文章其实原文叫 <老罗的Android之旅>导读PPT 是罗升阳的博客,我觉得用“Android系统概览”作为标题更贴切些,对于在应用层已经开发了一段时间的人来说,读完之后会有很多体会 ...

  7. Unity3D 装备系统学习Inventory Pro 2.1.2 总结

    前言 写在最前面,本文未必适合纯新手,但有一些C#开发经验的还是可以看懂的,虽然本人也是一位Unity3D新人,但是本文只是自己在学习Inventory Pro的学习总结,而不是教程,本人觉得要读懂理 ...

  8. unity3d 材质概述 ---- shader

    学习笔记:      材质概述:  物体呈现在我们前面除了形体外,还包括“固有颜色”和“质地”(质感与光学性质).固有颜色让物体的表面看起来是什么颜色,而质感决定了该物质是使用什么材质的.在三维建模软 ...

  9. Java——IO系统概览

    前言 对程序语言的设计者来说,创建一个好的输入/输出(IO)系统是一项艰难的任务.这艰难主要来自于要涵盖I/O的所有可能性.不仅存在各种I/O源端和想要与之通信的接收端(源端/接收端:文件.控制台和网 ...

随机推荐

  1. 关于解决python线上问题的几种有效技术

    工作后好久没上博客园了,虽然不是很忙,但也没学生时代闲了.今天上博客园,发现好多的文章都是年终总结,想想是不是自己也应该总结下,不过现在还没想好,等想好了再写吧.今天写写自己在工作后用到的技术干货,争 ...

  2. ASP.NET Core的路由[2]:路由系统的核心对象——Router

    ASP.NET Core应用中的路由机制实现在RouterMiddleware中间件中,它的目的在于通过路由解析为请求找到一个匹配的处理器,同时将请求携带的数据以路由参数的形式解析出来供后续请求处理流 ...

  3. Carousel 旋转画廊特效的疑难杂症

    疑难杂症 该画廊特效的特点就是前后元素有层级关系. 我想很多人应该看过或者用过这个插件carousel.js,网上也有相关的教程.不知道这个插件的原型是哪个,有知道的朋友可以告诉我. 该插件相对完美, ...

  4. jQuery学习之路(7)- 用原生JavaScript实现jQuery的某些简单功能

    ▓▓▓▓▓▓ 大致介绍 学习了妙味,用原生的JavaScript实现jQuery中的某些部分功能 定义自己的函数库lQuery ▓▓▓▓▓▓ $()选择器的实现 jQuery是面向对象的,所以自己编写 ...

  5. UWP开发之Template10实践:本地文件与照相机文件操作的MVVM实例(图文付原代码)

    前面[UWP开发之Mvvmlight实践五:SuspensionManager中断挂起以及复原处理]章节已经提到过Template10,为了认识MvvmLight的区别特做了此实例. 原代码地址:ht ...

  6. inline-block元素间距问题的几种解决方案

    不知道大家有没有碰到过设置了display:inline-block;的几个相邻元素之间有几px间距的问题,这里提供几种简单实用的解决方法,希望能够帮到大家!   方法1. 将<li>标签 ...

  7. 验证管理员权限(C#)

    参考页面: http://www.yuanjiaocheng.net/webapi/test-webapi.html http://www.yuanjiaocheng.net/webapi/web-a ...

  8. TCP/IP基础

    TCP/IP 是用于因特网 (Internet) 的通信协议. 计算机通信协议是对那些计算机必须遵守以便彼此通信的规则的描述. 什么是 TCP/IP? TCP/IP 是供已连接因特网的计算机进行通信的 ...

  9. 移动BPM解决方案分享

    畅通开放  无边界的渠道 效率倍增  更高效的处理方式 即时共享  更强大的决策能力 各种终端应用 帮您实现:新任务通知.任务预警.催办.任务审批.任何数据汇总提醒消息通知...... 短信 客户端: ...

  10. RMS Server打开或关闭日志记录

    原文: https://technet.microsoft.com/zh-cn/library/cc732758 在 Active Directory Rights Management Servic ...