unity3d技术---在2d游戏中用shader模拟阴影
2016-06-10 12:45
369 查看
在做2d游戏的时候,往往会遇到2d场景或角色阴影投射时,无法使用正常的光照投影系统,以前我一般会复制一份要投影的物体进行变换后处理颜色并给透明度就当作影子了,但最近有位朋友说到性能和实际工作效率时提出想用shader来实现这一问题,我就试着写了一个这样的shader。
首先需要让shader绘制出第二份同样的物体,一般来讲就是添加一个pass。
效果是这样的,注意,这里是一个gameobject。
然后把透明遮罩加上,并把阴影部分的透明度在0.5以上的部分设置为0.5,最后在调整好位置。
记得把ZWrite off 加上,否则就会出现看起来是透明的底,却能把同样的物体挡住的现象。像这样:
说道ZWrite的问题,其实挺麻烦的,因为关闭了之后就会使得后面的物体反倒出现在前面,最直接的方法就是定义渲染顺序,直接加上
最终版本的代码如下:
最终效果图:
首先需要让shader绘制出第二份同样的物体,一般来讲就是添加一个pass。
Pass { ZWrite Off Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert_offset #pragma fragment frag_color ENDCG } Pass { ZWrite Off Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert_normal #pragma fragment frag_normal ENDCG }
效果是这样的,注意,这里是一个gameobject。
然后把透明遮罩加上,并把阴影部分的透明度在0.5以上的部分设置为0.5,最后在调整好位置。
记得把ZWrite off 加上,否则就会出现看起来是透明的底,却能把同样的物体挡住的现象。像这样:
说道ZWrite的问题,其实挺麻烦的,因为关闭了之后就会使得后面的物体反倒出现在前面,最直接的方法就是定义渲染顺序,直接加上
Tags{"Queue" = "Transparent"}
最终版本的代码如下:
Shader "Custom/Shadow" { Properties { _MainTex ("Main Tex", 2D) = "white" {} _AlphaTex("AlphaTex",2D) = "white"{} _Offset ("Offset", vector) = (0, 0, 0, 0) } CGINCLUDE #include "UnityCG.cginc" sampler2D _MainTex; float4 _Offset; sampler2D _AlphaTex; float4 _MainTex_ST; struct v2f { float4 pos : POSITION; float2 uv : TEXCOORD0; }; v2f vert_normal(appdata_base v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); return o; } v2f vert_offset(appdata_base v) { v2f o; float4 pos = mul(_Object2World, v.vertex); o.pos = mul(UNITY_MATRIX_VP, pos + _Offset); o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); return o; } float4 frag_normal(v2f i) : COLOR { float4 texcol = tex2D (_MainTex, i.uv); texcol.w = tex2D(_AlphaTex,i.uv)*texcol.w; return texcol; } float4 frag_color(v2f i) : COLOR { float4 c; c = tex2D(_MainTex, i.uv); c.w = tex2D(_AlphaTex,i.uv)*c.w; if(c.w >= 0.5) { c.r =0; c.g=0; c.b=0; c.w = 0.5f; } return c; } ENDCG SubShader { Tags{"Queue" = "Transparent"} Pass { ZWrite Off Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert_offset #pragma fragment frag_color ENDCG } Pass { ZWrite Off Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert_normal #pragma fragment frag_normal ENDCG } } FallBack "Diffuse" }
最终效果图:
相关文章推荐
- Kinect结合Unity3D引擎开发体感游戏(一)
- 我是运营,我没有假期
- 每个 Linux 游戏玩家都绝不想要的恼人体验
- test
- 在 Fedora 上使用 Steam play 和 Proton 来玩 Windows 游戏
- Steam 让我们在 Linux 上玩 Windows 的游戏更加容易
- 如何使用 Steam Play 在 Linux 上玩仅限 Windows 的游戏
- 新一代iPad适配应用之游戏篇
- 网络路由技术及运用2
- 路由器的关键技术
- IP网络路由技术
- 远程控制技术的应用
- 智能防火墙的技术特征
- 什么是多层交换技术
- 浅析多层交换技术
- 路由器技术的变革
- 网络路由技术及运用3
- VB实现的《QQ美女找茬游戏》作弊器实例
- CSS中的滑动门技术