昨天逛街的时候看到太平鸟里面摆了个金属的米老鼠,于是职业病犯了,一直在想金属的颜色是什么,这个反射该怎么写,想不出来……
今天正好看到动态反射立方图系统这一节,看完觉得很别扭,因为书上介绍的是事先踩点生成Cubemap的方式而不是实时的。于是到官方文档找到实时反射的代码,做了一个比较花俏的场景,运行之后吃了一大惊,实时反射是如此的震撼。。
第四章第一节第二节介绍了创建Cubemap,然后学习了如何使用。
Unity Shaders and Effects Cookbook (4-1)(4-2)静态立方体贴图的创建与使用
我也说过了,是静态的Cubemap,就是说这个Cubemap是采集自一个地方,不会随着位置的移动去动态采集周围环境来产生反射。
这一节学习实时动态立方图。
书上 4.6 这一节讲的是简单的动态立方图系统,意思就是在一个房间内的几个点,进行采集,然后生成好几个Cubemap。
然后判断物体位置,靠近了采集点的时候就选用当前采集点的Cubemap。
我画了个图
1、2、3、4是采集点,在这4个点分别创建 Cubemap1、Cubemap2、Cubemap3、Cubemap4。
中间的是人。
当人走到靠近 采集点3 的位置,就使用 Cubemap3。
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
这样是动态的,但并不是实时。
我还是到网上寻找实时的反射,参照Unity 文档实现。
http://docs.unity3d.com/ScriptReference/Camera.RenderToCubemap.html
我翻译成了 C#的。
先来看看效果图。
和4.1 学习的静态立方图 相比,这一节学习的实时立方图,只是把立方图修改为实时生成了。
还记得立方图生成 是使用了 Camera的API
camera.RenderToCubemap(cubemap);
之前我们在 Assets 中创建了 Cubemap ,是因为 创建 和 使用 不是在一起做的。
这一次因为是实时的,所以不用在 Assets 中创建 Cubemap了,创建后用变量存起来,在 LateUpdate 中更新。
搭建好场景,我这里为了好看点就涂涂抹抹做了一个地形。添加一个 Sphere做反射,材质用第一节 的就可以了,复制一份。然后材质中的 Cubemap 去掉,因为现在我们用实时生成的了。
在 Sphere 上挂上下面的脚本
using UnityEngine; using System.Collections; public class RealtimeReflection : MonoBehaviour { Camera reflectionCamera; RenderTexture cubemap; // Use this for initialization void Start () { GameObject go = new GameObject("Reflection Camera", typeof(Camera)); reflectionCamera = go.camera; go.hideFlags = HideFlags.HideAndDontSave; go.transform.position = transform.position; go.transform.rotation = Quaternion.identity; reflectionCamera.farClipPlane = 100; reflectionCamera.enabled = false; cubemap = new RenderTexture(128, 128, 16); cubemap.isCubemap = true; cubemap.hideFlags = HideFlags.HideAndDontSave; renderer.sharedMaterial.SetTexture("_Cubemap", cubemap); reflectionCamera.transform.position = transform.position; reflectionCamera.RenderToCubemap(cubemap, 63); } void RenderCubemap() { } // Update is called once per frame void Update () { } void LateUpdate() { reflectionCamera.transform.position = transform.position; reflectionCamera.RenderToCubemap(cubemap, 63); } }
主要的就是 LateUpdate 中的 RenderToCubemap
public bool RenderToCubemap(RenderTexture cubemap, int faceMask = 63);
官方文档
http://docs.unity3d.com/ScriptReference/Camera.RenderToCubemap.html
这 6 个 1的顺序是:右 左 上 下 前 后
官方文档
http://docs.unity3d.com/ScriptReference/CubemapFace.html
using UnityEngine; using System.Collections; public class MoveController : MonoBehaviour { [SerializeField] Transform cameraTrans; // Use this for initialization void Start () { } void OnGUI() { if (GUI.RepeatButton(new Rect(250, 50, 90, 90), "Forward")) { transform.localPosition += new Vector3(0, 0, 10 * Time.deltaTime); } if (GUI.RepeatButton(new Rect(250, 150, 90, 90), "Back")) { transform.localPosition += new Vector3(0, 0, -10 * Time.deltaTime); } if (GUI.RepeatButton(new Rect(150, 150, 90, 90), "Left")) { transform.localPosition += new Vector3(-10 * Time.deltaTime, 0, 0); } if (GUI.RepeatButton(new Rect(350, 150, 90, 90), "Right")) { transform.localPosition += new Vector3(10 * Time.deltaTime, 0, 0); } if (GUI.RepeatButton(new Rect(650, 50, 90, 90), "Up")) { transform.localPosition += new Vector3(0, 10 * Time.deltaTime, 0); } if (GUI.RepeatButton(new Rect(650, 150, 90, 90), "Down")) { transform.localPosition += new Vector3(0, -10 * Time.deltaTime, 0); } } // Update is called once per frame void Update () { if (Input.GetKey(KeyCode.W)) { transform.localPosition += new Vector3(0, 0, 10 * Time.deltaTime); } if (Input.GetKey(KeyCode.A)) { transform.localPosition += new Vector3(-10 * Time.deltaTime,0, 0); } if (Input.GetKey(KeyCode.S)) { transform.localPosition += new Vector3(0, 0, -10 * Time.deltaTime); } if (Input.GetKey(KeyCode.D)) { transform.localPosition += new Vector3(10 * Time.deltaTime, 0, 0); } if (Input.GetKey(KeyCode.Q)) { transform.localPosition += new Vector3(0, -10 * Time.deltaTime, 0); } if (Input.GetKey(KeyCode.E)) { transform.localPosition += new Vector3(0, 10 * Time.deltaTime, 0); } } void LateUpdate() { cameraTrans.localPosition = transform.localPosition + new Vector3(0f, 1.0f, -2f); } }
手机上的截图
但是效果真的很震撼。
项目打包下载:
http://pan.baidu.com/s/1dFqb7NV
APK下载:
http://pan.baidu.com/s/1gf2iJcv