本系列主要参考《Unity Shaders and Effects Cookbook》一书(感谢原书作者),同时会加上一点个人理解或拓展。

这里是本书所有的插图。这里是本书所需的代码和资源(当然你也可以从官网下载)。

========================================== 分割线 ==========================================

写在前面

有很多情况你可能想要使用法线去影响反射效果。比如,你想要模拟一个被霜雪覆盖的玻璃材质的表面,或者一个冰块。如果你根据物理知识真实的模拟这个平面的每一个细节部分,那么你就不要希望你游戏的FPS还可以达到60帧了。相反的,我们可以使用法线贴图来伪造一个视觉体验,因此我们需要学习如何将法线贴图的信息传递给反射效果。
为了完成这个任务,我们将要学习Input结构体的另一个内置参数,它可以将由法线贴图技术生成的修改后的平面法线信息传递进来。下面,让我们来具体看一下如何修改Input结构体来达到这个效果吧!

准备

  1. 首先,我们需要一个Cubemap来产生反射效果。所以你可以使用前一节中的Cubemap,或者生成一个新的。这一节中,我们使用的如下所示(你可以在本书资源中找到它):
  2. 我们还需要一张法线贴图来产生基于法线的反射效果。
  3. 最后,创建一个新的场景、一个球体、一个平面以及一个平行光。同时,还需要创建一个新的Shader和Material,命名为NormalMappedReflection。

实现

  1. 首先让我们添加新的properties,使得我们能够添加自己的Cubemap和法线贴图。这个步骤你应该非常熟悉了。向Properties块添加下列代码:

      Properties {_MainTint ("Diffuse Tint", Color) = (1,1,1,1)_MainTex ("Base (RGB)", 2D) = "white" {}_NormalMap ("Normal Map", 2D) = "bump" {}_Cubemap ("Cubemap", CUBE) = ""{}_ReflAmount ("Reflection Amount", Range(0,1)) = 0.5}
  2. 然后,我们需要在SubShader块声明这些properties,使得我们能够访问Properties块中的这些数据:
            CGPROGRAM#pragma surface surf LambertsamplerCUBE _Cubemap;sampler2D _MainTex;sampler2D _NormalMap;float4 _MainTint;float _ReflAmount;
  3. 然后,修改Input结构体。这是基于法线贴图的反射的精华所在。通过使用INTERNAL_DATA声明,我们可以访问经过法线贴图修改后的平面的法线信息:
            struct Input {float2 uv_MainTex;float2 uv_NormalMap;float3 worldRefl;INTERNAL_DATA};
  4. 最后,我们需要修改surf函数,来得到最后的基于法线贴图的反射效果:
          void surf (Input IN, inout SurfaceOutput o) {half4 c = tex2D (_MainTex, IN.uv_MainTex);float3 normals = UnpackNormal(tex2D(_NormalMap, IN.uv_NormalMap)).rgb;o.Normal = normals;o.Emission = texCUBE (_Cubemap, WorldReflectionVector (IN, o.Normal)).rgb * _ReflAmount;o.Albedo = c.rgb * _MainTint;o.Alpha = c.a;}
