feat(gioser): luna con textura rica + terminador curvo, auras anchas, overlay nubes
Luna (FS_CHACANA::render_moon):
- Normales esféricas reales: nx=p.x/R, ny=p.y/R, nz=sqrt(1-nx²-ny²).
- Terminador CURVO: dot(normal, sun_dir) donde sun_dir gira en el plano
X-Z según la fase. Resultado: la frontera luz/sombra es una elipse
proyectada en pantalla, como en la luna real (no una vertical recta).
- Fase lineal: phi = fract(t/40) * 2π cicla new→first-q→full→last-q→new
en ~40s.
- Limb darkening realista: pow(nz, 0.45) — bordes más oscuros que el
centro (el regolito lunar dispersa).
- 6 capas de textura:
maria_n (escala 4.5) → mares oscuros (smoothstep 0.42..0.60)
craters_mid (escala 13) → cráteres grandes
craters_small (escala 28) → cráteres chicos
fine (escala 55) → granularidad del terreno
micro (escala 110) → polvo
ring_mid + ring_small → crests via pow(abs(n-0.5)*2, k) → bordes
elevados de cráteres
Albedo final: 0.80 + craters±0.32 + small±0.22 + fine±0.20 + micro±0.10
+ rings (+0.22, +0.16) - maria 0.50, clamp [0.10, 1.15].
Auras elementales (FS_CHACANA::element_cloud):
- sigma_along 0.42 → 0.62 (más reach hacia afuera)
- sigma_perp 0.34 → 0.62 (mucho más ancho perpendicular)
- cloud_center offset 0.22 → 0.28 (más lejos del centro)
- multiplier 0.28 → 0.26 (compensa intensidad por la mayor cobertura)
- Resultado: las nubes elementales se solapan en las esquinas NE/NW/SE/SW
y mezclan colores. El cuadrante entero respira el color del cardinal.
Overlay clouds (FS_OVERLAY_CLOUDS — nuevo shader):
- Tercer pase tras chacana, fullscreen quad.
- blend = SRC_ALPHA / ONE_MINUS_SRC_ALPHA (compositing normal, no aditivo)
→ las nubes COMPONEN sobre la escena en lugar de sumar luz.
- Dos capas FBM (escalas 0.55 y 1.30) con parallax inverso del mouse
(-0.05 y -0.09) — se sienten "delante" del cosmos.
- Drift más lento que las nubes del cosmos (0.020 vs 0.055), para que se
perciban como otra capa atmosférica.
- smoothstep(0.55..0.88, 0.50..0.82) → sólo crestas se vuelven nube;
mucho del viewport queda transparente.
- Alpha máximo 0.10 — "apenas visible" como pidió el diseño.
- Color mix gris→blanco-azul según densidad local.
Renderer (gioser-canvas-web):
- Nuevo Program overlay_prog con uniforms u_resolution/u_time/u_parallax.
- render() ahora hace 3 pases: cosmos → chacana → overlay clouds.
Workspace verde.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,8 @@ use gioser_geom::ChacanaSpec;
|
||||
use gioser_palette::{cosmos, Rgb};
|
||||
use gioser_physics::{SpringDamper1, SpringDamper2};
|
||||
use gioser_shaders::{
|
||||
chacana_quad, FS_CHACANA, FS_COSMOS, FULLSCREEN_QUAD, VS_CHACANA, VS_FULLSCREEN,
|
||||
chacana_quad, FS_CHACANA, FS_COSMOS, FS_OVERLAY_CLOUDS, FULLSCREEN_QUAD, VS_CHACANA,
|
||||
VS_FULLSCREEN,
|
||||
};
|
||||
use glam::{Mat4, Vec3, Vec4};
|
||||
use std::collections::HashMap;
|
||||
@@ -80,6 +81,7 @@ pub struct Renderer {
|
||||
gl: GL,
|
||||
cosmos_prog: Program,
|
||||
chacana_prog: Program,
|
||||
overlay_prog: Program,
|
||||
cosmos_vao: WebGlVertexArrayObject,
|
||||
chacana_vao: WebGlVertexArrayObject,
|
||||
chacana_quad_count: i32,
|
||||
@@ -244,6 +246,14 @@ impl Renderer {
|
||||
)
|
||||
.map_err(JsValue::from)?;
|
||||
|
||||
let overlay_prog = Program::new(
|
||||
&gl,
|
||||
VS_FULLSCREEN,
|
||||
FS_OVERLAY_CLOUDS,
|
||||
&["u_resolution", "u_time", "u_parallax"],
|
||||
)
|
||||
.map_err(JsValue::from)?;
|
||||
|
||||
let (cosmos_vao, _) = upload_quad(&gl, &FULLSCREEN_QUAD, 0).map_err(JsValue::from)?;
|
||||
let chacana_quad_verts = chacana_quad(chacana.arm_extent());
|
||||
let (chacana_vao, chacana_quad_count) =
|
||||
@@ -258,6 +268,7 @@ impl Renderer {
|
||||
gl,
|
||||
cosmos_prog,
|
||||
chacana_prog,
|
||||
overlay_prog,
|
||||
cosmos_vao,
|
||||
chacana_vao,
|
||||
chacana_quad_count,
|
||||
@@ -500,6 +511,23 @@ impl Renderer {
|
||||
}
|
||||
gl.bind_vertex_array(Some(&self.chacana_vao));
|
||||
gl.draw_arrays(GL::TRIANGLES, 0, self.chacana_quad_count);
|
||||
|
||||
// ---- Capa overlay de nubes (apenas visible, encima de todo) ----
|
||||
// blend normal alpha — las nubes COMPONEN sobre la escena, no suman luz.
|
||||
gl.blend_func(GL::SRC_ALPHA, GL::ONE_MINUS_SRC_ALPHA);
|
||||
gl.use_program(Some(&self.overlay_prog.program));
|
||||
if let Some(u) = self.overlay_prog.u("u_resolution") {
|
||||
gl.uniform2f(Some(u), self.viewport.0 as f32, self.viewport.1 as f32);
|
||||
}
|
||||
if let Some(u) = self.overlay_prog.u("u_time") {
|
||||
gl.uniform1f(Some(u), t);
|
||||
}
|
||||
if let Some(u) = self.overlay_prog.u("u_parallax") {
|
||||
gl.uniform2f(Some(u), self.mouse.0, self.mouse.1);
|
||||
}
|
||||
gl.bind_vertex_array(Some(&self.cosmos_vao));
|
||||
gl.draw_arrays(GL::TRIANGLES, 0, 6);
|
||||
|
||||
gl.bind_vertex_array(None);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user