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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
[require]
GLSL >= 1.30
[fragment shader]
#version 130
#define saturate(x) clamp(x,0.0,1.0)
#define lerp mix
#define COUNT 40
#define FIRST_PASS
#line 52
uniform sampler2D Base;
uniform sampler2D Bump;
uniform sampler3D Fog;
uniform sampler3D LightMap;
varying vec2 texCoord;
varying vec3 lVec;
varying vec3 vVec;
varying vec3 dir;
varying vec3 fogCrd;
varying vec3 shadowCrd;
uniform float fogStart;
uniform vec3 shadowStart;
uniform vec4 fogScaleBias;
uniform vec3 shadowScale, shadowBias;
void main(){
const vec3 fogColor = vec3(0.9, 1.0, 0.8);
const float fogDensity = 0.005;
float n = fogDensity * length(dir);
vec3 fogCoord = fogCrd;
vec3 shadowCoord = shadowCrd;
#ifdef FIRST_PASS
// Regular per pixel lighting
float atten = 1.0 / (1.0 + 0.000001 * dot(lVec, lVec));
vec3 lightVec = normalize(lVec);
vec3 viewVec = normalize(vVec);
vec3 base = texture2D(Base, texCoord).rgb;
vec3 normal = normalize(texture2D(Bump, texCoord).xyz * 2.0 - 1.0);
float diffuse = saturate(dot(lightVec, normal));
float specular = pow(saturate(dot(reflect(-viewVec, normal), lightVec)), 16.0);
float shadow = texture3D(LightMap, shadowCrd).x;
vec3 lighting = atten * shadow * (diffuse * base + 0.5 * specular) + 0.14 * base;
#else
// For later passes, continue the fog computation where we stopped last pass
fogCoord += fogStart * dir;
shadowCoord += shadowStart * dir;
#endif
float a = 1.0;
float b = 0.0;
// Volumetric fog computation
for (int i = 0; i < COUNT; i++){
fogCoord += fogScaleBias.w * dir;
shadowCoord += shadowScale * dir;
float fog = texture3D(Fog, fogCoord).x;
float shadow = texture3D(LightMap, shadowCoord).x;
// Compute weighting factors. This implements the commented out lerp more efficiently.
float x = 1.0 - fog * n;
a *= x;
b = lerp(shadow, b, x);
}
#ifdef FIRST_PASS
gl_FragColor.rgb = lighting * a + fogColor * b;
#else
// "lighting" is in the framebuffer, so we use alpha blending to multiply it with "a".
gl_FragColor.rgb = b * fogColor;
gl_FragColor.a = a;
#endif
}
[vertex shader]
#version 130
#define saturate(x) clamp(x,0.0,1.0)
#define lerp mix
#define COUNT 40
#define FIRST_PASS
#line 2
uniform mat4 mvp;
uniform vec3 lightPos;
uniform vec3 camPos;
attribute vec2 textureCoord;
attribute vec3 tangent;
attribute vec3 binormal;
attribute vec3 normal;
varying vec2 texCoord;
varying vec3 lVec;
varying vec3 vVec;
varying vec3 dir;
varying vec3 fogCrd;
varying vec3 shadowCrd;
uniform vec4 fogScaleBias;
uniform vec3 shadowScale, shadowBias;
void main(){
gl_Position = mvp * gl_Vertex;
vec3 viewVec = camPos - gl_Vertex.xyz;
#ifdef FIRST_PASS
texCoord = textureCoord;
vec3 lightVec = lightPos - gl_Vertex.xyz;
lVec.x = dot(lightVec, tangent);
lVec.y = dot(lightVec, binormal);
lVec.z = dot(lightVec, normal);
vVec.x = dot(viewVec, tangent);
vVec.y = dot(viewVec, binormal);
vVec.z = dot(viewVec, normal);
#endif
dir = viewVec / 40.0;
fogCrd = gl_Vertex.xyz * fogScaleBias.w + fogScaleBias.xyz;
shadowCrd = gl_Vertex.xyz * shadowScale + shadowBias;
}
|