unity3d游戏项目实战实战核心技术详解怎么样

【图文】unity游戏开发实战教程 第15讲:总体回顾_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
unity游戏开发实战教程 第15讲:总体回顾
||文档简介
总评分0.0|
&&北​风​网​u​n​i​t​y​游​戏​开​发​实​战​视​频​教​程​《​U​n​i​t​yD​ D​实​战​游​戏​开​发​-​ ​特​种​任​务​》​(​S​p​r​i​t​e​R​e​n​d​e​r​,D​刚​体​碰​撞​,.后​的​动​画​系​统​)​,5​课​时​,​中​级​,​用​到​技​术​:​U​n​i​t​yD​ D​,​u​n​i​t​y​游​戏​开​发​实​战​视​频​教​程​涉​及​项​目​:​特​种​任​务​游​戏​开​发​。​通​过​u​n​i​t​y​游​戏​开​发​实​战​视​频​教​程​这​门​课​程​,​我​们​来​制​作​一​款​经​典​的​横​版​游​戏​―​特​种​任​务​。​通​过​这​个​U​n​i​t​yD​游​戏​开​发​实​战​,​我​们​来​熟​悉D​的​重​要​元​素​S​p​r​i​t​e​R​e​n​d​e​r​,D​刚​体​和​碰​撞​,​以​及.之​后​的​新​的​动​画​系​统​等​。
大小:1.66MB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢扫一扫下载手机客户端
扫描我,关注团购信息,享更多优惠
||网络安全
| | | | | | | | | | | | | | | |
||电子电工
汽车交通| | | | | | | | | |
||投资理财
| | | | | | | | | | | | | | | | |
| | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
||外语考试
| | | | | | | | |
| 视频教程|
Unity 3D实战核心技术详解
多年一线开发经验和实际运用技术分享,从数学及Shader出发,分享实战项目,剖析架构
定价:¥79.00
校园优惠价:¥59.25 (75折)
促销活动:
商品已成功飞到您的手机啦!快登录手机站看看吧!
下载客户端
> 微信关注“互动出版网”,便捷查询订单,更多惊喜天天有
ISBN:3上架时间:出版日期:2017 年1月开本:16开版次:1-1
所属分类:
  ★这是一本从实战项目总结出来的好书★从数学及Shader出发为大家揭露开发的机密★在架构的角度上介绍了游戏的UI模块、IO模块、Sound模块、Net模块等★在游戏制作的角度上讲了UI的制作、角色的加载及使用、场景的制作(地形、树木、水、阴影等)、粒子和物理系统的使用★让读者接触到一个真正的商业项目中遇到的一些难题和解决方案★本书作者从业15年,本书是其多年一线开发经验和实际运用技术分享
