Building generator for four-tiles texture sheets with basement, regular and top floor facades as well as roof tiles.
Random points positions get mapped pair-wise as corners to a grid.
vector pos[] = detail(1, 'positions', 0);
i@group_footprint = 0;
foreach(int i; vector p; pos){
int n = (i + 1) % len(pos);
int prs[] = primfind(0, p, pos[n]);
int index = find(prs, i@primnum);
if(index >= 0){
i@group_footprint = 1;
break;
}
}
The facades are build from a sweep node that also outputs primrow numbers to define basement, regular and top levels.
The roof geometry is created using the polyexpand node with its edgedist attribute mapped to the roof's elevation. The texture coordinates are constructed around on the primitives center position and normal direction.
vector up = {0,1,0};
vector nml = normalize(prim_normal(0, i@primnum, 0.0, 0.0));
vector tang = normalize(up - dot(nml, up) * nml);
vector bitang = normalize(cross(-nml, tang));
vector pos_rel = v@P - prim(0, 'P', i@primnum);
float u = dot(pos_rel, bitang);
float v = dot(pos_rel, tang);
v@uv = set(u, v, 0.0);
The textures get mapped into quarters to match the tiled texture map. Primitive faces are unitized and offset based on their groups.
// UNITIZE
v@uv[0] = vertexprimindex(0, @vtxnum) == 0 || vertexprimindex(0, @vtxnum) == 3;
v@uv[1] = vertexprimindex(0, @vtxnum) == 2 || vertexprimindex(0, @vtxnum) == 3;
// QUARTER
v@uv *= 0.5;
// OFFSETS
if(inprimgroup(0, 'regular', i@primnum)){
v@uv[0] += 0.5;
}
else if(inprimgroup(0, 'top', i@primnum)){
v@uv[1] += 0.5;
}
After fusing the facade and roof meshes the texture gets applied. Randomly generating new building variants only takes milliseconds.
Hand painted texture created exclusively by Omar Faruq Tawsif.
Portfolio: https://www.artstation.com/omartawsif