Newer
Older
using namespace cgp;
// Evaluate 3D position of the terrain for any (x,y)
float evaluate_terrain_height(float x, float y)
//p, h, sigma -> positions, heights and wideness of bell curves
vec2 p[] = { {-10, -10}, {5, 5}, {-3, 4}, {6, 4} };
float h[] = { 3.0f, -1.5f, 1.0f, 2.0f };
float sigma[] = { 10.0f, 3.0f, 4.0f, 4.0f };
float z = 0;
for (int i = 0; i < 4; i++) {
float d = norm(vec2(x, y) - p[i]) / sigma[i];
z += h[i] * std::exp(-d * d);
}
parameters.terrain_height = terrain_length()/10;
parameters.octave = 9;
parameters.frequency_gain = 2.4;
parameters.persistency = 0.33;
float perlin_noise = parameters.terrain_height * noise_perlin(vec2(3*x / terrain_length(), 3 * y / terrain_length()), parameters.octave, parameters.persistency, parameters.frequency_gain);
{
mesh terrain; // temporary terrain storage (CPU only)
terrain.position.resize(N*N);
terrain.uv.resize(N * N);
parameters.terrain_height = terrain_length()*6/250;
parameters.persistency = 0.26;
float perlin_noise;
// Fill terrain geometry
for(int ku=0; ku<N; ++ku)
{
for(int kv=0; kv<N; ++kv)
{
// Compute local parametric coordinates (u,v) \in [0,1]
float u = ku/(N-1.0f);
float v = kv/(N-1.0f);
// Compute the real coordinates (x,y) of the terrain in [-terrain_length/2, +terrain_length/2]
float x = (u - 0.5f) * terrain_length();
float y = (v - 0.5f) * terrain_length();
// Compute the surface height function at the given sampled coordinate
float z = evaluate_terrain_height(x,y);
// Store vertex coordinates
terrain.position[kv+N*ku] = {x,y,z};
terrain.uv[kv+N*ku] = {x,y};
perlin_noise = parameters.terrain_height * noise_perlin(vec2(3 * x / terrain_length(), 3 * y / terrain_length()), parameters.octave, parameters.persistency, parameters.frequency_gain);
float b = std::min(1.0, exp((z + perlin_noise - terrain_length()/10 + 5) / 2) / exp(6));
terrain.color[kv + N * ku] = std::max(0.0f,(1-b))*vec3(0,0.3f,0) + b * 1.5 * vec3(1, 1, 1);
}
}
// Generate triangle organization
// Parametric surface with uniform grid sampling: generate 2 triangles for each grid cell
for(int ku=0; ku<N-1; ++ku)
{
for(int kv=0; kv<N-1; ++kv)
{
unsigned int idx = kv + N*ku; // current vertex offset
uint3 triangle_1 = {idx, idx+1+N, idx+1};
uint3 triangle_2 = {idx, idx+N, idx+1+N};
terrain.connectivity.push_back(triangle_1);
terrain.connectivity.push_back(triangle_2);
}
}
// need to call this function to fill the other buffer with default values (normal, color, etc)
terrain.fill_empty_field();
return terrain;
}
std::vector<cgp::vec3> generate_positions_on_terrain(int N) {
for (int i = 0; i < N; i++) {
x = rand_interval(-d, d);
y = rand_interval(-d, d);
rand_pos.push_back({ x,y, evaluate_terrain_height(x, y) });