《Unity 3D 实战核心技术详解》详细介绍了实际游戏开发中使用的核心技术,每一章都结合了游戏开发的实战案例。首先,介绍了3D 数学在Unity 中的运用,3D 数学知识包括:Unity 坐标系统、向量、矩阵、四元数、欧拉角等基础知识。其次,介绍了游戏开发中常用的核心技术:Avatar 换装系统、消息事件系统、Protobuf 在游戏中的运用,以及游戏中的文本文件加密算法等。再次,介绍了游戏中的AI 行为树算法、残影算法、移动端实时阴影绘制、移动端海水的绘制等技术。然后,在游戏架构设计方面,介绍了最经典的针对UI 的MVC 架构设计和对于角色动作和技能的FSM 有限状态机架构,以及游戏版本迭代使用的热更新技术方案。最后,介绍了移动端GPU 编程和游戏开发的一些经验。
《Unity 3D 实战核心技术详解》适合具备一定Unity 开发经验的初学者和有一定Unity 项目开发经验的游戏开发者阅读。
创业公司技术合伙人,从事IT行业15年,主导或参与了18款大型游戏的研发;
曾在网龙、久游、趣游等知名IT公司担任核心技术团队负责人;
在泰课和CSDN学院等在线教育网担任高级讲师,CSDN社区专家;
研究方向为客户端架构、3D引擎架构、图形学算法、GPU编程等,目前负责公司3D引擎的研发工作;
工作之余,喜欢用书籍记录自己多年的技术积淀。
第1 章 3D 数学与Unity
1.1 Unity 坐标系
1.2.1 向量的加法
1.2.2 向量的减法
1.2.3 向量点乘
1.2.4 向量叉乘
1.3.1 平移矩阵
1.3.2 矩阵缩放
1.3.3 矩阵旋转
1.4 四元数
1.5 欧拉角
第2 章 Avatar 换装系统
2.1 换装原理
  在IT 行业中游戏程序员的薪资相对于其他领域来说还是比较高的,这也导致了许许多多的软件开发者转入游戏行业,从事Unity 3D 游戏开发。Unity 引擎因为具有上手快并且能跨平台开发的优点,被众多开发者所喜爱。虽然游戏研发公司对开发人员的需求越来越大,但是初次踏入游戏行业的开发者由于游戏产品项目经验不足,并不被游戏公司所认可。我在泰课在线教育做讲座时发现,有的学员水平还是不错的,但由于他们在游戏行业的工作经验不足,最终很难被游戏公司录用。如今,政府和公司支持的各种创客空间的兴起,为开发者提供了非常好的硬件条件,极大地促进了IT 行业的繁荣发展,特别是游戏和软件开发的发展。
  但是游戏行业也是一种技术浓缩型行业,作为一名从业者,要想在这个行业生存和发展,没有过硬的技术是不行的。可是,多年的从业经历让我见到许许多多的年轻人,他们在公司里只能写一些简单的逻辑,长期被边缘化,随时都有被辞退的危险。究其原因,还是他们缺乏解决实际问题的经验,在公司的产品开发中无法提供价值。在和他们接触的过程中,我发现了一个很严重的问题:这些能力欠佳的年轻人也有强烈的欲望去学习专业知识,但是市场上的Unity书籍讲述的都是一些入门的基础知识,已经远远不能满足手游开发工作的需要,他们急需能够与实际开发相结合并且能够帮助他们解决实际问题的书籍。作为他们的前辈,我也有过相似的经历,花费了很多时间去摸索,我一直在思考如何才能让后来者少走弯路。经过多年的经验积累,我终于奉上了这本呕心沥血之作。本书讲述的所有知识点都是与实际开发密切相关的,很多代码可以直接拿过来运用到项目中,实用性超强!
  本书致力于用最通俗的语言讲述初学者最需要的知识。在写作形式上,本书采用图文并茂的方式,让读者更容易掌握知识,为开发能力的提升提供了巨大的帮助。在技术知识的安排上,本书并没有把核心技术一一讲解,而是选择了一些游戏开发中经常使用的技术。
  本书的编写不同于只写对Unity 编辑器的一些基本操作的书籍。本书重点讲解游戏开发中实际运用的技术,分享游戏开发经验,阅读完本书,游戏开发者在技术方面和开发经验方面都会有一个质的提升。本书并不是介绍一个游戏是如何制作的,而是介绍游戏开发中的各个核心技术点。因为对于现在的游戏公司来说,核心技术只掌握在少数几个人手里,其他人很难接触到,他们或者是在已有框架的基础上开发,或者是使用已经封装好的技术模块开发。这样对于开发者技术的提升是非常不利的,也不利于增长实际项目开发经验。本书的宗旨就是把游戏中使用的核心技术无偿奉献给开发者,让开发者在最短的时间内提高自己的技能。
  姜雪伟
  2016 年10 月
  推 荐 序
  Unity 跨平台引擎这几年在国内的发展势头非常迅猛,截至目前已经横跨27 个主流游戏平台,尤其是在手游开发领域发展势头尤为凸显。大量的中小型公司几乎都使用Unity 开发游戏。所以在App Store 和Android Market 上有大量用Unity 开发的优质游戏或应用。开发者青睐Unity主要有两个方面原因,一方面是Unity 很方便就能跨平台,另一方面是Unity 上手快,但是在我看来它受欢迎最主要的原因是上手快。
  跨平台。Unity 能一键发布在27 个平台上,但是每个平台的特性是不同的,甚至可以说完全不一样。比如代码层面,接入移动SDK,不是所有厂商都能提供Unity 的SDK 接口。一些平台特定的API,Unity 可能没有提供,或者说还没来得及提供,在这些复杂情况下我们只能通过原生方法去调用它。此外,硬件层面内存CPU 性能的不同,操作层面触屏、手柄、PC 实体按键也都不同,游戏玩法从设计上不可能都一样,所以真正的跨平台并不是随随便便打个包就能完事的。
  上手快。Unity 底层全部使用 C/C++与 OpenGL ES 3D 渲染引擎交互,C#端封装了UnityEditor.DLL 和UnityEngine.DLL,通过与Unity 内部C/C++代码交互从而与底层代码相互调用。从开发层面看,开发者不用考虑怎么实现复杂的图形学、3D 数学算法,甚至完全不懂OpenGLES 的同学也能用 Unity 开发游戏。因为一切复杂的东西 Unity 在底层都封装好了,开发者只需要编写C#代码访问Unity 提供的UnityEditor.DLL 及其提供的API 接口即可从容地开发3D 游戏。听起来是不是很酷炫呢?可是Unity 依然存在很多隐患。
  目前看来Unity 确实很强大,能做的东西确实很多。但是它却有点“臃肿”了。做过Unity手游开发的人应该都知道,Unity 的效率并不高。在UI 层面,无论是NGUI,还是UGUI,界面元素稍微多一点打开界面的时候就会出现卡顿。在3D 层面,同屏人数多一点或者Shader 复杂一些,帧率马上就掉下去了。Unity 引擎“大而全”,它为了各个平台的兼容性,性能问题必然会显现出来,因为没办法对某个游戏平台做针对性的优化,加上Unity 没有开放源码,开发者更多时候只能靠“猜”,所以有些更大的公司会使用自研引擎。
  关于热更新,我觉得它更多是用来修正游戏Bug 的。如果没有热更新,修改一个Bug 后需要重新提交App Store 评审,这样来来回回可能要耽误好几天时间,不是很合理。由于苹果禁止了JIT,Unity 官方没有提供热更新的方案,因此我们都采用Lua 进行热更新的开发。虽然Lua的解释器可以用C++代码解释,但是在处理Lua 与C#之间穿透的时候依然会很慢,程序设计不合理就会产生性能问题。
  所以Unity 最大的痛点就是性能问题,它上手确实很快,但是想学好却是一件很难的事情。脚本开发非常地灵活,但是太灵活就可能会被滥用。现在的互联网上已经充满了各式各样的Unity 教程,但是大多数都比较零散,我们太需要一本从实战项目总结出来的好书。姜雪伟的这本新书,从数学以及Shader 层面出发,通过实战项目经验的分享以及框架层面的剖析为大家揭露开发的机密,不可不读。
  宣雨松MOMO
  资深Unity 3D 开发者
  Unity 3D 游戏引擎在如火如荼的AR、VR 技术方向下正在大放异彩。Google 的Daydream引导的新一波移动VR 浪潮,将会使广大Unity 3D 手游程序员继续在VR 移动大势中弄潮。如果你对手游感兴趣,如果你不想错过AR、VR 乃至MR 技术浪潮,那么姜雪伟的这本《Unity 3D实战核心技术详解》,你是不应该错过的。本书不同于以往从hello world 开始介绍的Unity 图书,而是从3D 数学和Unity 3D 坐标系说起,继而就Unity 3D 的换装技术进行讲解,然后就MVC 架构设计、Protobuf、移动端Shader、移动端海水等Unity 3D 常备技能一一道来。无论是Unity 3D 的新手,还是Unity 3D 技术熟手,都能从姜雪伟有底蕴的文字中获得力量。
  --王文刚
  微软.NET MVP,原创技术博客 的博主
  爱工作,爱编程,爱分享,是我对姜雪伟的第一印象。姜雪伟在业余时间写了这本书,很不容易,也很实用,这本书里蕴藏着他的心血和他对游戏开发的热爱。这本书由浅入深,从基础3D 数学到高级的GPU 编程。如果你对游戏开发比较感兴趣,或者正在通往游戏开发的路上,想系统地了解游戏开发和制作均可以阅读本书。从架构的角度看,本书介绍了游戏的UI 模块、IO 模块、Sound 模块、Net 模块等。从游戏制作的角度看,本书介绍了UI 的制作、角色的加载及使用、场景的制作(地形、树木、水、阴影等)、粒子和物理系统的使用。恭喜买到本书的你可以系统而详细地了解游戏的开发和制作,祝愿姜雪伟的这本书可以大卖!
  --张泽瑞(小阿哥)
  掌趣科技主程,一个从业8 年不忘初心的游戏开发者
  Unity 3D 是一个富有生命力的游戏引擎,从最初的支持移动平台、多平台,到现在的支持AR/VR,它一直紧跟着发展的趋势。市场上众多用Unity 3D 开发的作品也证实了Unity 3D 用于游戏开发是可靠的。那么怎样利用Unity 3D 更好地进行开发,怎样充分挖掘Unity 3D 的特性,怎样在Unity 3D 中做出和其他大作一样的游戏产品,这些才是我们开发者应该关注的。
  姜雪伟这本《Unity 3D 实战核心技术详解》正是为了尝试解决上述问题而生的。这本书从Unity 3D 乃至3D 游戏的一些基本原理着手,让读者在编程时更清楚为什么这么做。同时辅以大量的实例,这些实例能让读者接触到一个真正的商业项目中遇到的一些难题和解决方案。这些经验对于开发者而言才是最宝贵的。
  --蔡俊鸿
  《Unity 5 实战:使用C#和Unity 开发多平台游戏》译者,
  广州西姆雷娱乐有限公司Technical Lead, 博主
  当前VR、AR 技术得到了普遍关注,成为了当下最热门的技术之一,这使得Unity 的使用领域不再局限于游戏开发,在虚拟现实、3D 空间展示(如房地产楼盘展示)等领域都有良好的表现,已经面世的Unity 游戏充分显示了Unity 的延展性。大到数百人进行研发的MMORPG,小到一两个人开发的独立游戏,都可以使用Unity 进行开发。
  姜雪伟老师的这本《Unity 3D 实战核心技术详解》与目前市面上的同类书籍有很大不同,它不是一些入门的基础知识,而是姜雪伟多年一线开发经验的技术分享,这本书从数学知识出发,剖析架构层面,以实例详细介绍游戏开发实际过程中常见的一些难点和重点,无论是Unity3D 的初学者还是已经入行的开发者,这本书对你们的能力提升都有很大的帮助,实用性很强。
  --张文(优弧)
  泰课在线产品经理,极客,独立开发者
  推 荐 序
  Unity 跨平台引擎这几年在国内的发展势头非常迅猛,截至目前已经横跨27 个主流游戏平台,尤其是在手游开发领域发展势头尤为凸显。大量的中小型公司几乎都使用Unity 开发游戏。所以在App Store 和Android Market 上有大量用Unity 开发的优质游戏或应用。开发者青睐Unity主要有两个方面原因,一方面是Unity 很方便就能跨平台,另一方面是Unity 上手快,但是在我看来它受欢迎最主要的原因是上手快。
  跨平台。Unity 能一键发布在27 个平台上,但是每个平台的特性是不同的,甚至可以说完全不一样。比如代码层面,接入移动SDK,不是所有厂商都能提供Unity 的SDK 接口。一些平台特定的API,Unity 可能没有提供,或者说还没来得及提供,在这些复杂情况下我们只能通过原生方法去调用它。此外,硬件层面内存CPU 性能的不同,操作层面触屏、手柄、PC 实体按键也都不同,游戏玩法从设计上不可能都一样,所以真正的跨平台并不是随随便便打个包就能完事的。
  上手快。Unity 底层全部使用 C/C++与 OpenGL ES 3D 渲染引擎交互,C#端封装了UnityEditor.DLL 和UnityEngine.DLL,通过与Unity 内部C/C++代码交互从而与底层代码相互调用。从开发层面看,开发者不用考虑怎么实现复杂的图形学、3D 数学算法,甚至完全不懂OpenGLES 的同学也能用 Unity 开发游戏。因为一切复杂的东西 Unity 在底层都封装好了,开发者只需要编写C#代码访问Unity 提供的UnityEditor.DLL 及其提供的API 接口即可从容地开发3D 游戏。听起来是不是很酷炫呢?可是Unity 依然存在很多隐患。
  目前看来Unity 确实很强大,能做的东西确实很多。但是它却有点"臃肿"了。做过Unity手游开发的人应该都知道,Unity 的效率并不高。在UI 层面,无论是NGUI,还是UGUI,界面元素稍微多一点打开界面的时候就会出现卡顿。在3D 层面,同屏人数多一点或者Shader 复杂一些,帧率马上就掉下去了。Unity 引擎"大而全",它为了各个平台的兼容性,性能问题必然会显现出来,因为没办法对某个游戏平台做针对性的优化,加上Unity 没有开放源码,开发者更多时候只能靠"猜",所以有些更大的公司会使用自研引擎。
  关于热更新,我觉得它更多是用来修正游戏Bug 的。如果没有热更新,修改一个Bug 后需要重新提交App Store 评审,这样来来回回可能要耽误好几天时间,不是很合理。由于苹果禁止了JIT,Unity 官方没有提供热更新的方案,因此我们都采用Lua 进行热更新的开发。虽然Lua的解释器可以用C++代码解释,但是在处理Lua 与C#之间穿透的时候依然会很慢,程序设计不合理就会产生性能问题。
  所以Unity 最大的痛点就是性能问题,它上手确实很快,但是想学好却是一件很难的事情。脚本开发非常地灵活,但是太灵活就可能会被滥用。现在的互联网上已经充满了各式各样的Unity 教程,但是大多数都比较零散,我们太需要一本从实战项目总结出来的好书。姜雪伟的这本新书,从数学以及Shader 层面出发,通过实战项目经验的分享以及框架层面的剖析为大家揭露开发的机密,不可不读。
  宣雨松MOMO
  资深Unity 3D 开发者
