跳到主要内容
← Grass

Grass

Grass - More Blades

shader-learning 自学第 4 课:Grass - More Blades

实时渲染 · 网格 GLSL

第 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);
}