特殊Pass之[GrabPass]

这篇博客介绍了如何在Unity 3D中使用GrabPass技术来实现复杂的视觉效果,包括法线贴图模拟折射和立方体贴图模拟反射。代码示例展示了如何结合纹理采样、屏幕坐标偏移以及切线空间法线来创建透明物体的折射效果,并利用反射向量从CubeMap中获取反射颜色,最终合成折射和反射的最终颜色。此外,还提到了渲染队列的设置和透明物体的处理方式。
以下是使用了GrabPass的完整代码
Properties { _MainTex("Main Tex",2D)= "white"{} _BumpMap("Normal Map",2D) ="bump"{} _CubeMap("Environment CubeMap",Cube) ="_Skybox"{} _Distortion("Distortion",Range(0,100)) = 10 _RefratAmount("Refract Amount",Range(0.0,1.0)) = 1.0 } SubShader { Tags { "Queue" = "Transparent" "RenderType"="Opaque" } GrabPass{"_RefractionTex"} pass{ CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex; float4 _MainTex_ST; sampler2D _BumpMap; float4 _BumpMap_ST; samplerCUBE _CubeMap; float _Distortion; float _RefratAmount; sampler2D _RefractionTex; float4 _RefractionTex_TexelSize; struct a2v{ float4 vertex : POSITION; float3 normal: NORMAL; float4 tangent : TANGENT; float2 texcoord : TEXCOORD0; }; struct v2f{ float4 pos : SV_POSITION; float4 scrPos : TEXCOORD0; float4 uv : TEXCOORD1; float4 TtoW0 : TEXCOORD2; float4 TtoW1 : TEXCOORD3; float4 TtoW2 : TEXCOORD4; }; v2f vert (a2v v){ v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.scrPos = ComputeGrabScreenPos(o.pos); o.uv.xy = TRANSFORM_TEX(v.texcoord,_MainTex); o.uv.zw = TRANSFORM_TEX(v.texcoord,_BumpMap); float3 worldPos = mul(unity_ObjectToWorld,v.vertex); fixed3 worldNormal = UnityObjectToWorldNormal(v.normal); fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz); fixed3 worldBinormal = cross(worldNormal,worldTangent) * v.tangent.w; 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); return o; } fixed4 frag (v2f i) : SV_Target{ float3 worldPos = float3(i.TtoW0.w,i.TtoW1.w,i.TtoW2.w); fixed3 worldViewDir = normalize(UnityWorldSpaceViewDir(worldPos)); fixed3 bump = UnpackNormal(tex2D(_BumpMap,i.uv.zw)); float2 offset = bump.xy * _Distortion * _RefractionTex_TexelSize.xy; i.scrPos.xy = offset + i.scrPos.xy; fixed3 refrCol = tex2D(_RefractionTex,i.scrPos.xy/i.scrPos.w).rgb; bump = normalize(half3(dot(i.TtoW0.xyz,bump),dot(i.TtoW1.xyz,bump),dot(i.TtoW2.xyz,bump))); fixed3 reflDir = reflect(-worldViewDir,bump); fixed4 texColor = tex2D(_MainTex,i.uv.xy); fixed3 reflCol = texCUBE(_CubeMap, reflDir).rgb * texColor.rgb; fixed3 finelColor = reflCol * (1-_RefratAmount) + refrCol * _RefratAmount; return fixed4(finelColor,1); } ENDCG } } FallBack "Diffuse"
在本代码中,通过使用“ GrabPass{"\_RefractionTex"}”这一行代码,来定义了一个名为\_RefractionTex的纹理中。 再通过 “sampler2D \_RefractionTex;”来创建一个同名纹理采样变量来供后面的pass进行访问。 通常用来实现玻璃等透明材质的模拟,例如:使用法线来模拟折射,而不是简单的原屏幕颜色进行混合。 在使用中需要小心物体的渲染队列设置,“Tags { "Queue" = "Transparent" "RenderType"="Opaque" }”需要把渲染队列设置成Transparent,这样才能保证所有不透明物体都已经被绘制在屏幕上。 在本文示例中: 使用了“\_BumpMap("Normal Map",2D) ="bump"{}”获取法线贴图来修改模型的法线信息。 使用了通过设置"GrabPass"得到的抓取透明物体背后采样信息,得到折射信息相关代码:“fixed3 refrCol = tex2D(\_RefractionTex,i.scrPos.xy/i.scrPos.w).rgb;” 为此须先使用“UnityCG.cginc“中声明的“ComputeGrabScreenPos()”函数来得到被抓取的屏幕图像采样坐标。“o.scrPos = ComputeGrabScreenPos(o.pos);” 在模拟折射时,使用了切线空间下的法线对屏幕纹理坐标的偏移后再采样。 使用了一个CubeMap来模拟玻璃的反射,相关代码:“fixed3 reflCol = texCUBE(\_CubeMap, reflDir).rgb \* texColor.rgb;
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值