最后,整体代码如下:
Shader "Custom/NormalMappedReflection" {Properties {_MainTint ("Diffuse Tint", Color) = (1,1,1,1)_MainTex ("Base (RGB)", 2D) = "white" {}_NormalMap ("Normal Map", 2D) = "bump" {}_Cubemap ("Cubemap", CUBE) = ""{}_ReflAmount ("Reflection Amount", Range(0,1)) = 0.5}SubShader {Tags { "RenderType"="Opaque" }LOD 200CGPROGRAM#pragma surface surf LambertsamplerCUBE _Cubemap;sampler2D _MainTex;sampler2D _NormalMap;float4 _MainTint;float _ReflAmount;struct Input {float2 uv_MainTex;float2 uv_NormalMap;float3 worldRefl;INTERNAL_DATA};void surf (Input IN, inout SurfaceOutput o) {half4 c = tex2D (_MainTex, IN.uv_MainTex);float3 normals = UnpackNormal(tex2D(_NormalMap, IN.uv_NormalMap)).rgb;o.Normal = normals;o.Emission = texCUBE (_Cubemap, WorldReflectionVector (IN, o.Normal)).rgb * _ReflAmount;o.Albedo = c.rgb * _MainTint;o.Alpha = c.a;}ENDCG} FallBack "Diffuse"
}

效果如下(一个表明凹凸不平的反射球):

而下图是不加法线影响的效果(一个光滑的反射球):

解释

你可能已经注意到这一节的Shader和上一节中的非常类似,而有一个非常重要的不同点(上一节直接使用IN.worldRefl来查找Cubemap)。我们想要使用逐像素的法线贴图来修改我们的反射贴图。为了完成这个目的,我们需要得到在应用法线贴图后、物体的平面法线信息。这意味着,我们需要下列代码:
            float3 normals = UnpackNormal(tex2D(_NormalMap, IN.uv_NormalMap)).rgb;o.Normal = normals;

一旦上述代码在Shader中执行后,物体的平面法线将被修改;因此,我们需要使用它来影响我们的反射。我们可以通过声明INTERNAL_DATA来访问修改后的法线信息,然后使用WorldReflectionVector (IN, o.Normal)去查找Cubemap中对应的反射信息。这是Unity提供给我们的另一个内置函数,因此我们不需要再自己写那些冗长的代码,而仅仅需要关注编写Shader中产生关键效果的部分。

更多…

结构体中还有很多内置函数(变量),而在将来的章节中我们的确会接触到它们。下面的表格描述了每一个内置函数的作用以及如何使用它们。你也可以访问官网来得到更多的关于内置函数的信息:
float3 viewDir 包含了视角的观察方向,主要用于计算视差效应(Parallax effects ),边缘光照,等等。
float4 COLOR 包含了经过内插值(interpolated )的每个顶点的颜色值。
float4 screenPos 包含了用于反射效果的屏幕坐标系的位置信息。例如,在Unity专业版的WetStreet shader中使用了它。
float3 worldPos 包含了世界坐标系中的位置。
float3 worldRefl 包含了世界坐标系中的反射向量,如果Surface Shader没有重写o.Normal。参考Reflect-Diffuse shader。
float3 worldNormal 包含了世界坐标系中的法线向量,如果Surface Shader没有重写o.Normal。
float3 worldRefl;
INTERNAL_DATA
包含了世界坐标系的反射向量,如果Surface Shader重写了o.Normal。为了得到基于逐像素的法线贴图的反射向量,请使用WorldReflectionVector (IN,o.Normal) 。参考Reflect-Bumped shader。
float3 worldNormal;
INTERNAL_DATA
包含了世界坐标系的发现向量,如果Surface Shader重写了o.Normal。为了得到基于逐像素的法线贴图的法线向量,请使用WorldNormalVector (IN,o.Normal) 。参考Reflect-Bumped shader。

【Unity Shaders】Reflecting Your World —— Unity3D中的法线贴图和反射相关推荐

  1. Unity中的法线贴图、漫反射及高光

    我们都知道,一个三维场景的画面的好坏,百分之四十取决于模型,百分之六十取决于贴图,可见贴图在画面中所占的重要性.在这里我将列举一些贴图,并且初步阐述其概念,理解原理的基础上制作贴图,也就顺手多了. 我 ...

  2. 如何在Unity实现从纹理中生成法线贴图?

    本文主要讲解从纹理中生成法线贴图的基本方法,并在 Unity 中进行实现和测试. 预备知识 法线贴图和基本的图形学知识,基本的向量和极限的知识. 高度图或灰度图 一张二维纹理有两个维度 u 和 v,但 ...

  3. Unity网络(二)-Unity3D中的网络

    正所谓:没有网络是没有灵魂的 欢迎关注公众号:雷潮课堂 Unity3D中的网络 一.WWW 1-1 Get 1-2 Post 1-3 案例(网络下载,本地存储与读取) 二.UnityWebReques ...

  4. 【Unity Shaders】Reflecting Your World —— Unity3D中简单的Cubemap反射

    在Project中可以创建我们自己的Cubemaps,现在,我们可以来看一下如何使用这种新的贴图类型来在Shaders中模拟反射效果.使用Cubemaps进行反射的原理实际上非常简单,但是这将给你的S ...

  5. 解析Unity3D中计算法线矩阵的函数

    如果法线简单地跟着顶点变换有时会出现如下图情况, 若图2所示,垂直关系变了. 可以用线性代数知识证明 设原来的切线为 T T T,法线 N N N,则有 T T N = 0 T^TN=0 TTN=0 ...

  6. photoshop中制作法线贴图

  7. 【Unity Shaders】Reflecting Your World(反射吧!)介绍

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  8. 3Dmax已经贴好图的文件如何导入unity3D中

    3Dmax已经贴好图的文件如何导入unity3D中,对于初学者而言,有时候在3Dmax中贴好图,配好颜色的模型导入unity3D中会丢失贴图的问题. 解决方法: 1.在3Dmax中建好模型.贴图完成. ...

  9. shader graph_在Shader Graph中使用表面梯度框架进行法线贴图合成

    shader graph A recent Unity Labs paper introduces a new framework for blending normal maps that is e ...

最新文章

  1. python 根据地址求经纬度 谷歌_利用google的API获取世界城市经纬度(python实现)
  2. Windows Live Messenger  正式版已经发布
  3. 五、线程的概念和特点
  4. 新 TMD 的二号人物
  5. 吵架后一个老公的检讨书(超经典)
  6. python库整理:heapq 最小堆
  7. 基于php的应用程序,基于PHP的Web应用程序和群发邮件
  8. E - 嗯? 51Nod - 1432(二分)
  9. oracle decode函数
  10. 推到 旋转矩阵公式_想知道旋转矩阵的带入公式
  11. matlab分析电梯,一种基于Matlab/Simulink的电梯驱动系统建模方法
  12. 工资短信生成器如何使用
  13. Tools - Blender快捷键大全
  14. java图像增强 对数_OpenCV图像增强之对数变换log C++
  15. Python入门_打印矩形
  16. 计算机术语中的channel,English 中关于道路方面用词之(4)—Channel, Tunnel
  17. html5网页录音插件Recorder
  18. Spring Cloud 入门 ---- Security 整合 Oauth2 认证授权【随笔】
  19. 微分几何学习(二)(曲线论,弧微分)
  20. java继承链中方法调用优先级.顺序:this.show(object)super.show(object)this.show((super)object)super.show((super))

热门文章

  1. php word 邮件合并发送邮件,在word2010中的邮件合并,除需要主文档,还需要什么...
  2. 无法从“cstring”转换为“lpcstr”_学会CAD布局作图,让你少加班一个点!布局必备技能:转换空间...
  3. 南昌大学《嵌入式系统》期末考试试卷真题(含答案)
  4. 社会内卷的真正原因:华为内部论坛的这篇雄文火了
  5. dataframe数据分析常用操作汇总
  6. 有关计算机知识的活动总结,计算机兴趣小组活动总结范文
  7. hihocoder1636-Pangu and Stones
  8. 专业的计算机软件著作权,大仙们谁能赐教 专业计算机软件著作权费用是多少,计算机软件著作权排名怎么样大家来说说?_天涯问答_天涯社区...
  9. 揭秘OPhone白手起家前后:一个系统的诞生
  10. 安装linux双系统简书,win10 + ubuntu18.04 双系统的安装