編輯:關於android開發
開始學習第4章 - 著色器的反射
看完了1、2節,來記錄一下。反射主要是利用了 Cubemap 立方體貼圖。
立方體貼圖,就如同名字所說,在一個立方體上有6張圖,就這樣認為吧。假想一下 ,在一個艷麗的房間裡,有一個表面是鏡子的圓球,那這個圓球表面就反射了房間裡面的所有東西,就是一個大號的凸鏡。
這是到網上找得一張圖,很直觀的表達了我的意思……
注意標題中說的,靜態立方體貼圖,為什麼叫靜態,因為這一次使用的立方體貼圖是提前生成好的圖片,而不是動態生成的。
這又是什麼意思呢?
就拿上面圖片中的場景來說,如果是靜態的立方體貼圖,那麼當這個球在移動的時候,球上面顯示的東西是不會變動的。
現實生活中的話,球移動,球上面顯示出來的內容應該也是要隨之變動的。
那麼這裡使用靜態立方體貼圖呢,是先學習立方體貼圖的知識,後面會學習動態立方體貼圖的,在書上是 4.6 這一節。
首先來創建一個立方體貼圖,在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。
上面創建好了立方體貼圖,然後就可以使用了。
仍然創建一個材質,一個 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
關於android架構的文章工程等 Flux Architecture https://github.com/lgvalle/android-flux-todo-app
Android中ListView實現圖文並列並且自定義分割線(完善仿微信APP),androidlistview昨天的(今天凌晨)的博文《Android中Fragment
Android--JNI簡單的實例解析 最近項目迭代了幾個版本,目前比較輕松,雖然項目閒了,但是人不能太閒,否則就廢了。千裡之行始於足下、量變引起質變、學而不思則罔.
小波Linux安卓Sqlite數據庫實現用戶登錄注冊,通俗易懂!,安卓sqlite看了很多別人寫的安卓SQlite數據的操作代碼,都是浮雲,瞎弄!一點也不通俗易懂,我覺得