770)this.width=770;' />
同类热销商品¥35.00¥24.50
订单处理配送
北京奥维博世图书发行有限公司 china-pub,All Rights ReservedUnity3D引擎之高级渲染技术 - 推酷
Unity3D引擎之高级渲染技术
笔者介绍:
,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人,已出版书籍:《手把手教你
3D游戏引擎》电子工业出版社 和《
实战核心技术详解》电子工业出版社等书籍
在游戏开发中尤其对于角色的材质渲染一直是被游戏开发者所看重,也成为衡量游戏品质的一个指标,关于渲染就需要考虑到Shader编程,Shader主要是对模型的顶点和模型的材质图片做处理,下面告诉读者如何去编写Shader。
在公司,策划需求提出用Unity3D引擎实现角色材质高光、法线效果。策划需求提出后,美术首先用PS和MAX工具将模型制作出来,MAX中有自身带的Shader,它可以完整的实现高光、法线效果,这也是程序编写和调试Shader时的参照依据,程序是参照MAX中的效果去调试,程序实现的效果只能无限接近MAX工具制作的效果。Unity5.4以上版本也有自己的高光法线Shader,但是在使用时效果并不理想,不如自己去实现一下。在这里首先需要提供三张贴图:Diffuse(原图),Specular(高光),Normal(法线)。
接下来就需要对其进行Shader编程实现,为了让美术调试方便,在这里我们使用了控制面板。首先实现一个继承于Materal类的编辑器脚本,将其放到Editor文件夹下面,内容如下所示:
using System.Collections.G
using UnityE
using UnityE
using System.L
using System.Text.RegularE
public abstract class CustomMaterialEditor : MaterialEditor
public class FeatureEditor
// The name the toggle will have in the inspector.
public string InspectorN
// We will look for properties that contain this word, and hide them if we're not enabled.
public string InspectorPropertyHideT
// The keyword that the shader uses when this feature is enabled or disabled.
public string ShaderKeywordE
public string ShaderKeywordD
// The current state of this feature.
public bool E
public FeatureEditor(string InspectorName, string InspectorPropertyHideTag, string ShaderKeywordEnabled, string ShaderKeywordDisabled)
this.InspectorName = InspectorN
this.InspectorPropertyHideTag = InspectorPropertyHideT
this.ShaderKeywordEnabled = ShaderKeywordE
this.ShaderKeywordDisabled = ShaderKeywordD
this.Enabled =
// A list of all the toggles that we have in this material editor.
protected List&FeatureEditor& Toggles = new List&FeatureEditor&();
// This function will be implemented in derived classes, and used to populate the list of toggles.
protected abstract void CreateToggleList();
public override void OnInspectorGUI ()
// if we are not visible... return
if (!isVisible)
// Get the current keywords from the material
Material targetMat = target as M
string[] oldKeyWords = targetMat.shaderK
// Populate our list of toggles
//Toggles.Clear();
Toggles = new List&FeatureEditor&();
CreateToggleList();
// Update each toggle to enabled if it's enabled keyword is present. If it's enabled keyword is missing, we assume it's disabled.
for(int i = 0; i & Toggles.C i++)
Toggles[i].Enabled = oldKeyWords.Contains (Toggles[i].ShaderKeywordEnabled);
// Begin listening for changes in GUI, so we don't waste time re-applying settings that haven't changed.
EditorGUI.BeginChangeCheck();
serializedObject.Update ();
var theShader = serializedObject.FindProperty (&m_Shader&);
if (isVisible && !theShader.hasMultipleDifferentValues && theShader.objectReferenceValue != null)
float controlSize = 64;
EditorGUIUtility.labelWidth = Screen.width - controlSize - 20;
EditorGUIUtility.fieldWidth = controlS
Shader shader = theShader.objectReferenceValue as S
EditorGUI.BeginChangeCheck();
// Draw Non-toggleable values
for (int i = 0; i & ShaderUtil.GetPropertyCount(shader); i++)
ShaderPropertyImpl(shader, i, null);
// Draw toggles, then their values.
for (int s = 0; s & Toggles.C s++)
EditorGUILayout.Separator();
Toggles[s].Enabled = EditorGUILayout.BeginToggleGroup(Toggles[s].InspectorName, Toggles[s].Enabled);
if (Toggles[s].Enabled)
for (int i = 0; i & ShaderUtil.GetPropertyCount(shader); i++)
ShaderPropertyImpl(shader, i, Toggles[s]);
EditorGUILayout.EndToggleGroup();
if (EditorGUI.EndChangeCheck())
PropertiesChanged ();
// If changes have been made, then apply them.
if (EditorGUI.EndChangeCheck())
// New list of key words.
List&string& newKeyWords = new List&string&();
// If true, add the enabled keyword (ending with _ON), if false, add the disabled keyword(ending with _OFF).
for(int i = 0; i & Toggles.C i++)
newKeyWords.Add(Toggles[i].Enabled ? Toggles[i].ShaderKeywordEnabled : Toggles[i].ShaderKeywordDisabled);
// Send the new list of keywords to the material, this will define what version of the shader to use.
targetMat.shaderKeywords = newKeyWords.ToArray ();
EditorUtility.SetDirty (targetMat);
// This runs once for every property in our shader.
private void ShaderPropertyImpl(Shader shader, int propertyIndex, FeatureEditor currentToggle)
string propertyDescription = ShaderUtil.GetPropertyDescription(shader, propertyIndex);
// If current toggle is null, we only want to show properties that aren't already &owned& by a toggle,
// so if it is owned by another toggle, then return.
if (currentToggle == null)
for (int i = 0; i & Toggles.C i++)
if (Regex.IsMatch(propertyDescription, Toggles[i].InspectorPropertyHideTag , RegexOptions.IgnoreCase))
// Only draw if we the current property is owned by the current toggle.
else if (!Regex.IsMatch(propertyDescription, currentToggle.InspectorPropertyHideTag , RegexOptions.IgnoreCase))
// If we've gotten to this point, draw the shader property regulairly.
ShaderProperty(shader,propertyIndex);
上面是我们自己实现的可以作为父类使用,其实就是做了一个接口封装,下面代码是自己定义的为我们自己的Shader脚本操作写的几个开关。如下所示:
using System.Collections.G
using UnityE
using UnityE
public class EditorInspector : CustomMaterialEditor
protected override void CreateToggleList()
Toggles.Add(new FeatureEditor(&Normal Enabled&,&normal&,&NORMALMAP_ON&,&NORMALMAP_OFF&));
Toggles.Add(new FeatureEditor(&Specular Enabled&,&specular&,&SPECULAR_ON&,&SPECULAR_OFF&));
Toggles.Add(new FeatureEditor(&Fresnel Enabled&,&fresnel&,&FRESNEL_ON&,&FRESNEL_OFF&));
Toggles.Add(new FeatureEditor(&Rim Light Enabled&,&rim&,&RIMLIGHT_ON&,&RIMLIGHT_OFF&));
相对来说比较简单,它只是做了几个Toggle作为Shader脚本中的控制。将上述两个文件拖放到Editor文件夹下面。
下面才开始真正的Shader编写工作,在这里我们使用了SurfaceOutput作为我们的输出结构体,
SurfaceOutput简单地描述了surface的属性(&& properties of the surface &),如反射率颜色(albedo color)、法线(normal)、散射(emission)、镜面反射(specularity&)等。 首先定义一个输入结构体如下所示:
struct Input
float2 uv_DiffuseM
#if SPECULAR_ON
float2 uv_SpecM
#if NORMALMAP_ON
float2 uv_NormalM
#if FRESNEL_ON || RIMLIGHT_ON
float3 viewD
结构体中包含 Diffuse贴图的uv坐标 uv_DiffuseMap ,高光的uv坐标 uv_SpecMap ,法线的uv坐标 uv_NormalMap ,另外还定义了一个方向值viewDir。接下来就是实现主函数surf了,对于高光法线的渲染就在这里面了,它调用了大量的CG库函数,如下所示:
void surf (Input IN, inout SurfaceOutput o)
float3 TexData = tex2D(_DiffuseMap, IN.uv_DiffuseMap);
float3 _BlendColor =
_TintColor.rgb * _TintColorM
o.Albedo.rgb = _Brightness * lerp(TexData, _TintColor.rgb, _TintColorMultiply) ;
#if SPECULAR_ON
o.Specular = _G
o.Gloss = max(_SpecAdd + _SpecularMultiply, 1.0) * tex2D (_SpecMap, IN.uv_SpecMap);
//o.Emission = _Gloss * tex2D (_SpecMap, IN.uv_SpecMap);
#if NORMALMAP_ON
o.Normal = UnpackNormal(tex2D(_NormalMap, IN.uv_NormalMap));
#if FRESNEL_ON && SPECULAR_ON || RIMLIGHT_ON
float facing = saturate(1.0 - max(dot(normalize(IN.viewDir), normalize(o.Normal)), 0.0));
#if FRESNEL_ON && SPECULAR_ON
float fresnel = max(_FresnelBias + (1.0-_FresnelBias) * pow(facing, _FresnelPower), 0);
fresnel = fresnel * o.Specular * _FresnelM
o.Gloss *= 1+
#if RIMLIGHT_ON
float rim = max(_RimBias + (1.0-_RimBias) * pow(facing, _RimPower), 0);
rim = rim * o.Specular * _RimM
o.Albedo *= 1+
下面将Shader的完整代码展示如下:
Shader &Custom_Shaders/DNSRender&
Properties
_TintColor (&Color Tint&,color) = (1.0,1.0,1.0,1.0)
//Diffuse Sliders
_TintColorMultiply(&Color Tint Multiply&, Range(0.0, 1.0)) = 0.0
_Brightness (&Diffuse Brightness&, Range(0.0, 2.0)) = 1.0
_DiffuseMap (&Diffuse (RGB)&, 2D) = &white& {}
_NormalMap (&Normal Map(RGB)&, 2D) = &bump& {}
_SpecColor (&Specular Color&, Color) = (0.5, 0.5, 0.5, 1)
_SpecularMultiply (&Specular Brightness&,float) = 1.0
_SpecAdd (&Specular Boost&, float) = 0
_SpecMap (&Specular Map (RGB)&, 2D) = &grey& {}
_Gloss (&Specular Glossiness&, float) = 0.5
_FresnelPower (&Fresnel Power&,float) = 1.0
_FresnelMultiply (&Fresnel Multiply&, float) = 0.2
_FresnelBias (&Fresnel Bias&, float) = -0.1
_RimPower (&RimLight Power&,float) = 1.0
_RimMultiply (&RimLight Multiply&, float) = 0.2
_RimBias (&RimLight Bias&, float) = 0
_EmissionColor(&Emission Color&, color) = (1.0,1.0,1.0,1.0)
Tags { &RenderType&=&Opaque& }
#pragma surface surf BlinnPhong
#pragma target 3.0
#pragma shader_feature NORMALMAP_ON NORMALMAP_OFF
#pragma shader_feature SPECULAR_ON SPECULAR_OFF
#pragma shader_feature FRESNEL_ON FRESNEL_OFF
#pragma shader_feature RIMLIGHT_ON RIMLIGHT_OFF
float3 _TintC
float _TintColorM
sampler2D _DiffuseM
sampler2D _NormalM
sampler2D _SpecM
float _SpecularM
float _SpecA
float _FresnelP
float _FresnelM
float _FresnelB
float _RimP
float _RimM
float _RimB
float3 _EmissionC
struct Input
float2 uv_DiffuseM
#if SPECULAR_ON
float2 uv_SpecM
#if NORMALMAP_ON
float2 uv_NormalM
#if FRESNEL_ON || RIMLIGHT_ON
float3 viewD
void surf (Input IN, inout SurfaceOutput o)
float3 TexData = tex2D(_DiffuseMap, IN.uv_DiffuseMap);
float3 _BlendColor =
_TintColor.rgb * _TintColorM
o.Albedo.rgb = _Brightness * lerp(TexData, _TintColor.rgb, _TintColorMultiply) ;
#if SPECULAR_ON
o.Specular = _G
o.Gloss = max(_SpecAdd + _SpecularMultiply, 1.0) * tex2D (_SpecMap, IN.uv_SpecMap);
//o.Emission = _Gloss * tex2D (_SpecMap, IN.uv_SpecMap);
#if NORMALMAP_ON
o.Normal = UnpackNormal(tex2D(_NormalMap, IN.uv_NormalMap));
#if FRESNEL_ON && SPECULAR_ON || RIMLIGHT_ON
float facing = saturate(1.0 - max(dot(normalize(IN.viewDir), normalize(o.Normal)), 0.0));
#if FRESNEL_ON && SPECULAR_ON
float fresnel = max(_FresnelBias + (1.0-_FresnelBias) * pow(facing, _FresnelPower), 0);
fresnel = fresnel * o.Specular * _FresnelM
o.Gloss *= 1+
#if RIMLIGHT_ON
float rim = max(_RimBias + (1.0-_RimBias) * pow(facing, _RimPower), 0);
rim = rim * o.Specular * _RimM
o.Albedo *= 1+
CustomEditor &EditorInspector&
将Shader挂接到材质球上效果如下:
最终展示效果如下所示:
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致}

我要回帖

更多关于 unity3d游戏项目实战 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信