<?phpnamespace App\Service;use JumPHP\Kernel\Engine;/** * The glow of the whole picture: a post-processing shader (OpenGL on the desktop, WebGL in the browser) that makes * what is bright bleed light around it (flames, halos, the exit, lava), with a soft colour grade. Option "bloom", off by default: it also makes texts and buttons bleed. * Without a GL context (headless tests) nothing happens: the game looks the same, without the bloom. */final class Effects{ private const BLOOM = <<<'GLSL' vec3 glow(vec2 uv) { vec3 c = texture2D(u_frame, uv).rgb; float l = max(c.r, max(c.g, c.b)); return c * smoothstep(0.55, 1.0, l); } void main() { vec2 px = 1.0 / u_resolution; float s = max(1.0, u_viewport.z / max(1.0, u_view.x)); vec3 c = texture2D(u_frame, v_uv).rgb; vec3 b = vec3(0.0); for (int i = 0; i < 8; i++) { float a = 0.7854 * float(i); vec2 d = vec2(cos(a), sin(a)) * px * s; b += glow(v_uv + d * 1.6) * 0.9 + glow(v_uv + d * 3.6) * 0.6 + glow(v_uv + d * 6.5) * 0.35; } c += b * 0.055; c = mix(c, c * c * (3.0 - 2.0 * c), 0.25); gl_FragColor = vec4(c, 1.0); } GLSL; private ?bool $on = null; public function isOn(Engine $engine): bool { return (bool)$engine->options->get('bloom', false); } public function available(Engine $engine): bool { return $engine->gl()->isAvailable(); } /** Puts the shader on or off as the option says (call from enter()). */ public function apply(Engine $engine): void { $want = $this->isOn($engine) && $this->available($engine); if ($this->on === $want) { return; } $this->on = $want; $engine->gl()->setPostShader($want ? self::BLOOM : null); } public function toggle(Engine $engine): void { $engine->options->set('bloom', !$this->isOn($engine)); $this->apply($engine); }}