@poolzin/pool-bot 2026.1.38 → 2026.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/chrome-extension/README.md +3 -3
- package/assets/chrome-extension/background.js +5 -5
- package/assets/chrome-extension/manifest.json +3 -3
- package/assets/chrome-extension/options.html +4 -4
- package/assets/chrome-extension/options.js +1 -1
- package/dist/acp/client.js +3 -3
- package/dist/acp/types.js +1 -1
- package/dist/agents/agent-paths.js +3 -3
- package/dist/agents/auth-profiles/paths.js +3 -3
- package/dist/agents/cli-runner/helpers.js +1 -1
- package/dist/agents/cli-runner.js +2 -2
- package/dist/agents/cloudflare-ai-gateway.js +31 -0
- package/dist/agents/compaction.js +16 -2
- package/dist/agents/context-window-guard.js +13 -10
- package/dist/agents/context.js +4 -4
- package/dist/agents/docs-path.js +1 -1
- package/dist/agents/minimax-vlm.js +1 -1
- package/dist/agents/model-auth.js +12 -1
- package/dist/agents/model-catalog.js +4 -4
- package/dist/agents/model-selection.js +10 -4
- package/dist/agents/models-config.js +3 -3
- package/dist/agents/models-config.providers.js +147 -39
- package/dist/agents/pi-embedded-helpers/openai.js +1 -1
- package/dist/agents/pi-embedded-runner/compact.js +8 -8
- package/dist/agents/pi-embedded-runner/model.js +2 -2
- package/dist/agents/pi-embedded-runner/run/attempt.js +6 -6
- package/dist/agents/pi-embedded-runner/run.js +4 -4
- package/dist/agents/pi-embedded-runner/tool-result-truncation.js +275 -0
- package/dist/agents/pi-embedded-runner/utils.js +1 -1
- package/dist/agents/pi-model-discovery.js +10 -0
- package/dist/agents/pi-tool-definition-adapter.js +50 -9
- package/dist/agents/pi-tools.before-tool-call.js +67 -0
- package/dist/agents/pi-tools.js +10 -5
- package/dist/agents/pi-tools.read.js +2 -2
- package/dist/agents/session-file-repair.js +83 -0
- package/dist/agents/session-transcript-repair.js +68 -0
- package/dist/agents/skills/frontmatter.js +1 -1
- package/dist/agents/skills/workspace.js +2 -2
- package/dist/agents/system-prompt.js +28 -4
- package/dist/agents/together-models.js +127 -0
- package/dist/agents/tool-images.js +1 -1
- package/dist/agents/tool-policy.js +1 -1
- package/dist/agents/tools/browser-tool.js +3 -3
- package/dist/agents/tools/image-tool.js +2 -2
- package/dist/agents/tools/memory-tool.js +94 -7
- package/dist/agents/tools/web-search.js +1 -1
- package/dist/agents/workspace.js +1 -5
- package/dist/auto-reply/commands-registry.data.js +1 -1
- package/dist/auto-reply/reply/commands-context-report.js +2 -2
- package/dist/auto-reply/reply/commands-session.js +2 -2
- package/dist/auto-reply/reply/get-reply-run.js +14 -4
- package/dist/auto-reply/reply/groups.js +1 -1
- package/dist/auto-reply/reply/inbound-context.js +4 -0
- package/dist/auto-reply/reply/inbound-meta.js +130 -0
- package/dist/auto-reply/reply/untrusted-context.js +15 -0
- package/dist/auto-reply/status.js +1 -1
- package/dist/browser/client-fetch.js +1 -1
- package/dist/browser/config.js +1 -1
- package/dist/browser/extension-relay.js +3 -3
- package/dist/browser/server-context.js +2 -2
- package/dist/build-info.json +3 -3
- package/dist/canvas-host/a2ui.js +3 -3
- package/dist/channels/plugins/agent-tools/whatsapp-login.js +1 -17
- package/dist/channels/plugins/catalog.js +2 -2
- package/dist/channels/plugins/onboarding/imessage.js +1 -1
- package/dist/channels/plugins/onboarding/signal.js +1 -1
- package/dist/channels/plugins/onboarding/slack.js +4 -4
- package/dist/channels/plugins/onboarding/whatsapp.js +3 -3
- package/dist/channels/plugins/pairing-message.js +1 -1
- package/dist/cli/browser-cli-extension.js +2 -2
- package/dist/cli/docs-cli.js +1 -1
- package/dist/cli/gateway-cli/dev.js +1 -1
- package/dist/cli/memory-cli.js +25 -15
- package/dist/cli/nodes-cli/register.canvas.js +1 -1
- package/dist/cli/plugins-cli.js +1 -1
- package/dist/cli/run-main.js +2 -2
- package/dist/cli/security-cli.js +1 -1
- package/dist/cli/tagline.js +1 -1
- package/dist/cli/update-cli.js +4 -4
- package/dist/cli/webhooks-cli.js +5 -5
- package/dist/commands/agents.commands.add.js +1 -1
- package/dist/commands/auth-choice.apply.api-providers.js +305 -17
- package/dist/commands/auth-choice.apply.js +4 -1
- package/dist/commands/auth-choice.apply.plugin-provider.js +2 -2
- package/dist/commands/auth-choice.apply.xai.js +63 -0
- package/dist/commands/auth-choice.preferred-provider.js +7 -1
- package/dist/commands/configure.wizard.js +1 -1
- package/dist/commands/dashboard.js +1 -1
- package/dist/commands/docs.js +1 -1
- package/dist/commands/doctor-gateway-services.js +3 -3
- package/dist/commands/doctor-state-integrity.js +2 -14
- package/dist/commands/doctor-update.js +3 -3
- package/dist/commands/doctor.js +1 -1
- package/dist/commands/models/list.probe.js +2 -2
- package/dist/commands/models/list.registry.js +4 -4
- package/dist/commands/models/list.status-command.js +2 -2
- package/dist/commands/onboard-auth.config-core.js +366 -28
- package/dist/commands/onboard-auth.credentials.js +71 -9
- package/dist/commands/onboard-auth.js +3 -3
- package/dist/commands/onboard-auth.models.js +26 -24
- package/dist/commands/onboard-non-interactive/local/auth-choice.js +140 -6
- package/dist/commands/status-all/report-lines.js +1 -1
- package/dist/commands/status.command.js +1 -1
- package/dist/commands/uninstall.js +3 -3
- package/dist/compat/legacy-names.js +1 -1
- package/dist/config/io.js +3 -3
- package/dist/config/schema.js +1 -1
- package/dist/config/types.js +0 -1
- package/dist/config/types.memory.js +1 -0
- package/dist/config/version.js +4 -4
- package/dist/config/zod-schema.js +0 -6
- package/dist/daemon/constants.js +7 -7
- package/dist/daemon/inspect.js +6 -6
- package/dist/daemon/systemd-unit.js +1 -1
- package/dist/discord/monitor/message-handler.process.js +6 -4
- package/dist/gateway/client.js +0 -14
- package/dist/gateway/live-image-probe.js +1 -66
- package/dist/gateway/openai-http.js +2 -2
- package/dist/gateway/openresponses-http.js +4 -4
- package/dist/gateway/server-discovery.js +2 -2
- package/dist/gateway/server-http.js +1 -1
- package/dist/gateway/server.impl.js +2 -6
- package/dist/hooks/frontmatter.js +1 -1
- package/dist/hooks/hooks-status.js +1 -1
- package/dist/hooks/install.js +2 -2
- package/dist/hooks/loader.js +1 -1
- package/dist/hooks/workspace.js +3 -3
- package/dist/index.js +2 -2
- package/dist/infra/bonjour.js +3 -3
- package/dist/infra/path-env.js +3 -3
- package/dist/infra/provider-usage.fetch.minimax.js +1 -1
- package/dist/infra/restart.js +1 -1
- package/dist/infra/tailscale.js +1 -1
- package/dist/macos/relay.js +2 -2
- package/dist/media/input-files.js +1 -1
- package/dist/media/mime.js +4 -0
- package/dist/media/png-encode.js +74 -0
- package/dist/media-understanding/providers/image.js +2 -2
- package/dist/memory/backend-config.js +207 -0
- package/dist/memory/embeddings.js +1 -1
- package/dist/memory/index.js +0 -5
- package/dist/memory/manager.js +3 -25
- package/dist/memory/types.js +1 -0
- package/dist/node-host/runner.js +2 -2
- package/dist/pairing/pairing-messages.js +1 -1
- package/dist/plugins/discovery.js +1 -1
- package/dist/plugins/install.js +2 -2
- package/dist/plugins/update.js +1 -1
- package/dist/security/audit.js +2 -2
- package/dist/shared/text/reasoning-tags.js +52 -7
- package/dist/slack/monitor/message-handler/prepare.js +10 -4
- package/dist/slack/monitor/slash.js +10 -4
- package/dist/tailscale/detect.js +146 -0
- package/dist/telegram/bot-message-context.js +1 -1
- package/dist/test-helpers/workspace.js +11 -0
- package/dist/test-utils/channel-plugins.js +82 -0
- package/dist/test-utils/ports.js +73 -0
- package/dist/utils/shell-argv.js +61 -0
- package/dist/utils.js +10 -0
- package/dist/web/qr-image.js +1 -61
- package/dist/wizard/onboarding.finalize.js +7 -7
- package/dist/wizard/onboarding.js +3 -3
- package/docs/RELEASE_WORKFOTS_COMPARISON.md +3 -3
- package/docs/_config.yml +2 -2
- package/docs/_layouts/default.html +9 -9
- package/docs/concepts/typebox.md +1 -1
- package/docs/docs.json +1 -1
- package/docs/northflank.mdx +7 -7
- package/docs/railway.mdx +3 -3
- package/docs/render.mdx +5 -5
- package/docs/start/lore.md +2 -2
- package/extensions/bluebubbles/index.ts +2 -2
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/bluebubbles/src/accounts.ts +8 -8
- package/extensions/bluebubbles/src/actions.test.ts +22 -22
- package/extensions/bluebubbles/src/actions.ts +5 -5
- package/extensions/bluebubbles/src/attachments.ts +2 -2
- package/extensions/bluebubbles/src/channel.ts +16 -16
- package/extensions/bluebubbles/src/chat.ts +2 -2
- package/extensions/bluebubbles/src/media-send.ts +2 -2
- package/extensions/bluebubbles/src/monitor.test.ts +46 -46
- package/extensions/bluebubbles/src/monitor.ts +5 -5
- package/extensions/bluebubbles/src/onboarding.ts +7 -7
- package/extensions/bluebubbles/src/reactions.ts +2 -2
- package/extensions/bluebubbles/src/send.ts +2 -2
- package/extensions/copilot-proxy/README.md +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/diagnostics-otel/index.ts +2 -2
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/diagnostics-otel/src/service.ts +3 -3
- package/extensions/discord/index.ts +2 -2
- package/extensions/discord/package.json +1 -1
- package/extensions/google-antigravity-auth/README.md +1 -1
- package/extensions/google-antigravity-auth/index.ts +1 -1
- package/extensions/google-antigravity-auth/package.json +1 -1
- package/extensions/google-gemini-cli-auth/README.md +1 -1
- package/extensions/google-gemini-cli-auth/oauth.ts +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/googlechat/index.ts +3 -3
- package/extensions/googlechat/package.json +1 -1
- package/extensions/googlechat/src/accounts.ts +8 -8
- package/extensions/googlechat/src/actions.ts +6 -6
- package/extensions/googlechat/src/channel.ts +21 -21
- package/extensions/googlechat/src/monitor.ts +8 -8
- package/extensions/googlechat/src/onboarding.ts +10 -10
- package/extensions/imessage/index.ts +2 -2
- package/extensions/imessage/package.json +1 -1
- package/extensions/line/index.ts +2 -2
- package/extensions/line/package.json +1 -1
- package/extensions/line/src/card-command.ts +2 -2
- package/extensions/line/src/channel.logout.test.ts +4 -4
- package/extensions/line/src/channel.sendPayload.test.ts +8 -8
- package/extensions/line/src/channel.ts +3 -3
- package/extensions/llm-task/README.md +3 -3
- package/extensions/llm-task/index.ts +2 -2
- package/extensions/llm-task/package.json +1 -1
- package/extensions/llm-task/src/llm-task-tool.ts +4 -4
- package/extensions/lobster/README.md +6 -6
- package/extensions/lobster/index.ts +2 -2
- package/extensions/lobster/src/lobster-tool.test.ts +4 -4
- package/extensions/lobster/src/lobster-tool.ts +2 -2
- package/extensions/matrix/index.ts +2 -2
- package/extensions/matrix/package.json +1 -1
- package/extensions/matrix/src/matrix/client/config.ts +1 -1
- package/extensions/matrix/src/matrix/monitor/handler.ts +1 -1
- package/extensions/matrix/src/onboarding.ts +1 -1
- package/extensions/mattermost/index.ts +2 -2
- package/extensions/mattermost/package.json +1 -1
- package/extensions/mattermost/src/mattermost/accounts.ts +8 -8
- package/extensions/mattermost/src/mattermost/monitor-helpers.ts +5 -5
- package/extensions/mattermost/src/mattermost/monitor.ts +2 -2
- package/extensions/mattermost/src/onboarding-helpers.ts +3 -3
- package/extensions/mattermost/src/onboarding.ts +2 -2
- package/extensions/memory-core/index.ts +2 -2
- package/extensions/memory-core/package.json +1 -4
- package/extensions/memory-lancedb/index.ts +3 -3
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/msteams/index.ts +2 -2
- package/extensions/msteams/package.json +1 -1
- package/extensions/msteams/src/channel.directory.test.ts +2 -2
- package/extensions/msteams/src/channel.ts +2 -2
- package/extensions/msteams/src/graph-upload.ts +4 -4
- package/extensions/msteams/src/monitor-handler.ts +2 -2
- package/extensions/msteams/src/monitor.ts +2 -2
- package/extensions/msteams/src/onboarding.ts +9 -9
- package/extensions/msteams/src/reply-dispatcher.ts +2 -2
- package/extensions/msteams/src/send-context.ts +2 -2
- package/extensions/msteams/src/send.ts +4 -4
- package/extensions/nextcloud-talk/index.ts +2 -2
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nextcloud-talk/src/channel.ts +7 -7
- package/extensions/nextcloud-talk/src/inbound.ts +7 -7
- package/extensions/nextcloud-talk/src/onboarding.ts +1 -1
- package/extensions/nostr/README.md +2 -2
- package/extensions/nostr/index.ts +5 -5
- package/extensions/nostr/package.json +1 -1
- package/extensions/nostr/src/types.ts +4 -4
- package/extensions/open-prose/index.ts +2 -2
- package/extensions/qwen-portal-auth/README.md +1 -1
- package/extensions/signal/index.ts +2 -2
- package/extensions/signal/package.json +1 -1
- package/extensions/slack/index.ts +2 -2
- package/extensions/slack/package.json +1 -1
- package/extensions/telegram/index.ts +2 -2
- package/extensions/telegram/package.json +1 -1
- package/extensions/telegram/src/channel.ts +2 -2
- package/extensions/tlon/README.md +2 -2
- package/extensions/tlon/index.ts +2 -2
- package/extensions/tlon/package.json +1 -1
- package/extensions/tlon/src/channel.ts +13 -13
- package/extensions/tlon/src/monitor/index.ts +3 -3
- package/extensions/tlon/src/onboarding.ts +3 -3
- package/extensions/tlon/src/types.ts +3 -3
- package/extensions/twitch/README.md +1 -1
- package/extensions/twitch/index.ts +2 -2
- package/extensions/twitch/package.json +1 -1
- package/extensions/twitch/src/config.ts +3 -3
- package/extensions/twitch/src/monitor.ts +3 -3
- package/extensions/twitch/src/onboarding.ts +9 -9
- package/extensions/twitch/src/outbound.test.ts +2 -2
- package/extensions/twitch/src/plugin.test.ts +2 -2
- package/extensions/twitch/src/plugin.ts +8 -8
- package/extensions/twitch/src/send.test.ts +2 -2
- package/extensions/twitch/src/send.ts +4 -4
- package/extensions/twitch/src/token.test.ts +8 -8
- package/extensions/twitch/src/token.ts +3 -3
- package/extensions/twitch/src/twitch-client.ts +3 -3
- package/extensions/twitch/src/types.ts +3 -3
- package/extensions/twitch/src/utils/markdown.ts +1 -1
- package/extensions/voice-call/README.md +3 -3
- package/extensions/voice-call/package.json +1 -1
- package/extensions/voice-call/src/core-bridge.ts +2 -2
- package/extensions/voice-call/src/response-generator.ts +1 -1
- package/extensions/whatsapp/index.ts +2 -2
- package/extensions/whatsapp/package.json +1 -1
- package/extensions/zalo/README.md +1 -1
- package/extensions/zalo/index.ts +2 -2
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalo/src/accounts.ts +8 -8
- package/extensions/zalo/src/actions.ts +4 -4
- package/extensions/zalo/src/channel.directory.test.ts +2 -2
- package/extensions/zalo/src/channel.ts +18 -18
- package/extensions/zalo/src/monitor.ts +9 -9
- package/extensions/zalo/src/monitor.webhook.test.ts +2 -2
- package/extensions/zalo/src/onboarding.ts +24 -24
- package/extensions/zalo/src/send.ts +2 -2
- package/extensions/zalouser/README.md +2 -2
- package/extensions/zalouser/index.ts +2 -2
- package/extensions/zalouser/package.json +1 -1
- package/extensions/zalouser/src/accounts.ts +9 -9
- package/extensions/zalouser/src/channel.ts +24 -24
- package/extensions/zalouser/src/monitor.ts +4 -4
- package/extensions/zalouser/src/onboarding.ts +28 -28
- package/package.json +13 -250
- package/skills/nano-banana-pro/scripts/generate_image.py +1 -1
- package/skills/tmux/scripts/find-sessions.sh +1 -1
- package/CHANGELOG.md +0 -200
- package/README-header.png +0 -0
- package/git-hooks/pre-commit +0 -4
- package/scripts/format-staged.js +0 -148
- package/scripts/postinstall.js +0 -300
- package/scripts/setup-git-hooks.js +0 -96
- package/skills/webgpu-threejs-tsl/REFERENCE.md +0 -283
- package/skills/webgpu-threejs-tsl/SKILL.md +0 -91
- package/skills/webgpu-threejs-tsl/docs/compute-shaders.md +0 -404
- package/skills/webgpu-threejs-tsl/docs/core-concepts.md +0 -453
- package/skills/webgpu-threejs-tsl/docs/materials.md +0 -353
- package/skills/webgpu-threejs-tsl/docs/post-processing.md +0 -434
- package/skills/webgpu-threejs-tsl/docs/wgsl-integration.md +0 -324
- package/skills/webgpu-threejs-tsl/examples/basic-setup.js +0 -87
- package/skills/webgpu-threejs-tsl/examples/custom-material.js +0 -170
- package/skills/webgpu-threejs-tsl/examples/earth-shader.js +0 -292
- package/skills/webgpu-threejs-tsl/examples/particle-system.js +0 -259
- package/skills/webgpu-threejs-tsl/examples/post-processing.js +0 -199
- package/skills/webgpu-threejs-tsl/templates/compute-shader.js +0 -305
- package/skills/webgpu-threejs-tsl/templates/webgpu-project.js +0 -276
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Earth Shader Example
|
|
3
|
-
*
|
|
4
|
-
* Complete procedural Earth with:
|
|
5
|
-
* - Day/night texture blending
|
|
6
|
-
* - Atmospheric glow (fresnel)
|
|
7
|
-
* - Cloud layer
|
|
8
|
-
* - City lights at night
|
|
9
|
-
* - Bump mapping
|
|
10
|
-
*
|
|
11
|
-
* Based on Three.js webgpu_tsl_earth example (MIT License)
|
|
12
|
-
* https://github.com/mrdoob/three.js
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import * as THREE from 'three/webgpu';
|
|
16
|
-
import {
|
|
17
|
-
Fn,
|
|
18
|
-
If,
|
|
19
|
-
float,
|
|
20
|
-
vec2,
|
|
21
|
-
vec3,
|
|
22
|
-
vec4,
|
|
23
|
-
color,
|
|
24
|
-
uniform,
|
|
25
|
-
texture,
|
|
26
|
-
uv,
|
|
27
|
-
time,
|
|
28
|
-
mix,
|
|
29
|
-
smoothstep,
|
|
30
|
-
pow,
|
|
31
|
-
clamp,
|
|
32
|
-
normalize,
|
|
33
|
-
dot,
|
|
34
|
-
max,
|
|
35
|
-
positionWorld,
|
|
36
|
-
normalWorld,
|
|
37
|
-
normalLocal,
|
|
38
|
-
cameraPosition,
|
|
39
|
-
bumpMap
|
|
40
|
-
} from 'three/tsl';
|
|
41
|
-
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
|
|
42
|
-
|
|
43
|
-
let camera, scene, renderer, controls;
|
|
44
|
-
let earth, clouds, atmosphere;
|
|
45
|
-
|
|
46
|
-
// Uniforms
|
|
47
|
-
const sunDirection = uniform(new THREE.Vector3(1, 0.2, 0.5).normalize());
|
|
48
|
-
const atmosphereDayColor = uniform(new THREE.Color(0x4db2ff));
|
|
49
|
-
const atmosphereTwilightColor = uniform(new THREE.Color(0xbd5f1b));
|
|
50
|
-
const cloudSpeed = uniform(0.01);
|
|
51
|
-
const cityLightIntensity = uniform(1.5);
|
|
52
|
-
|
|
53
|
-
async function init() {
|
|
54
|
-
// Camera
|
|
55
|
-
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100);
|
|
56
|
-
camera.position.set(0, 0, 4);
|
|
57
|
-
|
|
58
|
-
// Scene
|
|
59
|
-
scene = new THREE.Scene();
|
|
60
|
-
scene.background = new THREE.Color(0x000011);
|
|
61
|
-
|
|
62
|
-
// Load textures
|
|
63
|
-
const loader = new THREE.TextureLoader();
|
|
64
|
-
|
|
65
|
-
// Note: Replace with actual texture paths
|
|
66
|
-
const earthDayTexture = loader.load('textures/earth_day.jpg');
|
|
67
|
-
const earthNightTexture = loader.load('textures/earth_night.jpg');
|
|
68
|
-
const earthCloudsTexture = loader.load('textures/earth_clouds.jpg');
|
|
69
|
-
const earthBumpTexture = loader.load('textures/earth_bump.jpg');
|
|
70
|
-
|
|
71
|
-
// Set texture properties
|
|
72
|
-
[earthDayTexture, earthNightTexture, earthCloudsTexture, earthBumpTexture].forEach((tex) => {
|
|
73
|
-
tex.colorSpace = THREE.SRGBColorSpace;
|
|
74
|
-
tex.wrapS = THREE.RepeatWrapping;
|
|
75
|
-
tex.wrapT = THREE.ClampToEdgeWrapping;
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
// Create Earth
|
|
79
|
-
earth = createEarth(earthDayTexture, earthNightTexture, earthBumpTexture);
|
|
80
|
-
scene.add(earth);
|
|
81
|
-
|
|
82
|
-
// Create cloud layer
|
|
83
|
-
clouds = createClouds(earthCloudsTexture);
|
|
84
|
-
scene.add(clouds);
|
|
85
|
-
|
|
86
|
-
// Create atmosphere glow
|
|
87
|
-
atmosphere = createAtmosphere();
|
|
88
|
-
scene.add(atmosphere);
|
|
89
|
-
|
|
90
|
-
// Stars background
|
|
91
|
-
createStars();
|
|
92
|
-
|
|
93
|
-
// Renderer
|
|
94
|
-
renderer = new THREE.WebGPURenderer({ antialias: true });
|
|
95
|
-
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
96
|
-
renderer.setPixelRatio(window.devicePixelRatio);
|
|
97
|
-
document.body.appendChild(renderer.domElement);
|
|
98
|
-
await renderer.init();
|
|
99
|
-
|
|
100
|
-
// Controls
|
|
101
|
-
controls = new OrbitControls(camera, renderer.domElement);
|
|
102
|
-
controls.enableDamping = true;
|
|
103
|
-
controls.minDistance = 2;
|
|
104
|
-
controls.maxDistance = 10;
|
|
105
|
-
|
|
106
|
-
// Events
|
|
107
|
-
window.addEventListener('resize', onWindowResize);
|
|
108
|
-
|
|
109
|
-
renderer.setAnimationLoop(animate);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function createEarth(dayTex, nightTex, bumpTex) {
|
|
113
|
-
const geometry = new THREE.SphereGeometry(1, 64, 64);
|
|
114
|
-
const material = new THREE.MeshStandardNodeMaterial();
|
|
115
|
-
|
|
116
|
-
// Sun illumination factor
|
|
117
|
-
const sunOrientation = Fn(() => {
|
|
118
|
-
return normalWorld.dot(sunDirection).mul(0.5).add(0.5);
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
// Day/night color mixing
|
|
122
|
-
material.colorNode = Fn(() => {
|
|
123
|
-
const dayColor = texture(dayTex, uv());
|
|
124
|
-
const nightColor = texture(nightTex, uv());
|
|
125
|
-
|
|
126
|
-
const orientation = sunOrientation();
|
|
127
|
-
const dayNight = smoothstep(0.4, 0.6, orientation);
|
|
128
|
-
|
|
129
|
-
// Add city lights on night side
|
|
130
|
-
const cityLights = nightColor.mul(cityLightIntensity).mul(
|
|
131
|
-
float(1.0).sub(dayNight)
|
|
132
|
-
);
|
|
133
|
-
|
|
134
|
-
const baseColor = mix(nightColor, dayColor, dayNight);
|
|
135
|
-
return baseColor.add(cityLights.mul(float(1.0).sub(orientation).pow(2.0)));
|
|
136
|
-
})();
|
|
137
|
-
|
|
138
|
-
// Bump mapping for terrain
|
|
139
|
-
material.normalNode = bumpMap(texture(bumpTex, uv()), 0.03);
|
|
140
|
-
|
|
141
|
-
// PBR properties vary with day/night
|
|
142
|
-
material.roughnessNode = Fn(() => {
|
|
143
|
-
const orientation = sunOrientation();
|
|
144
|
-
return mix(float(0.8), float(0.4), smoothstep(0.3, 0.7, orientation));
|
|
145
|
-
})();
|
|
146
|
-
|
|
147
|
-
material.metalnessNode = float(0.0);
|
|
148
|
-
|
|
149
|
-
// Subtle atmospheric rim on day side
|
|
150
|
-
material.emissiveNode = Fn(() => {
|
|
151
|
-
const viewDir = normalize(cameraPosition.sub(positionWorld));
|
|
152
|
-
const fresnel = pow(float(1.0).sub(normalWorld.dot(viewDir).saturate()), 4.0);
|
|
153
|
-
|
|
154
|
-
const orientation = sunOrientation();
|
|
155
|
-
const atmosphereColor = mix(atmosphereTwilightColor, atmosphereDayColor, orientation);
|
|
156
|
-
|
|
157
|
-
return atmosphereColor.mul(fresnel).mul(orientation).mul(0.3);
|
|
158
|
-
})();
|
|
159
|
-
|
|
160
|
-
return new THREE.Mesh(geometry, material);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
function createClouds(cloudsTex) {
|
|
164
|
-
const geometry = new THREE.SphereGeometry(1.01, 64, 64);
|
|
165
|
-
const material = new THREE.MeshStandardNodeMaterial();
|
|
166
|
-
|
|
167
|
-
// Animated UV for cloud movement
|
|
168
|
-
const cloudUV = Fn(() => {
|
|
169
|
-
const baseUV = uv();
|
|
170
|
-
const offset = time.mul(cloudSpeed);
|
|
171
|
-
return vec2(baseUV.x.add(offset), baseUV.y);
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
// Cloud color (white with transparency)
|
|
175
|
-
material.colorNode = color(0xffffff);
|
|
176
|
-
|
|
177
|
-
// Cloud opacity from texture
|
|
178
|
-
material.opacityNode = Fn(() => {
|
|
179
|
-
const cloudAlpha = texture(cloudsTex, cloudUV()).r;
|
|
180
|
-
|
|
181
|
-
// Fade clouds on night side
|
|
182
|
-
const sunOrientation = normalWorld.dot(sunDirection).mul(0.5).add(0.5);
|
|
183
|
-
const dayFactor = smoothstep(0.2, 0.5, sunOrientation);
|
|
184
|
-
|
|
185
|
-
return cloudAlpha.mul(0.8).mul(dayFactor.mul(0.5).add(0.5));
|
|
186
|
-
})();
|
|
187
|
-
|
|
188
|
-
material.transparent = true;
|
|
189
|
-
material.depthWrite = false;
|
|
190
|
-
material.side = THREE.DoubleSide;
|
|
191
|
-
|
|
192
|
-
// Slight self-illumination
|
|
193
|
-
material.emissiveNode = Fn(() => {
|
|
194
|
-
const sunOrientation = normalWorld.dot(sunDirection).mul(0.5).add(0.5);
|
|
195
|
-
return color(0xffffff).mul(sunOrientation.mul(0.1));
|
|
196
|
-
})();
|
|
197
|
-
|
|
198
|
-
return new THREE.Mesh(geometry, material);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
function createAtmosphere() {
|
|
202
|
-
const geometry = new THREE.SphereGeometry(1.15, 64, 64);
|
|
203
|
-
const material = new THREE.MeshBasicNodeMaterial();
|
|
204
|
-
|
|
205
|
-
material.colorNode = Fn(() => {
|
|
206
|
-
const viewDir = normalize(cameraPosition.sub(positionWorld));
|
|
207
|
-
const fresnel = pow(float(1.0).sub(normalWorld.dot(viewDir).abs()), 3.0);
|
|
208
|
-
|
|
209
|
-
const sunOrientation = normalWorld.dot(sunDirection).mul(0.5).add(0.5);
|
|
210
|
-
const atmosphereColor = mix(atmosphereTwilightColor, atmosphereDayColor, sunOrientation);
|
|
211
|
-
|
|
212
|
-
return atmosphereColor;
|
|
213
|
-
})();
|
|
214
|
-
|
|
215
|
-
material.opacityNode = Fn(() => {
|
|
216
|
-
const viewDir = normalize(cameraPosition.sub(positionWorld));
|
|
217
|
-
const fresnel = pow(float(1.0).sub(normalWorld.dot(viewDir).abs()), 2.5);
|
|
218
|
-
|
|
219
|
-
// Stronger on day side
|
|
220
|
-
const sunOrientation = normalWorld.dot(sunDirection).mul(0.5).add(0.5);
|
|
221
|
-
|
|
222
|
-
return fresnel.mul(sunOrientation.mul(0.5).add(0.3));
|
|
223
|
-
})();
|
|
224
|
-
|
|
225
|
-
material.transparent = true;
|
|
226
|
-
material.depthWrite = false;
|
|
227
|
-
material.side = THREE.BackSide;
|
|
228
|
-
|
|
229
|
-
return new THREE.Mesh(geometry, material);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
function createStars() {
|
|
233
|
-
const starsGeometry = new THREE.BufferGeometry();
|
|
234
|
-
const starCount = 2000;
|
|
235
|
-
|
|
236
|
-
const positions = new Float32Array(starCount * 3);
|
|
237
|
-
const colors = new Float32Array(starCount * 3);
|
|
238
|
-
|
|
239
|
-
for (let i = 0; i < starCount; i++) {
|
|
240
|
-
// Random position on sphere
|
|
241
|
-
const theta = Math.random() * Math.PI * 2;
|
|
242
|
-
const phi = Math.acos(Math.random() * 2 - 1);
|
|
243
|
-
const radius = 50 + Math.random() * 50;
|
|
244
|
-
|
|
245
|
-
positions[i * 3] = radius * Math.sin(phi) * Math.cos(theta);
|
|
246
|
-
positions[i * 3 + 1] = radius * Math.sin(phi) * Math.sin(theta);
|
|
247
|
-
positions[i * 3 + 2] = radius * Math.cos(phi);
|
|
248
|
-
|
|
249
|
-
// Slight color variation
|
|
250
|
-
const brightness = 0.5 + Math.random() * 0.5;
|
|
251
|
-
colors[i * 3] = brightness;
|
|
252
|
-
colors[i * 3 + 1] = brightness;
|
|
253
|
-
colors[i * 3 + 2] = brightness + Math.random() * 0.2;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
starsGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
|
|
257
|
-
starsGeometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));
|
|
258
|
-
|
|
259
|
-
const starsMaterial = new THREE.PointsNodeMaterial();
|
|
260
|
-
starsMaterial.colorNode = Fn(() => {
|
|
261
|
-
return vec3(1.0);
|
|
262
|
-
})();
|
|
263
|
-
starsMaterial.sizeNode = float(2.0);
|
|
264
|
-
starsMaterial.vertexColors = true;
|
|
265
|
-
|
|
266
|
-
const stars = new THREE.Points(starsGeometry, starsMaterial);
|
|
267
|
-
scene.add(stars);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
function onWindowResize() {
|
|
271
|
-
camera.aspect = window.innerWidth / window.innerHeight;
|
|
272
|
-
camera.updateProjectionMatrix();
|
|
273
|
-
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
function animate() {
|
|
277
|
-
// Rotate Earth slowly
|
|
278
|
-
earth.rotation.y += 0.001;
|
|
279
|
-
clouds.rotation.y += 0.0012;
|
|
280
|
-
|
|
281
|
-
// Animate sun direction (optional - creates day/night cycle)
|
|
282
|
-
// const angle = time.value * 0.1;
|
|
283
|
-
// sunDirection.value.set(Math.cos(angle), 0.2, Math.sin(angle)).normalize();
|
|
284
|
-
|
|
285
|
-
controls.update();
|
|
286
|
-
renderer.render(scene, camera);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
init();
|
|
290
|
-
|
|
291
|
-
// Export for external control
|
|
292
|
-
export { sunDirection, atmosphereDayColor, atmosphereTwilightColor, cloudSpeed, cityLightIntensity };
|
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* GPU Particle System with Compute Shaders
|
|
3
|
-
*
|
|
4
|
-
* Demonstrates TSL compute shaders for particle simulation:
|
|
5
|
-
* - Instanced array buffers
|
|
6
|
-
* - Physics simulation on GPU
|
|
7
|
-
* - Mouse interaction
|
|
8
|
-
*
|
|
9
|
-
* Based on Three.js webgpu_compute_particles example (MIT License)
|
|
10
|
-
* https://github.com/mrdoob/three.js
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import * as THREE from 'three/webgpu';
|
|
14
|
-
import {
|
|
15
|
-
Fn,
|
|
16
|
-
If,
|
|
17
|
-
uniform,
|
|
18
|
-
float,
|
|
19
|
-
vec3,
|
|
20
|
-
color,
|
|
21
|
-
instancedArray,
|
|
22
|
-
instanceIndex,
|
|
23
|
-
hash,
|
|
24
|
-
time
|
|
25
|
-
} from 'three/tsl';
|
|
26
|
-
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
|
|
27
|
-
|
|
28
|
-
let camera, scene, renderer, controls;
|
|
29
|
-
let computeInit, computeUpdate, computeHit;
|
|
30
|
-
|
|
31
|
-
// Particle count
|
|
32
|
-
const PARTICLE_COUNT = 100000;
|
|
33
|
-
|
|
34
|
-
// Storage buffers
|
|
35
|
-
const positions = instancedArray(PARTICLE_COUNT, 'vec3');
|
|
36
|
-
const velocities = instancedArray(PARTICLE_COUNT, 'vec3');
|
|
37
|
-
|
|
38
|
-
// Uniforms
|
|
39
|
-
const gravity = uniform(-9.8);
|
|
40
|
-
const bounce = uniform(0.7);
|
|
41
|
-
const friction = uniform(0.98);
|
|
42
|
-
const deltaTimeUniform = uniform(0);
|
|
43
|
-
const clickPosition = uniform(new THREE.Vector3());
|
|
44
|
-
const hitStrength = uniform(5.0);
|
|
45
|
-
|
|
46
|
-
async function init() {
|
|
47
|
-
// Camera
|
|
48
|
-
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100);
|
|
49
|
-
camera.position.set(0, 5, 15);
|
|
50
|
-
|
|
51
|
-
// Scene
|
|
52
|
-
scene = new THREE.Scene();
|
|
53
|
-
scene.background = new THREE.Color(0x111122);
|
|
54
|
-
|
|
55
|
-
// Create compute shaders
|
|
56
|
-
createComputeShaders();
|
|
57
|
-
|
|
58
|
-
// Create particle mesh
|
|
59
|
-
createParticleMesh();
|
|
60
|
-
|
|
61
|
-
// Floor
|
|
62
|
-
const floorGeometry = new THREE.PlaneGeometry(30, 30);
|
|
63
|
-
const floorMaterial = new THREE.MeshStandardNodeMaterial({
|
|
64
|
-
color: 0x333333
|
|
65
|
-
});
|
|
66
|
-
const floor = new THREE.Mesh(floorGeometry, floorMaterial);
|
|
67
|
-
floor.rotation.x = -Math.PI / 2;
|
|
68
|
-
floor.receiveShadow = true;
|
|
69
|
-
scene.add(floor);
|
|
70
|
-
|
|
71
|
-
// Lights
|
|
72
|
-
const ambientLight = new THREE.AmbientLight(0x404040);
|
|
73
|
-
scene.add(ambientLight);
|
|
74
|
-
|
|
75
|
-
const pointLight = new THREE.PointLight(0xffffff, 100);
|
|
76
|
-
pointLight.position.set(5, 10, 5);
|
|
77
|
-
scene.add(pointLight);
|
|
78
|
-
|
|
79
|
-
// Renderer
|
|
80
|
-
renderer = new THREE.WebGPURenderer({ antialias: true });
|
|
81
|
-
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
82
|
-
renderer.setPixelRatio(window.devicePixelRatio);
|
|
83
|
-
document.body.appendChild(renderer.domElement);
|
|
84
|
-
await renderer.init();
|
|
85
|
-
|
|
86
|
-
// Initialize particles
|
|
87
|
-
await renderer.computeAsync(computeInit);
|
|
88
|
-
|
|
89
|
-
// Controls
|
|
90
|
-
controls = new OrbitControls(camera, renderer.domElement);
|
|
91
|
-
controls.enableDamping = true;
|
|
92
|
-
controls.target.set(0, 2, 0);
|
|
93
|
-
|
|
94
|
-
// Events
|
|
95
|
-
window.addEventListener('resize', onWindowResize);
|
|
96
|
-
renderer.domElement.addEventListener('click', onClick);
|
|
97
|
-
|
|
98
|
-
renderer.setAnimationLoop(animate);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function createComputeShaders() {
|
|
102
|
-
// Grid dimensions for initialization
|
|
103
|
-
const gridSize = Math.ceil(Math.sqrt(PARTICLE_COUNT));
|
|
104
|
-
const spacing = 0.15;
|
|
105
|
-
const offset = (gridSize * spacing) / 2;
|
|
106
|
-
|
|
107
|
-
// Initialize particles in a grid
|
|
108
|
-
computeInit = Fn(() => {
|
|
109
|
-
const position = positions.element(instanceIndex);
|
|
110
|
-
const velocity = velocities.element(instanceIndex);
|
|
111
|
-
|
|
112
|
-
// Calculate grid position
|
|
113
|
-
const x = instanceIndex.mod(gridSize);
|
|
114
|
-
const z = instanceIndex.div(gridSize);
|
|
115
|
-
|
|
116
|
-
// Set position
|
|
117
|
-
position.x.assign(x.toFloat().mul(spacing).sub(offset));
|
|
118
|
-
position.y.assign(float(5.0).add(hash(instanceIndex).mul(2.0)));
|
|
119
|
-
position.z.assign(z.toFloat().mul(spacing).sub(offset));
|
|
120
|
-
|
|
121
|
-
// Random initial velocity
|
|
122
|
-
velocity.x.assign(hash(instanceIndex.add(1)).sub(0.5).mul(2.0));
|
|
123
|
-
velocity.y.assign(hash(instanceIndex.add(2)).mul(-2.0));
|
|
124
|
-
velocity.z.assign(hash(instanceIndex.add(3)).sub(0.5).mul(2.0));
|
|
125
|
-
})().compute(PARTICLE_COUNT);
|
|
126
|
-
|
|
127
|
-
// Physics update
|
|
128
|
-
computeUpdate = Fn(() => {
|
|
129
|
-
const position = positions.element(instanceIndex);
|
|
130
|
-
const velocity = velocities.element(instanceIndex);
|
|
131
|
-
const dt = deltaTimeUniform;
|
|
132
|
-
|
|
133
|
-
// Apply gravity
|
|
134
|
-
velocity.y.addAssign(gravity.mul(dt));
|
|
135
|
-
|
|
136
|
-
// Update position
|
|
137
|
-
position.addAssign(velocity.mul(dt));
|
|
138
|
-
|
|
139
|
-
// Apply friction
|
|
140
|
-
velocity.mulAssign(friction);
|
|
141
|
-
|
|
142
|
-
// Ground collision
|
|
143
|
-
If(position.y.lessThan(0), () => {
|
|
144
|
-
position.y.assign(0);
|
|
145
|
-
velocity.y.assign(velocity.y.abs().mul(bounce).negate().mul(-1));
|
|
146
|
-
|
|
147
|
-
// Extra friction on ground
|
|
148
|
-
velocity.x.mulAssign(0.9);
|
|
149
|
-
velocity.z.mulAssign(0.9);
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
// Boundary walls
|
|
153
|
-
If(position.x.abs().greaterThan(15), () => {
|
|
154
|
-
position.x.assign(position.x.sign().mul(15));
|
|
155
|
-
velocity.x.assign(velocity.x.negate().mul(bounce));
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
If(position.z.abs().greaterThan(15), () => {
|
|
159
|
-
position.z.assign(position.z.sign().mul(15));
|
|
160
|
-
velocity.z.assign(velocity.z.negate().mul(bounce));
|
|
161
|
-
});
|
|
162
|
-
})().compute(PARTICLE_COUNT);
|
|
163
|
-
|
|
164
|
-
// Hit/explosion effect
|
|
165
|
-
computeHit = Fn(() => {
|
|
166
|
-
const position = positions.element(instanceIndex);
|
|
167
|
-
const velocity = velocities.element(instanceIndex);
|
|
168
|
-
|
|
169
|
-
// Distance to click
|
|
170
|
-
const toClick = position.sub(clickPosition);
|
|
171
|
-
const distance = toClick.length();
|
|
172
|
-
|
|
173
|
-
// Apply force within radius
|
|
174
|
-
If(distance.lessThan(3.0), () => {
|
|
175
|
-
const direction = toClick.normalize();
|
|
176
|
-
const force = float(3.0).sub(distance).div(3.0).mul(hitStrength);
|
|
177
|
-
|
|
178
|
-
// Add randomness
|
|
179
|
-
const randomForce = force.mul(hash(instanceIndex.add(time.mul(1000))).mul(0.5).add(0.75));
|
|
180
|
-
|
|
181
|
-
velocity.addAssign(direction.mul(randomForce));
|
|
182
|
-
velocity.y.addAssign(randomForce.mul(0.5));
|
|
183
|
-
});
|
|
184
|
-
})().compute(PARTICLE_COUNT);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
function createParticleMesh() {
|
|
188
|
-
// Simple sphere geometry for each particle
|
|
189
|
-
const geometry = new THREE.SphereGeometry(0.08, 8, 8);
|
|
190
|
-
|
|
191
|
-
// Material using computed positions
|
|
192
|
-
const material = new THREE.MeshStandardNodeMaterial();
|
|
193
|
-
|
|
194
|
-
// Position from compute buffer
|
|
195
|
-
material.positionNode = positions.element(instanceIndex);
|
|
196
|
-
|
|
197
|
-
// Color based on velocity
|
|
198
|
-
material.colorNode = Fn(() => {
|
|
199
|
-
const velocity = velocities.element(instanceIndex);
|
|
200
|
-
const speed = velocity.length();
|
|
201
|
-
|
|
202
|
-
// Color gradient: blue (slow) -> orange (fast)
|
|
203
|
-
const t = speed.div(10.0).saturate();
|
|
204
|
-
return color(0x0066ff).mix(color(0xff6600), t);
|
|
205
|
-
})();
|
|
206
|
-
|
|
207
|
-
material.roughnessNode = float(0.5);
|
|
208
|
-
material.metalnessNode = float(0.2);
|
|
209
|
-
|
|
210
|
-
// Create instanced mesh
|
|
211
|
-
const mesh = new THREE.InstancedMesh(geometry, material, PARTICLE_COUNT);
|
|
212
|
-
scene.add(mesh);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
function onClick(event) {
|
|
216
|
-
// Raycast to find click position on floor
|
|
217
|
-
const raycaster = new THREE.Raycaster();
|
|
218
|
-
const mouse = new THREE.Vector2(
|
|
219
|
-
(event.clientX / window.innerWidth) * 2 - 1,
|
|
220
|
-
-(event.clientY / window.innerHeight) * 2 + 1
|
|
221
|
-
);
|
|
222
|
-
|
|
223
|
-
raycaster.setFromCamera(mouse, camera);
|
|
224
|
-
|
|
225
|
-
// Intersect with floor plane (y = 0)
|
|
226
|
-
const plane = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0);
|
|
227
|
-
const intersection = new THREE.Vector3();
|
|
228
|
-
raycaster.ray.intersectPlane(plane, intersection);
|
|
229
|
-
|
|
230
|
-
if (intersection) {
|
|
231
|
-
// Raise click position slightly
|
|
232
|
-
intersection.y = 0.5;
|
|
233
|
-
clickPosition.value.copy(intersection);
|
|
234
|
-
|
|
235
|
-
// Run hit compute shader
|
|
236
|
-
renderer.compute(computeHit);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
function onWindowResize() {
|
|
241
|
-
camera.aspect = window.innerWidth / window.innerHeight;
|
|
242
|
-
camera.updateProjectionMatrix();
|
|
243
|
-
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
const clock = new THREE.Clock();
|
|
247
|
-
|
|
248
|
-
function animate() {
|
|
249
|
-
// Update delta time
|
|
250
|
-
deltaTimeUniform.value = Math.min(clock.getDelta(), 0.1);
|
|
251
|
-
|
|
252
|
-
// Run physics compute
|
|
253
|
-
renderer.compute(computeUpdate);
|
|
254
|
-
|
|
255
|
-
controls.update();
|
|
256
|
-
renderer.render(scene, camera);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
init();
|