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

运行后的效果



示例工程下载:

http://pan.baidu.com/s/1qYcNKxI


           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

猜你喜欢

转载自blog.csdn.net/qq_43667944/article/details/87866331