aboutsummaryrefslogtreecommitdiffhomepage
path: root/public/bluebey-studio/src/hats.js
diff options
context:
space:
mode:
Diffstat (limited to 'public/bluebey-studio/src/hats.js')
-rw-r--r--public/bluebey-studio/src/hats.js29
1 files changed, 21 insertions, 8 deletions
diff --git a/public/bluebey-studio/src/hats.js b/public/bluebey-studio/src/hats.js
index 3fb65f3..7a54c46 100644
--- a/public/bluebey-studio/src/hats.js
+++ b/public/bluebey-studio/src/hats.js
@@ -32,6 +32,19 @@ const sphere = (r, w = 24, h = 16, phiStart = 0, phiLength = Math.PI * 2, thetaS
);
const box = (w, h, d) => new THREE.BoxGeometry(w, h, d);
+/**
+ * The 線画 fill a part takes, as how far it steps from the paper towards the ink
+ * (see `addMesh` in src/styles.js). Every hat part already gets the light default
+ * tone, but two parts of the *same* hat then come out the same shade - so a part
+ * that sits flush on another (a band on a crown) loses its seam. Tagging it with
+ * a darker tone puts that seam back, without touching リアル / フラット, where the
+ * part's own colour already draws it.
+ */
+function tone(mesh, strength) {
+ mesh.userData.tone = strength;
+ return mesh;
+}
+
/** シルクハット: a tall black crown, a narrow band and a flat brim. */
function buildSilk() {
const group = new THREE.Group();
@@ -39,7 +52,7 @@ function buildSilk() {
const band = material('#3a2f4a');
add(group, cylinder(1.52, 1.52, 0.12, 32), black, 0, 0.06, 0);
add(group, cylinder(1.00, 1.04, 1.62, 32), black, 0, 0.93, 0);
- add(group, cylinder(1.05, 1.05, 0.24, 32), band, 0, 0.30, 0);
+ tone(add(group, cylinder(1.05, 1.05, 0.24, 32), band, 0, 0.30, 0), 0.34);
return group;
}
@@ -51,12 +64,12 @@ function buildCap() {
// The crown: a hemisphere whose flat face sits on y = 0.
const crown = add(group, sphere(1.08, 28, 18, 0, Math.PI * 2, 0, Math.PI / 2), blue, 0, 0, 0);
crown.scale.set(1, 0.92, 1);
- add(group, cylinder(1.10, 1.10, 0.18, 28), dark, 0, 0.09, 0);
+ tone(add(group, cylinder(1.10, 1.10, 0.18, 28), dark, 0, 0.09, 0), 0.30);
// The bill, tipped down a little at the front.
- const bill = add(group, cylinder(0.86, 0.86, 0.09, 24), dark, 0, 0.06, 0.92);
+ const bill = tone(add(group, cylinder(0.86, 0.86, 0.09, 24), dark, 0, 0.06, 0.92), 0.30);
bill.scale.set(1, 1, 1.25);
bill.rotation.x = -0.12;
- add(group, sphere(0.13, 12, 10), dark, 0, 1.02, 0);
+ tone(add(group, sphere(0.13, 12, 10), dark, 0, 1.02, 0), 0.30);
return group;
}
@@ -67,7 +80,7 @@ function buildChef() {
const shade = material('#e6e3da');
// The band: a tall cylinder that sits on the head.
add(group, cylinder(0.86, 0.92, 0.95, 28), white, 0, 0.475, 0);
- add(group, cylinder(0.90, 0.90, 0.10, 28), shade, 0, 0.90, 0);
+ tone(add(group, cylinder(0.90, 0.90, 0.10, 28), shade, 0, 0.90, 0), 0.26);
// The crown: a big squashed sphere ringed with lobes, so the top reads as the
// classic pleated toque rather than a plain dome.
const puff = add(group, sphere(1.24, 26, 20), white, 0, 1.30, 0);
@@ -90,12 +103,12 @@ function buildFire() {
const gold = material('#f0c24a', { metalness: 0.4, roughness: 0.4 });
const dome = add(group, sphere(1.06, 28, 18, 0, Math.PI * 2, 0, Math.PI / 2), red, 0, 0, 0);
dome.scale.set(1, 0.95, 1);
- const brim = add(group, cylinder(1.34, 1.34, 0.12, 28), dark, 0, 0.06, 0.18);
+ const brim = tone(add(group, cylinder(1.34, 1.34, 0.12, 28), dark, 0, 0.06, 0.18), 0.28);
brim.scale.set(1, 1, 1.1);
// The ridge along the top, front to back.
- const crest = add(group, box(0.16, 0.42, 1.5), dark, 0, 1.02, 0);
+ const crest = tone(add(group, box(0.16, 0.42, 1.5), dark, 0, 1.02, 0), 0.28);
crest.rotation.x = -0.05;
- add(group, sphere(0.2, 14, 12), gold, 0, 0.62, 1.02);
+ tone(add(group, sphere(0.2, 14, 12), gold, 0, 0.62, 1.02), 0.22);
return group;
}