加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

[Shader 着色器]Unity 体积雾 Shader

(2013-02-27 15:54:54)
标签:

unity

shader

mr.ider

it

分类: Unity技术文档
原文地址:Unity 体积雾 Shader|http://game.ceeger.com/forum/read.php?tid=3132

  全局雾很简单,在unity里只需要一个选项即可,可是它不能控制局部地区的雾化效果。所以有”Volume Fog”这种shader,网上搜了很久,只有一个比较满意:www.youtube.com/watch?v=HPo2gfy675o,可是要卖50刀(站长看看有没有意愿团一个?~~)

算了,自己动手,再次硬着头皮上了,为此我还狠心买了《GPU Gems》全套,既然目前我都在研究游戏里的特效实现,不光是粒子系统,shader也是重要的组成部分,所以我决定以后也会在Xffect里多包含一些实用的shader,比如这次分享的Volume Fog。还有很早前就包含的“Heat Distortion”(热浪?)shader,这个是非常实用的,因为很多特效都有局部画面扭曲效果。

下面放2张截图,目前的体积雾只支持球体。

在fog外面看到的效果:
http://game.ceeger.com/forum/attachment/thumb/Mon_1208/2_2159_f575b82e0d12d53.jpg?52着色器]Unity 体积雾 Shader" TITLE="[Shader 着色器]Unity 体积雾 Shader" />
在fog里面看到的效果:
http://game.ceeger.com/forum/attachment/thumb/Mon_1208/2_2159_f89c7ad414ee9c6.jpg?61着色器]Unity 体积雾 Shader" TITLE="[Shader 着色器]Unity 体积雾 Shader" />
我的游戏项目里用到的效果:
http://game.ceeger.com/forum/attachment/thumb/Mon_1208/2_2159_023f45b97dc5aac.jpg?173着色器]Unity 体积雾 Shader" TITLE="[Shader 着色器]Unity 体积雾 Shader" />
http://game.ceeger.com/forum/attachment/thumb/Mon_1208/2_2159_7a43ec5e02b1939.jpg?147着色器]Unity 体积雾 Shader" TITLE="[Shader 着色器]Unity 体积雾 Shader" />

=================================================================

好了,放上shader代码,需要注意的是,该shader需要开启DepthTextureMode,如果是deffered lightning则不需要手动开启,Forward lightning需要手动开启:“Camera.main.depthTextureMode = DepthTextureMode.Depth;”

另外,需要外部传送FogParam参数,FogParam.xyz代表Sphere center, FogParam.z 代表sphere radius,所以该shader不能独立使用,需要配合简单的脚本,脚本我就不放上了,不过我会在Xffect 1.2.3版本里加入完整的例子,包括免费版。

  1. //http://forum.unity3d.com/threads/142245-Xffect-Editor-Pro-powerful-tool-to-create-amazing-effects!
  2. Shader "Xffect/volume_fog" {
  3. Properties {
  4.     _FogColor ("Fog Color", Color) = (1,1,1,1)
  5. }
  6. Category {
  7.     Tags { "Queue"="Transparent+99" "IgnoreProjector"="True" "RenderType"="Transparent" }
  8.     Blend SrcAlpha OneMinusSrcAlpha
  9.     Cull Off Lighting Off ZWrite Off
  10.     ZTest Always
  11. SubShader {
  12.     Pass {
  13. CGPROGRAM
  14. #pragma target 3.0
  15. #pragma vertex vert
  16. #pragma fragment frag
  17. #include "UnityCG.cginc"
  18. float CalcVolumeFogIntensity(float3 sphereCenter, float sphereRadius, float3 cameraPosition, float3 viewDirection, float backDepth, float maxDistance, float density)
  19. {
  20.     float3 local = cameraPosition - sphereCenter;
  21.     float  fA      = dot(viewDirection, viewDirection);
  22.     float  fB      = 2 * dot(viewDirection, local);
  23.     float  fC      = dot(local, local) - sphereRadius * sphereRadius;
  24.     float  fD      = fB * fB - 4 * fA * fC;
  25.     if ( fD < 0.0f )
  26.         return 0;
  27.   
  28.   float recpTwoA = 0.5 / fA;
  29.   
  30.   float dist;
  31.   if (fD == 0.0f)
  32.   {
  33.     dist = backDepth;
  34.   }
  35.   else
  36.   {
  37.     float DSqrt = sqrt(fD);
  38.     dist = (-fB - DSqrt) * recpTwoA;
  39.   }
  40.   dist = min(dist, maxDistance);
  41.   backDepth = min(backDepth, maxDistance);
  42.   
  43.   float sample = dist;
  44.   float fog = 0;
  45.   float step_distance = ( backDepth - dist ) / 10;
  46.   for ( int seg = 0; seg < 10; seg++ )
  47.   {
  48.     float3 position = cameraPosition + viewDirection * sample;
  49.     fog += 1 - saturate( length( sphereCenter - position ) / sphereRadius );
  50.     sample += step_distance;
  51.   }
  52.   fog /= 10;
  53.   fog  = saturate( fog * density );
  54.   return fog;
  55. }
  56. fixed4 _FogColor;
  57. sampler2D _CameraDepthTexture;
  58. uniform float4 FogParam;
  59. struct v2f {
  60.     float4 pos : SV_POSITION;
  61.     float3 view : TEXCOORD0;
  62.     float4 projPos : TEXCOORD1;
  63. };
  64. v2f vert (appdata_base v)
  65. {
  66.     v2f o;
  67.     float4 wPos = mul (_Object2World, v.vertex);
  68.     o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
  69.     o.view = wPos.xyz - _WorldSpaceCameraPos;
  70.     o.projPos = ComputeScreenPos (o.pos);
  71.     // move projected z to near plane if point is behind near plane
  72.     float inFrontOf = ( o.pos.z / o.pos.w ) > 0;
  73.     o.pos.z *= inFrontOf;
  74.     return o;
  75. }
  76. half4 frag (v2f i) : COLOR
  77. {
  78.     half4 color = half4(1,1,1,1);
  79.     float depth = LinearEyeDepth (UNITY_SAMPLE_DEPTH(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos))));
  80.     float backDist = length(i.view);
  81.     float3 viewDir = normalize(i.view);
  82.     float fog = CalcVolumeFogIntensity(FogParam.xyz, FogParam.w, _WorldSpaceCameraPos, viewDir, backDist, depth,_FogColor.a);
  83.     
  84.     color.rgb = _FogColor.rgb;
  85.     color.a = fog;
  86.     return color;
  87. }
  88. ENDCG
  89.         }
  90.     }
  91. }
  92. Fallback "VertexLit"
  93. }

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有