-
Notifications
You must be signed in to change notification settings - Fork 3
/
Grass.vert
283 lines (234 loc) · 9.07 KB
/
Grass.vert
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
#define ATTENUATION
//#define HQ_ATTENUATION
#import "Common/ShaderLib/Skinning.glsllib"
uniform mat4 g_WorldViewProjectionMatrix;
uniform mat4 g_ViewProjectionMatrix;
uniform mat4 g_WorldViewMatrix;
uniform mat4 g_WorldMatrix;
uniform mat3 g_NormalMatrix;
uniform mat4 g_ViewMatrix;
uniform vec3 g_CameraPosition;
uniform float g_Time;
uniform vec4 m_Ambient;
uniform vec4 m_Diffuse;
uniform vec4 m_Specular;
uniform float m_Shininess;
uniform vec4 g_LightColor;
uniform vec4 g_LightPosition;
uniform vec4 g_AmbientLightColor;
varying vec2 texCoord;
#ifdef SEPARATE_TEXCOORD
varying vec2 texCoord2;
attribute vec2 inTexCoord2;
#endif
varying vec3 AmbientSum;
varying vec4 DiffuseSum;
varying vec3 SpecularSum;
varying float vDistance;
uniform sampler2D m_Noise;
uniform vec3 m_WorldOffset;
attribute vec3 inPosition;
attribute vec2 inTexCoord;
attribute vec3 inNormal;
varying vec3 lightVec;
//varying vec4 spotVec;
#ifdef VERTEX_COLOR
attribute vec4 inColor;
#endif
#ifndef VERTEX_LIGHTING
attribute vec4 inTangent;
#ifndef NORMALMAP
varying vec3 vNormal;
#endif
//varying vec3 vPosition;
varying vec3 vViewDir;
varying vec4 vLightDir;
#else
varying vec2 vertexLightValues;
uniform vec4 g_LightDirection;
#endif
#ifdef USE_REFLECTION
uniform vec3 g_CameraPosition;
uniform mat4 g_WorldMatrix;
uniform vec3 m_FresnelParams;
varying vec4 refVec;
/**
* Input:
* attribute inPosition
* attribute inNormal
* uniform g_WorldMatrix
* uniform g_CameraPosition
*
* Output:
* varying refVec
*/
void computeRef(in vec4 modelSpacePos){
vec3 worldPos = (g_WorldMatrix * modelSpacePos).xyz;
vec3 I = normalize( g_CameraPosition - worldPos ).xyz;
vec3 N = normalize( (g_WorldMatrix * vec4(inNormal, 0.0)).xyz );
refVec.xyz = reflect(I, N);
refVec.w = m_FresnelParams.x + m_FresnelParams.y * pow(1.0 + dot(I, N), m_FresnelParams.z);
}
#endif
// JME3 lights in world space
void lightComputeDir(in vec3 worldPos, in vec4 color, in vec4 position, out vec4 lightDir){
float posLight = step(0.5, color.w);
vec3 tempVec = position.xyz * sign(posLight - 0.5) - (worldPos * posLight);
lightVec = tempVec;
#ifdef ATTENUATION
float dist = length(tempVec);
lightDir.w = clamp(1.0 - position.w * dist * posLight, 0.0, 1.0);
lightDir.xyz = tempVec / vec3(dist);
#else
lightDir = vec4(normalize(tempVec), 1.0);
#endif
}
#ifdef VERTEX_LIGHTING
float lightComputeDiffuse(in vec3 norm, in vec3 lightdir){
return max(0.0, dot(norm, lightdir));
}
float lightComputeSpecular(in vec3 norm, in vec3 viewdir, in vec3 lightdir, in float shiny){
if (shiny <= 1.0){
return 0.0;
}
#ifndef LOW_QUALITY
vec3 H = (viewdir + lightdir) * vec3(0.5);
return pow(max(dot(H, norm), 0.0), shiny);
#else
return 0.0;
#endif
}
vec2 computeLighting(in vec3 wvPos, in vec3 wvNorm, in vec3 wvViewDir, in vec4 wvLightPos){
vec4 lightDir;
lightComputeDir(wvPos, g_LightColor, wvLightPos, lightDir);
float spotFallOff = 1.0;
if(g_LightDirection.w != 0.0){
vec3 L=normalize(lightVec.xyz);
vec3 spotdir = normalize(g_LightDirection.xyz);
float curAngleCos = dot(-L, spotdir);
float innerAngleCos = floor(g_LightDirection.w) * 0.001;
float outerAngleCos = fract(g_LightDirection.w);
float innerMinusOuter = innerAngleCos - outerAngleCos;
spotFallOff = clamp((curAngleCos - outerAngleCos) / innerMinusOuter, 0.0, 1.0);
}
float diffuseFactor = lightComputeDiffuse(wvNorm, lightDir.xyz);
float specularFactor = lightComputeSpecular(wvNorm, wvViewDir, lightDir.xyz, m_Shininess);
//specularFactor *= step(0.01, diffuseFactor);
return vec2(diffuseFactor, specularFactor) * vec2(lightDir.w)*spotFallOff;
}
#endif
void main(){
vec4 modelSpacePos = vec4(inPosition, 1.0);
vec3 modelSpaceNorm = inNormal;
#ifndef VERTEX_LIGHTING
vec3 modelSpaceTan = inTangent.xyz;
#endif
#ifdef NUM_BONES
#ifndef VERTEX_LIGHTING
Skinning_Compute(modelSpacePos, modelSpaceNorm, modelSpaceTan);
#else
Skinning_Compute(modelSpacePos, modelSpaceNorm);
#endif
#endif
// We plot the position of the grass vertexes based on the
// texture coordinates
//gl_Position = g_WorldViewProjectionMatrix * modelSpacePos;
texCoord = inTexCoord;
#ifdef SEPARATE_TEXCOORD
texCoord2 = inTexCoord2;
#endif
// Find the world location of the vertex. All three corners
// will have the same vertex.
vec3 wPos = (g_WorldMatrix * modelSpacePos).xyz;
vec2 groundPos = wPos.xz + m_WorldOffset.xz;
// We face the billboarded grass towards the camera's location
// instead of parallel to the screen. This keeps the blades from
// sliding around if we turn the camera.
vec3 cameraOffset = wPos - g_CameraPosition;
vDistance = length(cameraOffset);
vec3 cameraDir = cameraOffset / vDistance;
vec3 posOffset = normalize(vec3(-cameraDir.z, 0.0, cameraDir.x));
// The whole part of the x coordinate is the atlas cell.
// The fractional part says which corner this is.
// X fract() will be 0.25, 0.5, or 0.0
// Y will be 1 at x=0 and x=0.5 but 0 at x=0.25.
// I kept the decimal part small so that it could be safely
// extracted from the texture coordinate.
float texFract = fract(texCoord.x);
float offsetLength = (texFract * 2.0) - 0.5;
float texY = abs(offsetLength) * 2.0;
float normalProjectionLength = texY - 0.25;
float size = texCoord.y;
modelSpacePos.xyz += modelSpaceNorm * normalProjectionLength * size;
wPos = (g_WorldMatrix * modelSpacePos).xyz;
// Move the upper parts of the triangle along the camera-perpendicular
// vector (posOffset)
wPos += posOffset * offsetLength * size;
#ifdef USE_WIND
// some simple wind
vec4 noise = texture2D(m_Noise, vec2(groundPos.x * 0.01 + g_Time * 0.01, groundPos.y * 0.01));
//wPos.x += (noise.x * 0.5 - 0.25) * normalProjectionLength;
float strength = noise.y * 0.15 * size;
wPos.x += sin(g_Time * (1.0 + noise.x)) * normalProjectionLength * strength;
#endif
gl_Position = g_ViewProjectionMatrix * vec4(wPos, 1.0);
// Figure out the texture coordinate from the index
float index = texCoord.x - texFract;
float u = mod(index, 4.0);
float v = mod((index - u) * 0.25, 4.0);
texCoord.x = u * 0.25 + texFract * 0.5;
texCoord.y = v * 0.25 + texY * 0.25;
vec3 wvPosition = (g_WorldViewMatrix * modelSpacePos).xyz;
vec3 wvNormal = normalize(g_NormalMatrix * modelSpaceNorm);
vec3 viewDir = normalize(-wvPosition);
//vec4 lightColor = g_LightColor[gl_InstanceID];
//vec4 lightPos = g_LightPosition[gl_InstanceID];
//vec4 wvLightPos = (g_ViewMatrix * vec4(lightPos.xyz, lightColor.w));
//wvLightPos.w = lightPos.w;
vec4 wvLightPos = (g_ViewMatrix * vec4(g_LightPosition.xyz,clamp(g_LightColor.w,0.0,1.0)));
wvLightPos.w = g_LightPosition.w;
vec4 lightColor = g_LightColor;
#if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)
vec3 wvTangent = normalize(g_NormalMatrix * modelSpaceTan);
vec3 wvBinormal = cross(wvNormal, wvTangent);
mat3 tbnMat = mat3(wvTangent, wvBinormal * -inTangent.w,wvNormal);
//vPosition = wvPosition * tbnMat;
//vViewDir = viewDir * tbnMat;
vViewDir = -wvPosition * tbnMat;
lightComputeDir(wvPosition, lightColor, wvLightPos, vLightDir);
vLightDir.xyz = (vLightDir.xyz * tbnMat).xyz;
#elif !defined(VERTEX_LIGHTING)
vNormal = wvNormal;
//vPosition = wvPosition;
vViewDir = viewDir;
lightComputeDir(wvPosition, lightColor, wvLightPos, vLightDir);
#ifdef V_TANGENT
vNormal = normalize(g_NormalMatrix * inTangent.xyz);
vNormal = -cross(cross(vLightDir.xyz, vNormal), vNormal);
#endif
#endif
//computing spot direction in view space and unpacking spotlight cos
// spotVec = (g_ViewMatrix * vec4(g_LightDirection.xyz, 0.0) );
// spotVec.w = floor(g_LightDirection.w) * 0.001;
// lightVec.w = fract(g_LightDirection.w);
lightColor.w = 1.0;
#ifdef MATERIAL_COLORS
AmbientSum = (m_Ambient * g_AmbientLightColor).rgb;
DiffuseSum = m_Diffuse * lightColor;
SpecularSum = (m_Specular * lightColor).rgb;
#else
AmbientSum = vec3(0.2, 0.2, 0.2) * g_AmbientLightColor.rgb; // Default: ambient color is dark gray
DiffuseSum = lightColor;
SpecularSum = vec3(0.0);
#endif
#ifdef VERTEX_COLOR
AmbientSum *= inColor.rgb;
DiffuseSum *= inColor;
#endif
#ifdef VERTEX_LIGHTING
vertexLightValues = computeLighting(wvPosition, wvNormal, viewDir, wvLightPos);
#endif
#ifdef USE_REFLECTION
computeRef(modelSpacePos);
#endif
}