Unity Shaders and Effects Cookbook (4-1)(4-2)静态立方体贴图的创建与使用
Posted yangykaifa
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity Shaders and Effects Cookbook (4-1)(4-2)静态立方体贴图的创建与使用相关的知识,希望对你有一定的参考价值。
開始学习第4章 - 着色器的反射
看完了1、2节,来记录一下。反射主要是利用了 Cubemap 立方体贴图。
认识Cubemap
立方体贴图。就如同名字所说。在一个立方体上有6张图。就这样觉得吧。
假想一下 ,在一个艳丽的房间里。有一个表面是镜子的圆球。那这个圆球表面就反射了房间里面的全部东西。就是一个大号的凸镜。
这是到网上找得一张图,非常直观的表达了我的意思……
注意标题中说的,静态立方体贴图。为什么叫静态。由于这一次使用的立方体贴图是提前生成好的图片,而不是动态生成的。
这又是什么意思呢?
就拿上面图片中的场景来说,假设是静态的立方体贴图。那么当这个球在移动的时候。球上面显示的东西是不会变动的。
现实生活中的话,球移动。球上面显示出来的内容应该也是要随之变动的。
那么这里使用静态立方体贴图呢。是先学习立方体贴图的知识。后面会学习动态立方体贴图的。在书上是 4.6 这一节。
创建Cubemap
首先来创建一个立方体贴图,在Assets 中右键新建一个 Cubemap。
搭建场景,加入一个Sphere 作为Camera 的容器。
由于要借助 Camera 的 API 来生成Cubemap。
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
以下是我搭建的场景。
以下编写一个Unity编辑器插件来生成CubeMap。
using UnityEngine; using System.Collections; using UnityEditor; public class GenerateStaticCubemap : ScriptableWizard { public Transform renderPosition; public Cubemap cubemap; void OnizardUpdate() { helpString = "Select transform to render" + "from and cubemap to render into"; if (renderPosition != null && cubemap != null) { isValid = true; } else { isValid = false; } } void OnWizardCreate() { //加入一个Camera,用来创建Cubemap的。GameObject go = new GameObject("CubemapCamera", typeof(Camera)); go.transform.position = renderPosition.position; go.transform.rotation = Quaternion.identity; go.camera.RenderToCubemap(cubemap); DestroyImmediate(go); } [MenuItem("CookBookShaders/Render Cubemap")] static void RenderCubemap() { ScriptableWizard.DisplayWizard("Render Cube", typeof(GenerateStaticCubemap), "Render"); } }
由于是编辑器工具。所以要遵循unity的规定。把这个代码文件放在 名为 Editor 的目录中。自己新建一个即可。
这个代码文件的核心就是
go.camera.RenderToCubemap(cubemap);
借助Camera 的 API。生成了一个 Cubemap。
然后加入了一个菜单,作为入口。
[MenuItem("CookBookShaders/Render Cubemap")]
等unity 编译完毕后。菜单条就会出现我们自己加入的菜单。
把刚才创建的 Cubemap 拖进来,把Sphere拖进来。
点击 Render 就生成了 Cubemap。
使用Cubemap
上面创建好了立方体贴图,然后就能够使用了。
仍然创建一个材质。一个 Shader。
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
Shader 代码
Shader "CookBookShaders/Cubemap" { Properties { _MainTint("Diffuse Tint",Color)=(1,1,1,1) _MainTex ("Base (RGB)", 2D) = "white" {} _Cubemap("Cubemap",CUBE)=""{} _ReflectionAmount("Reflection Amount",Range(0.01,1))=0.5 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Lambert float4 _MainTint; sampler2D _MainTex; samplerCUBE _Cubemap; float _ReflectionAmount; 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 *_ReflectionAmount; o.Albedo = c.rgb; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" }
第一次使用立方体贴图。
在Properties 块中。定义属性的使用类型是 CUBE。普通纹理是 2D。
在SubShader 中,定义变量的时候注意用 samplerCUBE。普通纹理是 sampler2D。
在 Input 结构体中,使用了 Unity的内置变量 worldRefl 。这个变量 提供了在着色器中使用的 世界反射变量。
然后在 surf 函数中,使用 texCube 从Cubemap 中取纹素。
texCUBE(_Cubemap,IN.worldRefl).rgb
执行后的效果
演示样例project下载:
http://pan.baidu.com/s/1qYcNKxI
以上是关于Unity Shaders and Effects Cookbook (4-1)(4-2)静态立方体贴图的创建与使用的主要内容,如果未能解决你的问题,请参考以下文章
Unity Shaders and Effects Cookbook (6-2) 透明裁剪着色器
Unity Shaders and Effects Cookbook (6-1) 使用 alpha 参数的 半透明着色器
Unity Shaders and Effects Cookbook (6-3) 修改渲染队列Queue 来 修改渲染顺序
Unity Shaders and Effects Cookbook (7-3) 在地形中使用顶点颜色做混合
Unity Shaders and Effects Cookbook (D-2) Cull Back背面剔除 -- 模型半边不可见
Unity Shaders and Effects Cookbook (5-1)LitSphere lighting model