← Nature3D assetfogon/matas-de-pasto
Mata de pasto
Drag to turn it// «Mata de pasto» · gpt-6-sol (medium)
// A clump of tall grass blades in 3 shades of green, spiky and wild, growing from one spot.
// A single swaying clump of chunky, tapered grass blades.
part("grass", [24, 24, 0]);
const greens = ["#238d3d", "#32ad47", "#54ce53"];
const sunlit = "#77de66";
// Each blade grows from the same small patch, then bends outward.
const blades = [
// angle, height, outward reach, width, shade
[ 0, 29, 17, 2.4, 1], [ 22, 34, 15, 2.0, 2],
[ 43, 26, 18, 2.5, 1], [ 63, 32, 16, 2.1, 0],
[ 83, 25, 18, 2.6, 2], [105, 35, 14, 2.0, 1],
[125, 28, 17, 2.4, 2], [146, 33, 16, 2.1, 0],
[167, 27, 18, 2.5, 1], [188, 31, 17, 2.2, 2],
[210, 25, 18, 2.5, 0], [231, 34, 15, 2.0, 1],
[252, 28, 18, 2.3, 2], [273, 32, 17, 2.2, 1],
[295, 26, 18, 2.4, 0], [316, 35, 15, 2.0, 2],
[339, 28, 18, 2.5, 1],
// Taller, more upright blades give the center its spiky crown.
[ 12, 39, 8, 2.0, 2], [ 74, 37, 9, 1.8, 1],
[137, 40, 7, 1.9, 2], [196, 37, 10, 2.0, 1],
[258, 39, 8, 1.8, 0], [321, 38, 9, 1.9, 2]
];
// Dense, irregular little base rather than a separate pot or soil mound.
ellipsoid(24, 24, 1, 5, 5, 2, greens[0]);
ellipsoid(24, 24, 2, 4, 4, 2, greens[1]);
for (const [degrees, height, reach, width, shade] of blades) {
const a = degrees * Math.PI / 180;
const dx = Math.cos(a), dy = Math.sin(a);
const sideX = -dy, sideY = dx;
const offset = (rand() - 0.5) * 2;
for (let z = 1; z <= height; z++) {
const t = z / height;
const bend = reach * Math.pow(t, 1.65);
const sideways = offset * (1 - t) + Math.sin(t * Math.PI) * 0.8;
const cx = 24 + dx * bend + sideX * sideways;
const cy = 24 + dy * bend + sideY * sideways;
// Broad lower leaves, narrowing steadily into a sharp one-block tip.
const halfWidth = Math.max(0.4, width * (1 - Math.pow(t, 1.5)));
const halfThickness = t > 0.84 ? 0.45 : 0.85;
for (let u = -Math.ceil(halfWidth); u <= Math.ceil(halfWidth); u++) {
for (let v = -1; v <= 1; v++) {
if ((u * u) / (halfWidth * halfWidth + 0.15) +
(v * v) / (halfThickness * halfThickness + 0.15) > 1.2) continue;
let color = greens[shade];
if (v === -1 || (u > 0 && t > 0.35)) color = greens[2];
if (t > 0.72 && v <= 0 && (z + u) % 3 !== 0) color = sunlit;
if (t < 0.2 && v > 0) color = greens[0];
set(
Math.round(cx + sideX * u + dx * v),
Math.round(cy + sideY * u + dy * v),
z,
color
);
}
}
}
}
animate("grass", { type: "swing", axis: "y", speed: 1.6, amplitude: 0.12 });import { draw } from "./assets/voxel";
import { matasDePasto } from "./assets/matas-de-pasto";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, matasDePasto, x, y, { size: 64, angle: 0, t: performance.now() / 1000 });
// size: its longest side, in px
// angle: turn on the floor, in radians
// t: seconds; if it moves, that animates it# In a terminal, in the game's folder
fogon assets add matas-de-pasto
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["matas-de-pasto"] })
# It lands in client/assets/matas-de-pasto.ts
# https://fogon.page/object/matas-de-pasto