Sloped belts and filters drawn as one belt turned to 45° (t40)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
// Smooth slope shading, kept beside the shared CPU geometry in slope-belts.js.
|
||||
const SM_SLOPE_HELPERS = `
|
||||
// The same rounded strokes as slopeBeltShape; y/z carry distance along/across the band.
|
||||
vec3 slopeStroke(vec2 p, vec2 a, vec2 b, float origin) {
|
||||
vec2 ray = b - a; float len = length(ray); ray /= len;
|
||||
float along = dot(p - a, ray), across = dot(p - a, vec2(-ray.y, ray.x));
|
||||
vec2 q = abs(vec2(along - len * 0.5, across)) - vec2(len * 0.5 - 0.75, 1.1);
|
||||
float sd = length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - 0.75;
|
||||
return vec3(sd, origin + along, across + 2.0);
|
||||
}
|
||||
vec3 slopeCorner(vec2 p, vec2 a, float origin) {
|
||||
vec2 d = p - a; float radius = length(d);
|
||||
return vec3(radius - 1.85, origin + d.x, 2.0 + d.y);
|
||||
}
|
||||
vec3 slopeShape(vec2 p, vec2 worldOrigin, float grade, int joins) {
|
||||
float sy = grade < 0.0 ? 4.0 : 0.0;
|
||||
vec2 a = vec2(-grade * 1.30814755, sy + 1.30814755), b = vec2(4.0 - grade * 1.30814755, 4.0 - sy + 1.30814755);
|
||||
if ((joins & 1) != 0) { a.y = sy + 2.0; a.x = (a.y - sy - 2.61629509) / grade; }
|
||||
else if ((joins & 4) != 0) a -= vec2(4.0, grade * 4.0);
|
||||
if ((joins & 2) != 0) { b.y = 6.0 - sy; b.x = (b.y - sy - 2.61629509) / grade; }
|
||||
else if ((joins & 8) != 0) b += vec2(4.0, grade * 4.0);
|
||||
vec2 axis = vec2(1.0, grade) * 0.70710678;
|
||||
vec3 best = slopeStroke(p, a, b, dot(worldOrigin + a, axis));
|
||||
if ((joins & 1) != 0) {
|
||||
vec3 h = slopeStroke(p, vec2(-2.0, a.y), a, worldOrigin.x - 2.0);
|
||||
if (h.x < best.x) best = h;
|
||||
h = slopeCorner(p, a, worldOrigin.x + a.x);
|
||||
if (h.x < best.x) best = h;
|
||||
}
|
||||
if ((joins & 2) != 0) {
|
||||
vec3 h = slopeStroke(p, b, vec2(6, b.y), worldOrigin.x + b.x);
|
||||
if (h.x < best.x) best = h;
|
||||
h = slopeCorner(p, b, worldOrigin.x + b.x);
|
||||
if (h.x < best.x) best = h;
|
||||
}
|
||||
return best;
|
||||
}
|
||||
`;
|
||||
|
||||
const SM_SLOPE_DRAW = `
|
||||
// Slopes use the flat belt's band, rollers and mesh in coordinates along the run.
|
||||
if ((nc == 2 || (nc >= 23 && nc <= 30)) &&
|
||||
(int(cellAt(tTree, c).a * 255.0 + 0.5) & 128) != 0 &&
|
||||
cellAt(tTree, c).r * 255.0 >= 22.5 && cellAt(tTree, c).r * 255.0 <= 30.5) {
|
||||
int slopeClass = int(cellAt(tTree, c).r * 255.0 + 0.5);
|
||||
int shape = (slopeClass - 23) / 2;
|
||||
bool mesh = shape >= 2;
|
||||
float grade = (shape == 0 || shape == 2) ? -1.0 : 1.0;
|
||||
float dir = ((slopeClass - 23) % 2) == 1 ? 1.0 : -1.0;
|
||||
vec4 tag = cellAt(tTree, c);
|
||||
int joins = int(tag.a * 255.0 + 0.5);
|
||||
vec2 local = floor(tag.gb * 255.0 + 0.5) - 8.0 + fract(w);
|
||||
vec3 shapePos = slopeShape(local, w - local, grade, joins);
|
||||
float sd = shapePos.x, axis = shapePos.y, depth = shapePos.z;
|
||||
float time = (joins & 16) != 0 ? uTime : 0.0;
|
||||
vec2 lb = vec2(axis, depth), alongWorld = vec2(axis, depth);
|
||||
float rg = step(0.72, fract((axis - dir * (depth < 2.0 ? 1.0 : -1.0) * time * 30.0) * 0.5));
|
||||
vec3 belt;
|
||||
if (-sd < 0.8) {
|
||||
belt = bandColor(lb, rg);
|
||||
if (mesh && ((joins & 32) != 0) == (depth < 2.0) && dot(own.rgb, vec3(1)) > 0.01)
|
||||
belt = mix(belt, own.rgb * (depth < 2.0 ? 1.0 : 0.8), 0.75 * rg);
|
||||
belt *= mix(0.55, 1.0, smoothstep(0.0, max(px * 1.4, 0.12), -sd));
|
||||
} else if (mesh) {
|
||||
vec2 cg = abs(fract(alongWorld) - 0.5);
|
||||
float bw2 = max(px * 0.9, 0.09);
|
||||
float hole = 1.0 - smoothstep(0.5 - bw2 - px, 0.5 - bw2, max(cg.x, cg.y));
|
||||
vec3 steel = dot(own.rgb, vec3(1)) > 0.01 ? mix(vec3(0.42, 0.44, 0.5), own.rgb, 0.4) : vec3(0.42, 0.44, 0.5);
|
||||
belt = mix(steel * 0.78, C * 0.8, hole);
|
||||
} else {
|
||||
vec2 dv = vec2(mod(axis, 2.0) - 1.0, depth - 2.0);
|
||||
float rd = length(dv);
|
||||
belt = vec3(0.15, 0.16, 0.18);
|
||||
if (rd < 0.95) {
|
||||
float ang = atan(dv.y, dv.x) - dir * time * 30.0 / 0.95;
|
||||
float spoke = smoothstep(0.55, 0.85, cos(ang * 3.0));
|
||||
belt = mix(vec3(0.5, 0.36, 0.25), vec3(0.72, 0.53, 0.36), 0.5 + 0.5 * dot(normalize(dv + 1e-4), vec2(-0.6, -0.8)) * smoothstep(0.2, 0.95, rd));
|
||||
belt *= mix(1.0, 0.72, spoke * smoothstep(0.25, 0.4, rd));
|
||||
belt *= mix(1.0, 0.55, smoothstep(0.82, 0.95, rd));
|
||||
}
|
||||
}
|
||||
C = mix(C, belt, 1.0 - smoothstep(-px, px, sd));
|
||||
}
|
||||
`;
|
||||
Reference in New Issue
Block a user