unity實現(xiàn)玻璃效果
本文實例為大家分享了unity實現(xiàn)玻璃效果的具體代碼,供大家參考,具體內(nèi)容如下
一、使用Cubemap,做一個假反射
shader代碼如下:
Shader "Custom/glassShader" { Properties { _MainColor("Main Color",Color)=(1,1,1,1) _MainTex ("Base (RGB)", 2D) = "white" {} _Cube("Cube",CUBE)=""{} } SubShader { Tags {"RenderType"="Opaque"} LOD 200 //cull off CGPROGRAM #pragma surface surf Lambert alpha fixed4 _MainColor; sampler2D _MainTex; samplerCUBE _Cube; struct Input { float2 uv_MainTex; float3 worldRefl; }; void surf (Input IN, inout SurfaceOutput o) { half4 c = tex2D (_MainTex, IN.uv_MainTex); o.Albedo = c.rgb*_MainColor.rgb; o.Emission=texCUBE(_Cube,IN.worldRefl).rgb; o.Alpha = c.a*_MainColor.a; } ENDCG } FallBack "Diffuse" }
二、使用GrabPass,抓取屏幕紋理,實現(xiàn)實時反射
shader代碼如下:
Shader "Unlit/GrabGlass" { Properties { _Color("Main Color",Color)=(1,1,1,1) _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags {"Queue"="Transparent" "RenderType"="Opaque" }//Opaque LOD 100 //繪制半透明物體 關(guān)閉深度緩存 ZWrite Off //透明混合 Blend SrcAlpha OneMinusSrcAlpha //如果沒有命名,則可以用_GrabTexture來讀取,不過開銷很大,應(yīng)用到特殊效果時才去應(yīng)用 GrabPass { "_GrabTex" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag // make fog work #pragma multi_compile_fog #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; UNITY_FOG_COORDS(1) float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; fixed4 _Color; sampler2D _GrabTex; v2f vert (appdata v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); UNITY_TRANSFER_FOG(o,o.vertex); return o; } fixed4 frag (v2f i) : SV_Target { // sample the texture fixed4 col = tex2D(_MainTex, i.uv)*_Color; // apply fog UNITY_APPLY_FOG(i.fogCoord, col); //調(diào)整一下uv float2 uv=i.uv; uv.x=1-uv.x; return col*tex2D(_GrabTex,uv); } ENDCG } } }
效果如下:
三、使用攝像機實現(xiàn)實時反射
因為GrabPass,相對來說消耗較大,只建議用于一些特殊效果,于是這里就借助輔助攝像機,來實現(xiàn)實時反射效果,當然這需要多寫一個腳本,同時需要在輔助攝像機中屏蔽玻璃本身
shader代碼如下:
Shader "Unlit/CameraGlass" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag // make fog work #pragma multi_compile_fog #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; UNITY_FOG_COORDS(1) float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; v2f vert (appdata v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); UNITY_TRANSFER_FOG(o,o.vertex); return o; } fixed4 frag (v2f i) : SV_Target { // sample the texture 需要調(diào)整一下uv fixed4 col = tex2D(_MainTex, 1-i.uv); // apply fog UNITY_APPLY_FOG(i.fogCoord, col); return col; } ENDCG } } }
腳本代碼如下:
using UnityEngine; using System.Collections; public class RenderGlassTexture : MonoBehaviour { /// <summary> /// 輔助攝像機 /// 原理:就是將輔助攝像機所看到的內(nèi)容渲染到玻璃物體上,所以就實現(xiàn)了實時反射的鏡面效果 /// 因為玻璃也是場景中的物體,所以輔助攝像機也會看見他 /// 所以最好能將玻璃物體單獨放在一個層級中,讓輔助攝像機不去渲染他 /// </summary> public Camera cam; private RenderTexture renderTex; /// <summary> /// 玻璃shader /// </summary> public Shader glassShader; /// <summary> /// 玻璃材質(zhì) /// </summary> private Material m_GlassMaterial; protected Material GlassMaterial { get { if (m_GlassMaterial == null) { m_GlassMaterial = new Material(glassShader); } return m_GlassMaterial; } } // Use this for initialization void Start () { renderTex = new RenderTexture(Screen.width, Screen.height, 16); cam.targetTexture = renderTex; } //在攝像機開始裁剪場景之前調(diào)用 void OnPreCull() { GlassMaterial.SetTexture("_MainTex", renderTex); } //在相機完成場景渲染后調(diào)用 void OnPostRender() { GlassMaterial.SetTexture("_MainTex", null); } }
效果如下:
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
c#幾種數(shù)據(jù)庫的大數(shù)據(jù)批量插入(SqlServer、Oracle、SQLite和MySql)
這篇文章主要介紹了c#幾種數(shù)據(jù)庫的大數(shù)據(jù)批量插入(SqlServer、Oracle、SQLite和MySql),需要的朋友可以了解一下。2016-11-11c# EPPlus秘籍之Excel實現(xiàn)圖表導(dǎo)出
這篇文章主要為大家介紹了c# EPPlus秘籍之Excel實現(xiàn)圖表導(dǎo)出示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-12-12Winform基于多線程實現(xiàn)每隔1分鐘執(zhí)行一段代碼
這篇文章主要介紹了Winform基于多線程實現(xiàn)每隔1分鐘執(zhí)行一段代碼的方法,設(shè)計線程的操作及時間函數(shù)的用法,需要的朋友可以參考下2014-10-10