第 4 课:Grass - More Blades
实现
uniform float iTime;
attribute int index;
vec3 bezier3D(vec3 p0, vec3 p1, vec3 p2, float t) {
float u = 1.0 - t;
float tt = t * t;
float uu = u * u;
vec3 p = uu * p0;
p += 2.0 * u * t * p1;
p += tt * p2;
return p;
}
vec2 random2(vec2 st){
float d1 = dot(st, vec2(12.3, 32.1));
float d2 = dot(st, vec2(45.6, 65.4));
st = vec2(d1, d2);
return fract(sin(st) * 78.9) * 2.0 - 1.0;
}
float random(float x) {
float r = fract(sin(x * 12.34) * 1234.5678);
return r * 2.0 - 1.0;
}
mat3 rotationYMatrix(float angle) {
float cosAngle = cos(angle);
float sinAngle = sin(angle);
return mat3(
vec3(cosAngle, 0, -sinAngle),
vec3(0, 1, 0),
vec3(sinAngle, 0, cosAngle)
);
}
void main() {
int instance = index / 40;
int localIndex = index % 20;
float h = float(localIndex / 2) / 9.0;
float sideX = mod(float(localIndex), 2.0) * 2.0 - 1.0;
float bend = sin(iTime+random(float(instance))*3.14) * 0.2 ;
vec3 curve = bezier3D(
vec3(0.0, 0.0, 0.0),
vec3(0.0, 0.5, 0.0),
vec3(0.0, cos(bend), sin(bend)),
h
);
float xzScale = 3.0;
vec2 xzRandom = random2(vec2(instance)) * xzScale;
mat3 rotationY = rotationYMatrix(random(float(instance))*3.14);
vec3 translationOffset = vec3(xzRandom.x,0.0,xzRandom.y);
vec3 pos = curve + vec3(sideX * mix(0.05, 0.0, h * h), 0.0, 0.0);
pos = rotationY * pos;
pos += translationOffset;
gl_Position = projectionMatrix * viewMatrix * vec4(pos, 1.0);
}