Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Unity Shaders and Effects Cookbook (4-1)(4-2)靜態立方體貼圖的創建與使用

Unity Shaders and Effects Cookbook (4-1)(4-2)靜態立方體貼圖的創建與使用

編輯:關於Android編程

開始學習第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。

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

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved