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

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

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

写在前面


通过上一节,我们已经知道如何创建我们自己的Cubemaps,现在,我们可以来看一下如何使用这种新的贴图类型来在Shaders中模拟反射效果。使用Cubemaps进行反射的原理实际上非常简单,但是这将给你的Shader效果带来翻天覆地的变化。它的原理主要是通过模型表面的每个顶点的法向量,去查找Cubemap贴图上的某一个位置。这种查找将会返回一个颜色值,来模拟这个Cubemap反射到你的对象上的这种效果。

这篇教程将会教给你用Cubemaps来进行反射的第一步!Unity实际上给我们提供了自动得到反射向量的方法,所以我们不需要自己去计算它了。这是在Input结构体中的内置的worldRefl向量中实现的。这会帮助我们去查找对应的Cubemap贴图中的位置。因此,第一步的内容将非常简单!


准备工作


在我们开始写Shader代码之前,我们需要搭建一个简单的场景。
  1. 创建一个新的scene,Material,和Shader,可以取名为SimpleReflection。
  2. 附着新的Shader到新的Material上,然后创建一个物体,并把Material赋值给它。
  3. 最后,创建或者找到一个Cubemap,之后将用于我们的Shader。

下面的截图显示了我们这节中将要使用的Cubemap(这是通过在上一篇的基础上,在场景中球体所在的位置创建的自己的Cubemap)。你的可能和它不一样,没有关系,我们仅仅是想展示一下使用的Cubemap的样子,以便在最后的效果中不会产生任何难理解的地方。使用自己的也是完全可以的。





实现


