feat(gioser): ciclo sol↔luna↔tierra, auras anchas, nuevo set Software/Quién Soy/Manifiesto/Mística
Shader (gioser-shaders):
- 3 cuerpos centrales renderizados realísticamente con interpolación
gradual entre ellos (cross-fade smoothstep):
- render_sun: núcleo gauss + corona pulsante + textura de plasma FBM
(boiling surface).
- render_moon: disco con limb darkening, cráteres + mares (2 octavas
de fbm), terminador móvil (fase lunar), halo azulado en el limb
iluminado.
- render_earth: disco con continentes fbm (rotación lenta), polos
blancos, nubes en otra capa, día/noche en hemisferio iluminado,
halo atmosférico azul (Rayleigh simplificado).
- Uniforms u_body_a, u_body_b (int 0/1/2), u_body_blend (float).
- Cuerpo central se calcula sólo si inside > 0.001 (perf — saltea pixels
fuera de la superficie de la chacana).
- radial_mult atenúa los rayos cuando luna/tierra están activos — el sol
es el único que irradia tan intensamente.
- element_cloud(): aura ancha por cardinal (sigma_along=0.42,
sigma_perp=0.34) con textura fbm animada y modulación por elemento.
- AIRE: corrientes suaves que ondulan horizontalmente.
- FUEGO: lengüetazos rápidos con flicker.
- TIERRA: densidad sólida con variación lenta.
- AGUA: ondulaciones grandes que viajan hacia afuera.
Las nubes cubren todo el cuadrante del cardinal, no solo la punta.
- Helper functions vnoise_c + fbm_c agregadas (necesarias para superficies
realistas de luna/tierra y para nubes elementales).
Renderer (gioser-canvas-web):
- body_state(t) -> (body_a, body_b, blend) state machine:
- BODY_PHASE_SECS = 45 (≈10 pulsos del sol antes de transicionar).
- BODY_TRANSITION_SECS = 4 (cross-fade gradual).
- Total cycle: 147s = sol 45s → trans 4s → luna 45s → trans 4s → tierra 45s → trans 4s.
- Smoothstep cubic en el blend para curva natural (no linear).
- Sube u_body_a/b como int (uniform1i) y u_body_blend como float.
App + contenido:
- index.html: nuevos labels en los 4 tips
- NORTE (aire): SOFTWARE / Tecnología
- ESTE (fuego): QUIÉN SOY / Bitácora
- SUR (tierra): MANIFIESTO / Invariantes
- OESTE (agua): MÍSTICA / Espiritualidad
- Íconos SVG nuevos relacionados al tema:
- aire: chip de circuito con nodos y conexiones
- fuego: libro abierto con líneas
- tierra: hexagrama dentro de círculo (sacred geometry / invariante)
- agua: ojo en triángulo (mística)
- gioser-web src/lib.rs: ensure_page_dom usa nuevos title+tag por elemento.
- 4 md/*.md reescritos con contenido seed para los nuevos temas, con
manifiesto explícito en tierra.md.
Workspace verde + 21 tests.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -31,6 +31,16 @@ const COT_HALF_FOV: f32 = 2.414_213_5;
|
||||
/// con `FS_CHACANA::ringR_main` del shader.
|
||||
const RING_FACTOR: f32 = 1.45;
|
||||
|
||||
/// Duración en segundos de cada "cuerpo central" (sol / luna / tierra)
|
||||
/// antes de empezar a transicionar al siguiente. ~45 s = ~10 pulsos del
|
||||
/// sol (`sin(t*1.4)` período ≈ 4.5 s).
|
||||
const BODY_PHASE_SECS: f32 = 45.0;
|
||||
/// Duración del cross-fade entre cuerpos. Más alto = transiciones más
|
||||
/// graduales.
|
||||
const BODY_TRANSITION_SECS: f32 = 4.0;
|
||||
/// Cantidad de cuerpos en el ciclo: sol(0), luna(1), tierra(2).
|
||||
const BODY_COUNT: i32 = 3;
|
||||
|
||||
/// Identidad de cada cardinal (id, color de acento, label). Orden `[N, E, S, W]`.
|
||||
pub mod tips {
|
||||
use gioser_palette::{elements, Rgb};
|
||||
@@ -227,6 +237,9 @@ impl Renderer {
|
||||
"u_agua_color",
|
||||
"u_zodiac[0]",
|
||||
"u_sun_pulse",
|
||||
"u_body_a",
|
||||
"u_body_b",
|
||||
"u_body_blend",
|
||||
],
|
||||
)
|
||||
.map_err(JsValue::from)?;
|
||||
@@ -475,6 +488,16 @@ impl Renderer {
|
||||
if let Some(u) = self.chacana_prog.u("u_sun_pulse") {
|
||||
gl.uniform1f(Some(u), self.sun_pulse);
|
||||
}
|
||||
let (body_a, body_b, blend) = body_state(t);
|
||||
if let Some(u) = self.chacana_prog.u("u_body_a") {
|
||||
gl.uniform1i(Some(u), body_a);
|
||||
}
|
||||
if let Some(u) = self.chacana_prog.u("u_body_b") {
|
||||
gl.uniform1i(Some(u), body_b);
|
||||
}
|
||||
if let Some(u) = self.chacana_prog.u("u_body_blend") {
|
||||
gl.uniform1f(Some(u), blend);
|
||||
}
|
||||
gl.bind_vertex_array(Some(&self.chacana_vao));
|
||||
gl.draw_arrays(GL::TRIANGLES, 0, self.chacana_quad_count);
|
||||
gl.bind_vertex_array(None);
|
||||
@@ -486,3 +509,29 @@ fn upload_rgb(gl: &GL, loc: Option<&WebGlUniformLocation>, c: Rgb) {
|
||||
gl.uniform3f(Some(u), c.0, c.1, c.2);
|
||||
}
|
||||
}
|
||||
|
||||
/// Devuelve `(body_a, body_b, blend)` para el tiempo `t` (segundos).
|
||||
/// El ciclo es sol → luna → tierra → sol → ... cada uno estable por
|
||||
/// `BODY_PHASE_SECS` y con `BODY_TRANSITION_SECS` de cross-fade al
|
||||
/// siguiente.
|
||||
fn body_state(t: f32) -> (i32, i32, f32) {
|
||||
let slot = BODY_PHASE_SECS + BODY_TRANSITION_SECS;
|
||||
let cycle = slot * BODY_COUNT as f32;
|
||||
let pt = t.rem_euclid(cycle).max(0.0);
|
||||
let mut acc = 0.0_f32;
|
||||
for i in 0..BODY_COUNT {
|
||||
let stable_end = acc + BODY_PHASE_SECS;
|
||||
if pt < stable_end {
|
||||
return (i, i, 0.0);
|
||||
}
|
||||
let trans_end = stable_end + BODY_TRANSITION_SECS;
|
||||
if pt < trans_end {
|
||||
let blend = ((pt - stable_end) / BODY_TRANSITION_SECS).clamp(0.0, 1.0);
|
||||
// Smoothstep para una curva más natural que linear lerp.
|
||||
let s = blend * blend * (3.0 - 2.0 * blend);
|
||||
return (i, (i + 1) % BODY_COUNT, s);
|
||||
}
|
||||
acc = trans_end;
|
||||
}
|
||||
(0, 0, 0.0)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user