2 程序化生成地形算法设计
2.1 地形曲线的生成
2.1.1 初始化高度场
struct Make2DGridPrimitive : INode {virtual void apply() override {size_t nx = get_input<NumericObject>("nx")->get<int>();nx = std::max(nx, (size_t)1);size_t ny = has_input("ny") ?makepositive(get_input<NumericObject>("ny")->get<int>()) : 0;if (!ny) ny = nx;float dx = 1.f / std::max(nx - 1, (size_t)1);float dy = 1.f / std::max(ny - 1, (size_t)1);vec3f ax = has_input("sizeX") ?get_input<NumericObject>("sizeX")->get<vec3f>(): vec3f(1, 0, 0);vec3f ay = has_input("sizeY") ?get_input<NumericObject>("sizeY")->get<vec3f>(): vec3f(0, 1, 0);vec3f o = has_input("origin") ?get_input<NumericObject>("origin")->get<vec3f>() : vec3f(0);if (has_input("scale")) {auto obj = get_input<NumericObject>("scale");auto scale = obj->is<int>() ? obj->get<int>() : obj->get<float>();ax *= scale;ay *= scale;}auto dir = get_param<std::string>("Direction");if(dir == "YZ"){ax = zeno::vec3f(0,ax[0],0);ay = zeno::vec3f(0, 0, ay[1]);}if(dir == "XZ"){ay = zeno::vec3f(0,0,ay[1]);}if (get_param<bool>("isCentered"))o -= (ax + ay) / 2;ax *= dx; ay *= dy;auto prim = std::make_shared<PrimitiveObject>();prim->resize(nx * ny);auto &pos = prim->add_attr<vec3f>("pos");
#pragma omp parallel for collapse(2)for (intptr_t y = 0; y < ny; y++) for (intptr_t x = 0; x < nx; x++) {intptr_t index = y * nx + x;vec3f p = o + x * ax + y * ay;size_t i = x + y * nx;pos[i] = p;}if (get_param<bool>("hasFaces")) {prim->tris.resize((nx - 1) * (ny - 1) * 2);
#pragma omp parallel for collapse(2)for (intptr_t y = 0; y < ny-1; y++) for (intptr_t x = 0; x < nx-1; x++) {intptr_t index = y * (nx - 1) + x;prim->tris[index * 2][2] = y * nx + x;prim->tris[index * 2][1] = y * nx + x + 1;prim->tris[index * 2][0] = (y + 1) * nx + x + 1;prim->tris[index * 2 + 1][2] = (y + 1) * nx + x + 1;prim->tris[index * 2 + 1][1] = (y + 1) * nx + x;prim->tris[index * 2 + 1][0] = y * nx + x;}}prim->userData().set("nx", std::make_shared<NumericObject>((int)nx));//zhxxprim->userData().set("ny", std::make_shared<NumericObject>((int)ny));//zhxxset_output("prim", std::move(prim));}
};ZENDEFNODE(Make2DGridPrimitive,{ /* inputs: */ {{"int", "nx", "2"},{"int", "ny", "0"},{"vec3f", "sizeX", "1,0,0"},{"vec3f", "sizeY", "0,1,0"},{"float", "scale", "1"},{"vec3f", "origin", "0,0,0"},}, /* outputs: */ {{"PrimitiveObject", "prim"},}, /* params: */ {{"enum XZ XY YZ", "Direction", "XZ"}, // zhxxhappy{"bool", "isCentered", "0"},{"bool", "hasFaces", "1"},}, /* category: */ {"primitive",}});
2.1.2 原始几何体投影到高度场
2.1.3 创建低精度版的高度场
2.1.4 把造型采样到低精度高度场,并做平滑处理
2.1.5 平滑后的数据采样回高精度的高度场
2.2 地形变形处理
2.2.1 Curl Noise 变形处理
2.2.2 整体 Hybrid Noise 变形
2.2.3 初始化地形数据,并标记边界,为侵蚀处理做谁备
2.3 地形侵蚀
2.3.1 地表稳固
2.3.2 热侵蚀
2.3.3 崩塌
2.3.4 降水
2.3.5 崩塌 + 水侵蚀
2.3.6 蒸发