下面,让我们来实现真正的Shader代码吧!

  1. 首先在Properties块中创建新的properties。我们需要一个位置来得到我们的Cubemap贴图对象以及来控制反射的程度:

    	Properties {
    _MainTex ("Base (RGB)", 2D) = "white" {} _MainTint ("Diffuse Tint", Color) = (1,1,1,1)
    _Cubemap ("CubeMap", CUBE) = ""{}
    _ReflAmount ("Reflection Amount", Range(0.01, 1)) = 0.5
    }
  2. 同样,我们还需要在SubShader块中创建和properties中各变量的联系。这将允许我们从Properties块中访问这些数据。
    		CGPROGRAM
    #pragma surface surf Lambert sampler2D _MainTex;
    samplerCUBE _Cubemap;
    float4 _MainTint;
    float _ReflAmount
  3. 为了让我们能够模拟正确的反射角度,我们需要得到一个向量来提供给我们合适的世界反射方向。因此,我们可以使用上面提到的Unity的Surface Shaders内置的变量。在Input结构体中,下面的代码将提供给我们一个世界反射向量,来用于接下来的Shader中:
    		struct Input {
    float2 uv_MainTex;
    float3 worldRefl
    };
  4. 最后,我们仅仅需要从Cubemap中得到贴图信息,即使用texCUBE函数和Input提供给我们的新的世界反射向量。添加下面的代码到你的surf函数中:
    		void surf (Input IN, inout SurfaceOutput o) {
    half4 c = tex2D (_MainTex, IN.uv_MainTex) * _MainTint;
    o.Emission = texCUBE(_Cubemap, IN.worldRefl).rgb * _ReflAmount;;
    o.Albedo = c.rgb;
    o.Alpha = c.a;
整体代码如下:
Shader "Custom/SimpleReflection" {
Properties {
_MainTint ("Diffuse Tint", Color) = (1,1,1,1)
_MainTex ("Base (RGB)", 2D) = "white" {}
_Cubemap ("CubeMap", CUBE) = ""{}
_ReflAmount ("Reflection Amount", Range(0.01, 1)) = 0.5
} SubShader {
Tags { "RenderType"="Opaque" }
LOD 200 CGPROGRAM
#pragma surface surf Lambert sampler2D _MainTex;
samplerCUBE _Cubemap;
float4 _MainTint;
float _ReflAmount; struct Input {
float2 uv_MainTex;
float3 worldRefl;
}; void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex) * _MainTint;
o.Emission = texCUBE(_Cubemap, IN.worldRefl).rgb * _ReflAmount;;
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}


最后,当我们和上一篇中创建的Cubemap结合起来后,就可以得到下面的效果。可以看到其中的球有反射的效果。



解释


上面代码能够成功的主要原因就是Unity3D提供的Surface Shader的Input结构的内置属性。worldRefl变量给我们需要的反射向量来正确的采样我们的Cubemap。我们仅需要在函数中使用worldRefl属性,就可以很方便地得到正确的反射视角。

下面的截图展示了一个什么是传递给Shader的反射数据的例子。

【Unity Shaders】Reflecting Your World —— Unity3D中简单的Cubemap反射的更多相关文章

  1. Unity3D中简单的C#异步Socket实现

    Unity3D中简单的C#异步Socket实现 简单的异步Socket实现..net框架自身提供了很完善的Socket底层.笔者在做Unity3D小东西的时候需要使用到Socket网络通信.于是决定自 ...

  2. 【Unity Shaders】学习笔记——SurfaceShader(九)Cubemap

    [Unity Shaders]学习笔记——SurfaceShader(九)Cubemap 如果你想从零开始学习Unity Shader,那么你可以看看本系列的文章入门,你只需要稍微有点编程的概念就可以 ...

  3. 【Unity Shaders】Reflecting Your World —— Unity3D中的遮罩反射(Masking Reflections)

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

  4. 【Unity Shaders】Reflecting Your World —— Unity3D中的法线贴图和反射

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

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

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

  6. 【Unity Shaders】Lighting Models —— 光照模型之Lit Sphere

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

  7. 【Unity Shaders】Lighting Models —— 灯型号Lit Sphere

    考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同一时候会加上一点个人理解或拓展. 这里是本书全部的插图.这里是本书所需的代码和资源(当然你 ...

  8. Unity3D中的常用方法

    备注:文中所使用的this均指脚本所依附的对象 1.移动(用Translate方法进行移动) ; //移动速度 this.transform.Translate(Vector3.down * Time ...

  9. 【Unity Shaders】Reflecting Your World —— 在Unity3D中创建一个简单的动态Cubemap系统

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

随机推荐

  1. hive升级遇到的几个小问题

    1.hiveserver2正常启动,但是beeline连不上服务. 我的服务是开在本机的,但是用主机名和127好像都不能访问服务了 jdbc:hive2://172.19.1.11:10000> ...

  2. RandomAccessFile&IO流&排序&方法论

    RandomAccessFile&IO流&排序&方法论 我们总觉得历史是极其遥远的东西,与我们并无关联,又觉得历史隐藏在图书馆的旧书之中. 然而,我们每个人都有真真切切的历史. ...

  3. ORA-01207: file is more recent than control file - old control file的处理方法

    1. 连接数据库 sqlplus / as sysdba2. 启动数据库,此时会报标题中的错误startup 3.备份创建控制文件的脚本语句,并从中拷贝出相关的NORESETLOGS模式的创建控制文件 ...

  4. JVM的Server与Client运行模式区别与切换

    概述 JVM有两种运行模式Server与Client.两种模式的区别在于,Client模式启动速度较快,Server模式启动较慢:但是启动进入稳定期长期运行之后Server模式的程序运行速度比Clie ...

  5. (译)快速指南:用UIViewPropertyAnimator做动画

    翻译自:QUICK GUIDE: ANIMATIONS WITH UIVIEWPROPERTYANIMATOR 译者:Haley_Wong iOS 10 带来了一大票有意思的新特性,像 UIViewP ...

  6. Android艺术开发探索第三章——View的事件体系(上)

    Android艺术开发探索第三章----View的事件体系(上) 我们继续来看这本书,因为有点长,所以又分了上下,你在本片中将学习到 View基础知识 什么是View View的位置参数 Motion ...

  7. Html书写规范,基本标签使用

    一.html简介1.html是什么Html是用来描述网页的一种语言.(1)HTML 指的是超文本标记语言 (Hyper Text Markup Language)(2)HTML 不是一种编程语言,而是 ...

  8. ActiveMQ入门示例

    1.ActiveMQ下载地址 http://activemq.apache.org/download.html 2.ActiveMQ安装,下载解压之后如下目录

  9. Struts 2之Servlet API

    Struts 2对Servlet API进行了封装,是业务层更加独立,如果需要调用Request.Response等Servlet API有两种途径 利用ServletActinContext的静态方 ...

  10. 01_学习java WEB涉及到的相关技术

     http协议 Tomcat服务器 Servlet技术 JSP技术 HTML CSS Javascript JDBC技术 MySQL.Oracle SQL语言 JavaBean 常用开源组件 DO ...