全局雾很简单,在unity里只需要一个选项即可,可是它不能控制局部地区的雾化效果。所以有”Volume Fog”这种shader,网上搜了很久,只有一个比较满意:
www.youtube.com/watch?v=HPo2gfy675o
,可是要卖50刀(站长看看有没有意愿团一个?~~)
算了,自己动手,再次硬着头皮上了,为此我还狠心买了《GPU Gems》全套,既然目前我都在研究游戏里的特效实现,不光是粒子系统,shader也是重要的组成部分,所以我决定以后也会在Xffect里多包含一些实用的shader,比如这次分享的Volume Fog。还有很早前就包含的“Heat Distortion”(热浪?)shader,这个是非常实用的,因为很多特效都有局部画面扭曲效果。
下面放2张截图,目前的体积雾只支持球体。
在fog外面看到的效果:
在fog里面看到的效果:
我的游戏项目里用到的效果:
=================================================================
好了,放上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版本里加入完整的例子,包括免费版。
复制代码
算了,自己动手,再次硬着头皮上了,为此我还狠心买了《GPU Gems》全套,既然目前我都在研究游戏里的特效实现,不光是粒子系统,shader也是重要的组成部分,所以我决定以后也会在Xffect里多包含一些实用的shader,比如这次分享的Volume Fog。还有很早前就包含的“Heat Distortion”(热浪?)shader,这个是非常实用的,因为很多特效都有局部画面扭曲效果。
下面放2张截图,目前的体积雾只支持球体。
在fog外面看到的效果:
在fog里面看到的效果:
我的游戏项目里用到的效果:
=================================================================
好了,放上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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
//http://forum.unity3d.com/threads/142245-Xffect-Editor-Pro-powerful-tool-to-create-amazing-effects!
Shader "Xffect/volume_fog" {
Properties {
_FogColor ("Fog Color", Color) = (1,1,1,1)
}
Category {
Tags { "Queue"="Transparent+99" "IgnoreProjector"="True" "RenderType"="Transparent" }
Blend SrcAlpha OneMinusSrcAlpha
Cull Off Lighting Off ZWrite Off
ZTest Always
SubShader {
Pass {
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
float CalcVolumeFogIntensity(float3 sphereCenter, float sphereRadius, float3 cameraPosition, float3 viewDirection, float backDepth, float maxDistance, float density)
{
float3 local = cameraPosition - sphereCenter;
float fA = dot(viewDirection, viewDirection);
float fB = 2 * dot(viewDirection, local);
float fC = dot(local, local) - sphereRadius * sphereRadius;
float fD = fB * fB - 4 * fA * fC;
if ( fD < 0.0f )
return 0;
float recpTwoA = 0.5 / fA;
float dist;
if (fD == 0.0f)
{
dist = backDepth;
}
else
{
float DSqrt = sqrt(fD);
dist = (-fB - DSqrt) * recpTwoA;
}
dist = min(dist, maxDistance);
backDepth = min(backDepth, maxDistance);
float sample = dist;
float fog = 0;
float step_distance = ( backDepth - dist ) / 10;
for ( int seg = 0; seg < 10; seg++ )
{
float3 position = cameraPosition + viewDirection * sample;
fog += 1 - saturate( length( sphereCenter - position ) / sphereRadius );
sample += step_distance;
}
fog /= 10;
fog = saturate( fog * density );
return fog;
}
fixed4 _FogColor;
sampler2D _CameraDepthTexture;
uniform float4 FogParam;
struct v2f {
float4 pos : SV_POSITION;
float3 view : TEXCOORD0;
float4 projPos : TEXCOORD1;
};
v2f vert (appdata_base v)
{
v2f o;
float4 wPos = mul (_Object2World, v.vertex);
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.view = wPos.xyz - _WorldSpaceCameraPos;
o.projPos = ComputeScreenPos (o.pos);
// move projected z to near plane if point is behind near plane
float inFrontOf = ( o.pos.z / o.pos.w ) > 0;
o.pos.z *= inFrontOf;
return o;
}
half4 frag (v2f i) : COLOR
{
half4 color = half4(1,1,1,1);
float depth = LinearEyeDepth (UNITY_SAMPLE_DEPTH(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos))));
float backDist = length(i.view);
float3 viewDir = normalize(i.view);
float fog = CalcVolumeFogIntensity(FogParam.xyz, FogParam.w, _WorldSpaceCameraPos, viewDir, backDist, depth,_FogColor.a);
color.rgb = _FogColor.rgb;
color.a = fog;
return color;
}
ENDCG
}
}
}
Fallback "VertexLit"
}
|