"use strict"; const Level0Theme = { key : "level_0", name: "Level 0 - The Lobby", shaders: { floor: { vertex: ` varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } `, fragment: ` varying vec2 vUv; float hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123); } void main() { vec3 col_base = vec3(0.55, 0.48, 0.32); vec3 col_dark = vec3(0.42, 0.36, 0.24); // Patrón tenue de moqueta húmeda float grain = hash(floor(vUv * 50.0)) * 0.15; vec3 color = mix(col_base, col_dark, grain); gl_FragColor = vec4(color, 1.0); } ` }, ceiling: { vertex: ` varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } `, fragment: ` varying vec2 vUv; float hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123); } void main() { vec2 panel_uv = fract(vUv); float border = step(0.02, panel_uv.x) * step(panel_uv.x, 0.98) * step(0.02, panel_uv.y) * step(panel_uv.y, 0.98); vec3 plate = vec3(0.82, 0.81, 0.77); vec3 grid = vec3(0.35, 0.35, 0.35); float speck = hash(floor(panel_uv * 100.0)) * 0.05; plate -= speck; gl_FragColor = vec4(mix(grid, plate, border), 1.0); } ` }, walls: { vertex: ` varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } `, fragment: ` varying vec2 vUv; float hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123); } void main() { vec3 col_yellow = vec3(0.76, 0.70, 0.42); vec3 col_dark = vec3(0.68, 0.62, 0.36); float stripe = sin(vUv.x * 31.4159) * 0.5 + 0.5; vec3 color = mix(col_yellow, col_dark, stripe * 0.12); // Zócalo inferior if(vUv.y < 0.12) { color = vec3(0.25, 0.22, 0.18); } float grain = hash(floor(vUv * 140.0)) * 0.05; color -= grain; gl_FragColor = vec4(color, 1.0); } ` }, frame: { vertex: ` varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } `, fragment: ` varying vec2 vUv; float hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123); } void main() { // Tono marco madera barnizada oscura / metal marrón de oficina vec3 col_base = vec3(0.24, 0.18, 0.14); vec3 col_grain = vec3(0.18, 0.13, 0.10); // Veteado suave alineado al marco float grain = hash(floor(vUv * vec2(15.0, 180.0))) * 0.12; vec3 color = mix(col_base, col_grain, grain); gl_FragColor = vec4(color, 1.0); } ` }, hole: { vertex: ` varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } `, fragment: ` varying vec2 vUv; float hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123); } void main() { // Hormigón oscuro / forjado de obra vec3 col_base = vec3(0.22, 0.20, 0.18); vec3 col_grain = vec3(0.14, 0.13, 0.12); float grain = hash(floor(vUv * 60.0)) * 0.25; vec3 color = mix(col_base, col_grain, grain); gl_FragColor = vec4(color, 1.0); } ` }, stair: { vertex: ` varying vec2 vUv; varying vec3 vNormal; void main() { vUv = uv; vNormal = normalize(normalMatrix * normal); gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } `, fragment: ` varying vec2 vUv; varying vec3 vNormal; float hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123); } void main() { // Acero gris oscuro con textura rayada en los peldaños vec3 base = vec3(0.22, 0.22, 0.23); vec3 edge = vec3(0.35, 0.35, 0.36); float stripes = sin(vUv.y * 120.0) * 0.05; float noise = hash(floor(vUv * 60.0)) * 0.06; vec3 col = mix(base, edge, abs(vNormal.y) * 0.25 + stripes + noise); gl_FragColor = vec4(col, 1.0); } ` }, elevator_cabin: { vertex: ` varying vec2 vUv; varying vec3 vNormal; varying vec3 vWorldPosition; void main() { vUv = uv; vNormal = normalize(normalMatrix * normal); vec4 worldPos = modelMatrix * vec4(position, 1.0); vWorldPosition = worldPos.xyz; gl_Position = projectionMatrix * viewMatrix * worldPos; } `, fragment: ` varying vec2 vUv; varying vec3 vNormal; varying vec3 vWorldPosition; float hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123); } void main() { // Acero cepillado con reflejos anisotrópicos simulados vec3 metal_dark = vec3(0.28, 0.28, 0.29); vec3 metal_light = vec3(0.48, 0.47, 0.46); float grain = hash(floor(vUv * vec2(40.0, 400.0))) * 0.08; float specular = pow(abs(dot(vNormal, vec3(0.0, 1.0, 0.0))), 2.0) * 0.15; vec3 col = mix(metal_dark, metal_light, grain + specular); gl_FragColor = vec4(col, 1.0); } ` }, elevator_light: { vertex: ` varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } `, fragment: ` varying vec2 vUv; void main() { // Luz blanca cálida fluorescente de tubo típico de oficina vec3 light_color = vec3(0.96, 0.94, 0.85); gl_FragColor = vec4(light_color * 1.4, 1.0); } ` }, } }