New SR_LIVE sandbox scene: CharacterVisual composited in a 3D greybox world derived from server snapshots. Per-leg constant-velocity interpolation keyed to the stance throttle, 'server feet / client eyes' facing (wire octant while moving, client aim octant idle), cadence-synced gait state machine on AnimationPlayer custom blends, D-148 orthographic follow camera (-30deg default, T-cycle presets), sim-space grid shader, camera-side wall cutaway, accumulating never-evict tile store with four-state visibility tint. Additive seams only: InputMapper.facing_angle_provider (2D path unchanged), CharacterVisual.play_animation blend_time param + get_animation_player(). Visual harness gains per-scenario scene field + SR_AUTOPILOT input scripting. 210 new gdUnit assertions across five suites; verified live (230/230 total, clean smoke, screenshot at .cache/screenshots/locomotion_idle_live.png). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
56 lines
2.6 KiB
Plaintext
56 lines
2.6 KiB
Plaintext
shader_type spatial;
|
|
render_mode diffuse_lambert, specular_disabled;
|
|
|
|
// T-1088 greybox floor (design §3.3) — sandbox-only.
|
|
//
|
|
// Per-instance visibility tint x world-space grid lines. The MultiMesh instance
|
|
// color (use_colors, GreyboxWorld) arrives as the COLOR built-in and multiplies
|
|
// albedo: white = Forward, 85% = Peripheral, 70% = BoundaryWall, dim cool grey =
|
|
// Remembered (SandboxConstants.TINTS — §3.2).
|
|
//
|
|
// Grid: data is per-0.5 m subtile (D-066/D-222) but the floor must READ as 1 m
|
|
// visual tiles (2x2 subtiles) — minor lines every 0.5 m (alpha 0.15), major
|
|
// lines every 1.0 m (alpha 0.45). Lines are sampled in SIM space (u_sim_from_world
|
|
// undoes the 45 deg WorldRoot rotation) so they land on tile edges; sampling raw
|
|
// world space would draw the grid rotated 45 deg against the tiles. Continuous
|
|
// across instances because sim space is shared. D-243's "voxel = 1 m" is
|
|
// generation-cascade vocabulary — the 1 m visual tile exists ONLY as the major
|
|
// lines here (§2).
|
|
|
|
uniform vec3 u_base_albedo : source_color = vec3(0.52, 0.54, 0.58);
|
|
uniform vec3 u_line_albedo : source_color = vec3(0.10, 0.11, 0.14);
|
|
uniform float u_minor_spacing_m = 0.5;
|
|
uniform float u_major_spacing_m = 1.0;
|
|
uniform float u_minor_alpha = 0.15;
|
|
uniform float u_major_alpha = 0.45;
|
|
uniform float u_line_half_width_m = 0.02;
|
|
// World -> sim-space transform; set by GreyboxWorld from its own inverse global
|
|
// transform so the grid rotates WITH the tiles under the WorldRoot 45 deg.
|
|
uniform mat4 u_sim_from_world = mat4(1.0);
|
|
|
|
varying vec2 v_world_xz;
|
|
|
|
void vertex() {
|
|
// MODEL_MATRIX folds in the per-instance MultiMesh transform (incl. WorldRoot
|
|
// rotation); u_sim_from_world undoes the scene rotation back to sim axes.
|
|
v_world_xz = (u_sim_from_world * MODEL_MATRIX * vec4(VERTEX, 1.0)).xz;
|
|
}
|
|
|
|
// 1.0 on a grid line of the given spacing, 0.0 off it, one-fwidth AA edge.
|
|
float line_mask(vec2 p, float spacing, float half_width) {
|
|
vec2 dxy = abs(fract(p / spacing + 0.5) - 0.5) * spacing; // metres to nearest line
|
|
float d = min(dxy.x, dxy.y);
|
|
float aa = fwidth(d);
|
|
return 1.0 - smoothstep(half_width - aa, half_width + aa, d);
|
|
}
|
|
|
|
void fragment() {
|
|
float minor = line_mask(v_world_xz, u_minor_spacing_m, u_line_half_width_m) * u_minor_alpha;
|
|
float major = line_mask(v_world_xz, u_major_spacing_m, u_line_half_width_m) * u_major_alpha;
|
|
float line_a = max(minor, major); // major wins where the grids coincide
|
|
vec3 tinted = u_base_albedo * COLOR.rgb;
|
|
// Line color is tinted too, so remembered/peripheral tiles keep dim lines.
|
|
ALBEDO = mix(tinted, u_line_albedo * COLOR.rgb, line_a);
|
|
ROUGHNESS = 1.0;
|
|
}
|