Unity Shader模拟玻璃效果
本文实例为大家分享了UnityShader实现玻璃效果的具体代码,供大家参考,具体内容如下
Shader"GlassRefraction"{ Properties{ _MainTex("MainTex",2D)="white"{} _BumpMap("NormalMap",2D)="bump"{} _Cubemap("EnvironmentCubemap",Cube)="_Skybox"{} _Distortion("Distortion",Range(0,100))=10 _RefractAmount("RefractAmount",Range(0.0,1.0))=1.0 } SubShader{ //1.队列设置成透明的可以保证渲染该物体的时候,其他所有不透明的物体都已经被渲染到屏幕上了 //这样GrabPass保存屏幕图像的时候才能完整 //2.渲染类型设置为不透明是为了使用着色器替换的时候,物体可以在被需要时正确的渲染 Tags{"Queue"="Transparent""RenderType"="Opaque"} //抓取屏幕图像并保存到纹理_RefractionTex中 GrabPass{"_RefractionTex"} Pass{ CGPROGRAM #pragmavertexvert #pragmafragmentfrag #include"UnityCG.cginc" sampler2D_MainTex; float4_MainTex_ST; sampler2D_BumpMap; float4_BumpMap_ST; samplerCUBE_Cubemap; float_Distortion; fixed_RefractAmount; sampler2D_RefractionTex; //可以得到系统保存的纹素的尺寸大小1/256,1/512 //对屏幕图像坐标采样进行偏移的时候需要使用该变量 float4_RefractionTex_TexelSize; structa2v{ float4vertex:POSITION; float3normal:NORMAL; float4tangent:TANGENT; float2texcoord:TEXCOORD0; }; structv2f{ float4pos:SV_POSITION; float4scrPos:TEXCOORD0; float4uv:TEXCOORD1; float4TtoW0:TEXCOORD2; float4TtoW1:TEXCOORD3; float4TtoW2:TEXCOORD4; }; v2fvert(a2vv){ v2fo; o.pos=mul(UNITY_MATRIX_MVP,v.vertex); //得到对应被抓取的屏幕图像的采样坐标 o.scrPos=ComputeGrabScreenPos(o.pos); //原图和法线贴图公用同一套UV坐标,进行纹理偏移缩放设置 o.uv.xy=TRANSFORM_TEX(v.texcoord,_MainTex); o.uv.zw=TRANSFORM_TEX(v.texcoord,_BumpMap); //世界方向 float3worldPos=mul(unity_ObjectToWorld,v.vertex).xyz; //法线世界方向 fixed3worldNormal=UnityObjectToWorldNormal(v.normal); //切线世界方向 fixed3worldTangent=UnityObjectToWorldDir(v.tangent.xyz); //世界副切线方向 fixed3worldBinormal=cross(worldNormal,worldTangent)*v.tangent.w; //定义:切线空间到世界空间的变换矩阵 //所有的TBN都从切线空间转换到了世界空间 o.TtoW0=float4(worldTangent.x,worldBinormal.x,worldNormal.x,worldPos.x); o.TtoW1=float4(worldTangent.y,worldBinormal.y,worldNormal.y,worldPos.y); o.TtoW2=float4(worldTangent.z,worldBinormal.z,worldNormal.z,worldPos.z); returno; } fixed4frag(v2fi):SV_Target{ //世界空间 float3worldPos=float3(i.TtoW0.w,i.TtoW1.w,i.TtoW2.w); //世界空间下的观察方向 fixed3worldViewDir=normalize(UnityWorldSpaceViewDir(worldPos)); //对法线贴图进行采样,并使用UnpackNormal解压*2-1,但实际上法线贴图在切线空间下 //所以需要将bump从切线空间转换到世界空间 fixed3bump=UnpackNormal(tex2D(_BumpMap,i.uv.zw)); //对采样坐标进行偏移 float2offset=bump.xy*_Distortion*_RefractionTex_TexelSize.xy; i.scrPos.xy=offset*i.scrPos.z+i.scrPos.xy; //对屏幕纹理进行采样 fixed3refrCol=tex2D(_RefractionTex,i.scrPos.xy/i.scrPos.w).rgb; //将bump从切线空间转换到世界空间 //TtoW0的xyz:T的X,B的X,N的X //用点积得到一个常量 bump=normalize(half3(dot(i.TtoW0.xyz,bump),dot(i.TtoW1.xyz,bump),dot(i.TtoW2.xyz,bump))); //用法线贴图求反射方向 fixed3reflDir=reflect(-worldViewDir,bump); //主纹理采样 fixed4texColor=tex2D(_MainTex,i.uv.xy); //对_Cubemap进行纹理采样,使用反射方向 fixed3reflCol=texCUBE(_Cubemap,reflDir).rgb*texColor.rgb; //反射颜色+折射颜色 fixed3finalColor=reflCol*(1-_RefractAmount)+refrCol*_RefractAmount; returnfixed4(finalColor,1); } ENDCG } } FallBack"Diffuse" }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。