├── .gitattributes ├── .github ├── FUNDING.yml ├── dependabot.yml └── workflows │ ├── ci.yml │ ├── deploy-docs.yml │ └── pkg-pr.yml ├── .gitignore ├── .vscode ├── extensions.json └── settings.json ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── apps ├── infra-benchmarks │ ├── deno.json │ ├── package.json │ └── src │ │ └── discriminated-union.ts └── typegpu-docs │ ├── .gitignore │ ├── astro.config.mjs │ ├── deno.json │ ├── ec.config.mjs │ ├── package.json │ ├── public │ ├── assets │ │ ├── 3d-fish │ │ │ ├── fish.jpg │ │ │ ├── fish.obj │ │ │ ├── ocean_floor.obj │ │ │ └── ocean_floor.png │ │ ├── atom.svg │ │ ├── code.svg │ │ ├── cubemap-reflection │ │ │ ├── beach │ │ │ │ ├── negx.jpg │ │ │ │ ├── negy.jpg │ │ │ │ ├── negz.jpg │ │ │ │ ├── posx.jpg │ │ │ │ ├── posy.jpg │ │ │ │ └── posz.jpg │ │ │ ├── campsite │ │ │ │ ├── negx.jpg │ │ │ │ ├── negy.jpg │ │ │ │ ├── negz.jpg │ │ │ │ ├── posx.jpg │ │ │ │ ├── posy.jpg │ │ │ │ └── posz.jpg │ │ │ ├── chapel │ │ │ │ ├── negx.jpg │ │ │ │ ├── negy.jpg │ │ │ │ ├── negz.jpg │ │ │ │ ├── posx.jpg │ │ │ │ ├── posy.jpg │ │ │ │ └── posz.jpg │ │ │ └── city │ │ │ │ ├── negx.jpg │ │ │ │ ├── negy.jpg │ │ │ │ ├── negz.jpg │ │ │ │ ├── posx.jpg │ │ │ │ ├── posy.jpg │ │ │ │ └── posz.jpg │ │ ├── doublechevron-down.svg │ │ ├── gravity │ │ │ ├── skyboxes │ │ │ │ └── milky-way │ │ │ │ │ ├── negx.jpg │ │ │ │ │ ├── negy.jpg │ │ │ │ │ ├── negz.jpg │ │ │ │ │ ├── posx.jpg │ │ │ │ │ ├── posy.jpg │ │ │ │ │ └── posz.jpg │ │ │ ├── sphere.obj │ │ │ └── textures │ │ │ │ ├── ceres-fictional.jpg │ │ │ │ ├── earth.jpg │ │ │ │ ├── haumea-fictional.jpg │ │ │ │ ├── jupiter.jpg │ │ │ │ ├── mars.jpg │ │ │ │ ├── mercury.jpg │ │ │ │ ├── moon.jpg │ │ │ │ ├── neptune.jpg │ │ │ │ ├── saturn.jpg │ │ │ │ ├── sun.jpg │ │ │ │ ├── uranus.jpg │ │ │ │ └── venus.jpg │ │ ├── grid-mixed.svg │ │ ├── key-alt.svg │ │ ├── label-alt.svg │ │ ├── migration.mp4 │ │ ├── mnist-weights │ │ │ ├── layer0.bias.npy │ │ │ ├── layer0.weight.npy │ │ │ ├── layer1.bias.npy │ │ │ ├── layer1.weight.npy │ │ │ ├── layer2.bias.npy │ │ │ ├── layer2.weight.npy │ │ │ ├── layer3.bias.npy │ │ │ ├── layer3.weight.npy │ │ │ ├── layer4.bias.npy │ │ │ ├── layer4.weight.npy │ │ │ ├── layer5.bias.npy │ │ │ ├── layer5.weight.npy │ │ │ ├── layer6.bias.npy │ │ │ ├── layer6.weight.npy │ │ │ ├── layer7.bias.npy │ │ │ └── layer7.weight.npy │ │ └── task-check.svg │ ├── favicon.svg │ ├── plums.jpg │ ├── typegpu-logo-dark.svg │ ├── typegpu-logo-light.svg │ ├── typegpu-logo-monodark.svg │ ├── typegpu-logo-monolight.svg │ ├── typegpu-logomark-dark.svg │ ├── typegpu-logomark-light.svg │ ├── typegpu-logomark-monodark.svg │ └── typegpu-logomark-monolight.svg │ ├── src │ ├── assets │ │ ├── cross.svg │ │ ├── discord-icon.svg │ │ ├── giant-typegpu.svg │ │ ├── github-icon.svg │ │ ├── hamburger.svg │ │ ├── illustration.svg │ │ ├── selected-dot.svg │ │ ├── swm-logo.svg │ │ ├── swm-logomark.svg │ │ ├── troubleshooting_thumbnail.png │ │ ├── typegpu-logo-dark.svg │ │ ├── typegpu-logo-light.svg │ │ ├── typegpu-logo-monodark.svg │ │ ├── typegpu-logo-monolight.svg │ │ ├── typegpu-logomark-dark.svg │ │ ├── typegpu-logomark-light.svg │ │ ├── typegpu-logomark-monodark.svg │ │ └── typegpu-logomark-monolight.svg │ ├── components │ │ ├── CodeEditor.tsx │ │ ├── ControlPanel.tsx │ │ ├── ExampleCard.tsx │ │ ├── ExampleLayout.tsx │ │ ├── ExampleLink.tsx │ │ ├── ExampleNotFound.tsx │ │ ├── ExamplePage.tsx │ │ ├── ExampleView.tsx │ │ ├── FeatureCard.astro │ │ ├── FileDiff.astro │ │ ├── FooterLink.astro │ │ ├── GetStartedButton.astro │ │ ├── ListItem.astro │ │ ├── SearchableExampleList.tsx │ │ ├── TryInPlaygroundButton.astro │ │ ├── design │ │ │ ├── Button.tsx │ │ │ ├── ColorPicker.tsx │ │ │ ├── DeleteIcon.tsx │ │ │ ├── Select.tsx │ │ │ ├── Slider.tsx │ │ │ ├── Snackbar.tsx │ │ │ ├── TextArea.tsx │ │ │ ├── Toggle.tsx │ │ │ └── VectorSlider.tsx │ │ ├── roadmap │ │ │ ├── MilestoneBindGroupsBadge.astro │ │ │ ├── MilestoneBuffersBadge.astro │ │ │ ├── MilestoneCodeBadge.astro │ │ │ ├── MilestoneFunctionsBadge.astro │ │ │ ├── MilestoneLinkerBadge.astro │ │ │ ├── MilestonePipelinesBadge.astro │ │ │ └── RoadMapStep.astro │ │ ├── stackblitz │ │ │ ├── openInStackBlitz.ts │ │ │ └── stackBlitzIndex.ts │ │ └── starlight │ │ │ ├── Head.astro │ │ │ ├── Sidebar.astro │ │ │ └── ThemeSelect.astro │ ├── content.config.ts │ ├── content │ │ ├── docs │ │ │ ├── blog │ │ │ │ └── troubleshooting.md │ │ │ ├── ecosystem │ │ │ │ ├── third-party.mdx │ │ │ │ ├── typegpu-color.mdx │ │ │ │ └── typegpu-noise.mdx │ │ │ ├── fundamentals │ │ │ │ ├── bind-groups.mdx │ │ │ │ ├── buffers.mdx │ │ │ │ ├── data-schemas.mdx │ │ │ │ ├── functions │ │ │ │ │ ├── index.mdx │ │ │ │ │ └── triangle-result.png │ │ │ │ ├── resolve.mdx │ │ │ │ ├── roots.mdx │ │ │ │ ├── slots.mdx │ │ │ │ ├── tgsl.mdx │ │ │ │ └── vertex-layouts.mdx │ │ │ ├── getting-started.mdx │ │ │ ├── integration │ │ │ │ ├── react-native │ │ │ │ │ ├── example-fish.png │ │ │ │ │ ├── example-fluid-1.png │ │ │ │ │ ├── example-fluid-2.png │ │ │ │ │ └── index.mdx │ │ │ │ ├── webgpu-interoperability.mdx │ │ │ │ ├── wesl-interoperability.mdx │ │ │ │ └── working-with-wgpu-matrix.mdx │ │ │ ├── reference │ │ │ │ ├── data-schema-cheatsheet.mdx │ │ │ │ └── naming-convention.mdx │ │ │ ├── tooling │ │ │ │ ├── tgpu-gen.mdx │ │ │ │ └── unplugin-typegpu.mdx │ │ │ ├── tutorials │ │ │ │ ├── game-of-life │ │ │ │ │ ├── images │ │ │ │ │ │ └── effect.png │ │ │ │ │ └── index.mdx │ │ │ │ └── triangle-to-boids │ │ │ │ │ ├── code │ │ │ │ │ ├── step1-typegpu.ts │ │ │ │ │ ├── step1-webgpu.ts │ │ │ │ │ ├── step1side-typegpu.ts │ │ │ │ │ ├── step2-typegpu.ts │ │ │ │ │ ├── step2-webgpu.ts │ │ │ │ │ ├── step3-typegpu.ts │ │ │ │ │ ├── step4-typegpu.ts │ │ │ │ │ ├── step4-webgpu.ts │ │ │ │ │ ├── step5-typegpu.ts │ │ │ │ │ ├── step5-webgpu.ts │ │ │ │ │ ├── step6-typegpu.ts │ │ │ │ │ ├── step7-typegpu.ts │ │ │ │ │ ├── step8-typegpu.ts │ │ │ │ │ ├── step9-typegpu.ts │ │ │ │ │ └── step9-webgpu.ts │ │ │ │ │ ├── images │ │ │ │ │ ├── ttbt-boids.png │ │ │ │ │ └── ttbt-triangle.png │ │ │ │ │ └── index.mdx │ │ │ └── why-typegpu │ │ │ │ ├── index.mdx │ │ │ │ ├── modularity-dark.svg │ │ │ │ └── modularity-light.svg │ │ └── examples │ │ │ ├── algorithms │ │ │ ├── matrix-multiplication │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ └── mnist-inference │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ ├── image-processing │ │ │ ├── blur │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ ├── camera-thresholding │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ ├── chroma-keying-next │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ └── chroma-keying │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ ├── rendering │ │ │ ├── 3d-fish │ │ │ │ ├── compute.ts │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── load-model.ts │ │ │ │ ├── meta.json │ │ │ │ ├── params.ts │ │ │ │ ├── render.ts │ │ │ │ ├── schemas.ts │ │ │ │ ├── tgsl-helpers.ts │ │ │ │ └── thumbnail.png │ │ │ ├── box-raytracing │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ ├── cubemap-reflection │ │ │ │ ├── cubemap.ts │ │ │ │ ├── dataTypes.ts │ │ │ │ ├── helpers.ts │ │ │ │ ├── icosphere.ts │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ ├── function-visualizer │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ ├── perlin-noise │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ └── two-boxes │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ ├── simple │ │ │ ├── gradient-tiles │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ ├── increment-tgsl │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ ├── increment │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ ├── oklab │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ └── triangle │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ ├── simulation │ │ │ ├── boids-next │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ ├── boids │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ ├── confetti │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ ├── fluid-double-buffering │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ ├── fluid-with-atomics │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ ├── game-of-life │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ └── thumbnail.png │ │ │ ├── gravity │ │ │ │ ├── compute.ts │ │ │ │ ├── enums.ts │ │ │ │ ├── helpers.ts │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ ├── presets.ts │ │ │ │ ├── render.ts │ │ │ │ ├── schemas.ts │ │ │ │ └── thumbnail.png │ │ │ └── stable-fluid │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── meta.json │ │ │ │ ├── params.ts │ │ │ │ ├── render.ts │ │ │ │ ├── simulation.ts │ │ │ │ ├── thumbnail.png │ │ │ │ └── types.ts │ │ │ └── tests │ │ │ └── tgsl-parsing-test │ │ │ ├── index.html │ │ │ ├── index.ts │ │ │ ├── logical-expressions.ts │ │ │ ├── matrix-ops.ts │ │ │ └── meta.json │ ├── env.d.ts │ ├── fonts │ │ ├── Aeonik-Air.otf │ │ ├── Aeonik-AirItalic.otf │ │ ├── Aeonik-Black.otf │ │ ├── Aeonik-BlackItalic.otf │ │ ├── Aeonik-Bold.otf │ │ ├── Aeonik-BoldItalic.otf │ │ ├── Aeonik-Light.otf │ │ ├── Aeonik-LightItalic.otf │ │ ├── Aeonik-Medium.otf │ │ ├── Aeonik-MediumItalic.otf │ │ ├── Aeonik-Regular.otf │ │ ├── Aeonik-RegularItalic.otf │ │ ├── Aeonik-Thin.otf │ │ ├── Aeonik-ThinItalic.otf │ │ └── font-face.css │ ├── layouts │ │ ├── PageLayout.astro │ │ └── loadingSpinner.css │ ├── pages │ │ ├── benchmark │ │ │ ├── atom-with-url.ts │ │ │ ├── benchmark-app.tsx │ │ │ ├── components │ │ │ │ ├── benchmark-results.tsx │ │ │ │ ├── checkbox-tree.tsx │ │ │ │ └── parameter-set-row.tsx │ │ │ ├── index.astro │ │ │ ├── modules.ts │ │ │ ├── parameter-set.ts │ │ │ ├── suites.ts │ │ │ └── test-suites │ │ │ │ ├── compiled-write.ts │ │ │ │ ├── partial-write.ts │ │ │ │ └── vector-creation.ts │ │ ├── examples │ │ │ └── index.astro │ │ └── index.astro │ ├── tailwind.css │ └── utils │ │ ├── examples │ │ ├── codeEditorShownAtom.ts │ │ ├── currentExampleAtom.ts │ │ ├── currentSnackbarAtom.ts │ │ ├── errors.ts │ │ ├── exampleContent.ts │ │ ├── exampleControlAtom.ts │ │ ├── exampleRunner.ts │ │ ├── exampleState.ts │ │ ├── menuShownAtom.ts │ │ ├── sandboxModules.ts │ │ └── types.ts │ │ ├── isGPUSupported.ts │ │ ├── liveEditor │ │ └── embeddedTypeScript.ts │ │ └── useEvent.ts │ └── tsconfig.json ├── babel.config.js ├── biome.json ├── deno.json ├── package.json ├── packages ├── tgpu-dev-cli │ ├── colors.mjs │ ├── deno.json │ ├── icons.mjs │ ├── index.mjs │ ├── log.mjs │ ├── package.json │ ├── prepack.mjs │ ├── progress.mjs │ ├── tgpu-dev-cli.mjs │ └── verify-publish-tag.mjs ├── tgpu-gen │ ├── LICENSE.md │ ├── README.md │ ├── colors.mjs │ ├── deno.json │ ├── gen.mjs │ ├── outputPathCompiler.mjs │ ├── package.json │ ├── tests │ │ ├── alias.test.ts │ │ ├── bindGroupLayouts.test.ts │ │ ├── functions.test.ts │ │ ├── outputPathCompiler.test.ts │ │ └── structs.test.ts │ ├── tgpu-gen.mjs │ └── tsconfig.json ├── tgpu-jit │ ├── README.md │ ├── deno.json │ ├── package.json │ ├── src │ │ └── index.ts │ ├── tests │ │ └── foo.test.ts │ ├── tsconfig.json │ ├── tsconfig.test.json │ └── tsup.config.ts ├── tgpu-wgsl-parser │ ├── deno.json │ ├── nearley-redirect-plugin.mjs │ ├── package.json │ ├── src │ │ ├── grammar.ne │ │ ├── grammar.ne.d.ts │ │ ├── grammar.ts │ │ └── index.ts │ ├── tests │ │ ├── boolLiteral.spec.ts │ │ ├── callExpression.spec.ts │ │ ├── callStatement.spec.ts │ │ ├── floatLiteral.spec.ts │ │ ├── forStatement.spec.ts │ │ ├── functionDecl.spec.ts │ │ ├── intLiteral.spec.ts │ │ ├── overrideDecl.spec.ts │ │ ├── returnStatement.spec.ts │ │ ├── structDecl.spec.ts │ │ ├── valueDecl.spec.ts │ │ └── variableDecl.spec.ts │ ├── tsconfig.json │ ├── tsup.config.ts │ └── vitest.config.mts ├── tinyest-for-wgsl │ ├── README.md │ ├── deno.json │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── parsers.ts │ ├── tests │ │ └── parsers.test.ts │ ├── tsconfig.json │ ├── tsconfig.test.json │ └── tsup.config.ts ├── tinyest │ ├── README.md │ ├── deno.json │ ├── jsr.json │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── nodes.ts │ ├── tsconfig.json │ └── tsup.config.ts ├── typegpu-color │ ├── README.md │ ├── build.config.ts │ ├── deno.json │ ├── package.json │ ├── src │ │ ├── hsv.ts │ │ ├── index.ts │ │ ├── oklab.ts │ │ ├── srgb.ts │ │ └── ycbcr.ts │ └── tsconfig.json ├── typegpu-noise │ ├── README.md │ ├── build.config.ts │ ├── deno.json │ ├── package.json │ ├── src │ │ ├── generator.ts │ │ ├── index.ts │ │ ├── perlin-2d.ts │ │ ├── perlin-3d │ │ │ ├── algorithm.ts │ │ │ ├── dynamic-cache.ts │ │ │ ├── index.ts │ │ │ └── static-cache.ts │ │ ├── random.ts │ │ └── utils.ts │ └── tsconfig.json ├── typegpu │ ├── README.md │ ├── deno.json │ ├── package.json │ ├── scripts │ │ └── generateSwizzleFunctions.ts │ ├── setupVitest.ts │ ├── src │ │ ├── builtin.ts │ │ ├── core │ │ │ ├── buffer │ │ │ │ ├── buffer.ts │ │ │ │ └── bufferUsage.ts │ │ │ ├── constant │ │ │ │ └── tgpuConstant.ts │ │ │ ├── declare │ │ │ │ └── tgpuDeclare.ts │ │ │ ├── function │ │ │ │ ├── astUtils.ts │ │ │ │ ├── extractArgs.ts │ │ │ │ ├── fnCore.ts │ │ │ │ ├── fnTypes.ts │ │ │ │ ├── ioOutputType.ts │ │ │ │ ├── templateUtils.ts │ │ │ │ ├── tgpuComputeFn.ts │ │ │ │ ├── tgpuFn.ts │ │ │ │ ├── tgpuFragmentFn.ts │ │ │ │ └── tgpuVertexFn.ts │ │ │ ├── pipeline │ │ │ │ ├── computePipeline.ts │ │ │ │ ├── connectAttachmentToShader.ts │ │ │ │ ├── connectTargetsToShader.ts │ │ │ │ └── renderPipeline.ts │ │ │ ├── resolve │ │ │ │ ├── externals.ts │ │ │ │ ├── resolveData.ts │ │ │ │ └── tgpuResolve.ts │ │ │ ├── root │ │ │ │ ├── init.ts │ │ │ │ └── rootTypes.ts │ │ │ ├── sampler │ │ │ │ └── sampler.ts │ │ │ ├── slot │ │ │ │ ├── accessor.ts │ │ │ │ ├── derived.ts │ │ │ │ ├── slot.ts │ │ │ │ └── slotTypes.ts │ │ │ ├── texture │ │ │ │ ├── externalTexture.ts │ │ │ │ ├── texture.ts │ │ │ │ ├── textureFormats.ts │ │ │ │ ├── textureProps.ts │ │ │ │ └── usageExtension.ts │ │ │ ├── valueProxyUtils.ts │ │ │ ├── variable │ │ │ │ └── tgpuVariable.ts │ │ │ └── vertexLayout │ │ │ │ ├── connectAttributesToShader.ts │ │ │ │ ├── vertexAttribute.ts │ │ │ │ └── vertexLayout.ts │ │ ├── data │ │ │ ├── alignIO.ts │ │ │ ├── alignmentOf.ts │ │ │ ├── array.ts │ │ │ ├── atomic.ts │ │ │ ├── attributes.ts │ │ │ ├── compiledIO.ts │ │ │ ├── dataIO.ts │ │ │ ├── dataTypes.ts │ │ │ ├── disarray.ts │ │ │ ├── index.ts │ │ │ ├── matrix.ts │ │ │ ├── numeric.ts │ │ │ ├── offsets.ts │ │ │ ├── partialIO.ts │ │ │ ├── ptr.ts │ │ │ ├── sizeOf.ts │ │ │ ├── struct.ts │ │ │ ├── unstruct.ts │ │ │ ├── vector.ts │ │ │ ├── vectorImpl.ts │ │ │ ├── vectorOps.ts │ │ │ ├── vertexFormatData.ts │ │ │ └── wgslTypes.ts │ │ ├── errors.ts │ │ ├── extension.ts │ │ ├── extractGpuValueGetter.ts │ │ ├── globals.d.ts │ │ ├── gpuMode.ts │ │ ├── index.ts │ │ ├── jitTranspiler.ts │ │ ├── mathUtils.ts │ │ ├── memo.ts │ │ ├── namable.ts │ │ ├── nameRegistry.ts │ │ ├── resolutionCtx.ts │ │ ├── shared │ │ │ ├── README.md │ │ │ ├── generators.ts │ │ │ ├── meta.ts │ │ │ ├── repr.ts │ │ │ ├── symbols.ts │ │ │ ├── utilityTypes.ts │ │ │ └── vertexFormat.ts │ │ ├── std │ │ │ ├── array.ts │ │ │ ├── atomic.ts │ │ │ ├── boolean.ts │ │ │ ├── discard.ts │ │ │ ├── index.ts │ │ │ ├── matrix.ts │ │ │ ├── numeric.ts │ │ │ ├── packing.ts │ │ │ └── texture.ts │ │ ├── taskQueue.ts │ │ ├── tgpuBindGroupLayout.ts │ │ ├── tgsl │ │ │ ├── generationHelpers.ts │ │ │ ├── index.ts │ │ │ └── wgslGenerator.ts │ │ ├── types.ts │ │ └── unwrapper.ts │ ├── tests │ │ ├── accessor.test.ts │ │ ├── align.test.ts │ │ ├── array.test.ts │ │ ├── asUsage.test.ts │ │ ├── attributes.test.ts │ │ ├── bindGroupLayout.test.ts │ │ ├── buffer.test.ts │ │ ├── bufferUsage.test.ts │ │ ├── builtin.test.ts │ │ ├── compiledIO.test.ts │ │ ├── computePipeline.test.ts │ │ ├── constant.test.ts │ │ ├── data │ │ │ ├── atomic.test.ts │ │ │ └── ptr.test.ts │ │ ├── declare.test.ts │ │ ├── derived.test.ts │ │ ├── disarray.test.ts │ │ ├── entryFnBuiltinArgs.test.ts │ │ ├── entryFnHeaderGen.test.ts │ │ ├── externals.test.ts │ │ ├── extractArgs.test.ts │ │ ├── function.test.ts │ │ ├── functionTagged.test.ts │ │ ├── indentController.test.ts │ │ ├── interpolate.test.ts │ │ ├── ioOutputType.test.ts │ │ ├── location.test.ts │ │ ├── mathUtils.test.ts │ │ ├── matrix.test.ts │ │ ├── numeric.test.ts │ │ ├── partialIo.test.ts │ │ ├── primitiveCast.test.ts │ │ ├── rawFn.test.ts │ │ ├── renderPipeline.test.ts │ │ ├── resolve.test.ts │ │ ├── root.test.ts │ │ ├── size.test.ts │ │ ├── slot.test.ts │ │ ├── std │ │ │ ├── boolean │ │ │ │ ├── all.test.ts │ │ │ │ ├── allEq.test.ts │ │ │ │ ├── and.test.ts │ │ │ │ ├── any.test.ts │ │ │ │ ├── eq.test.ts │ │ │ │ ├── ge.test.ts │ │ │ │ ├── gt.test.ts │ │ │ │ ├── isCloseTo.test.ts │ │ │ │ ├── le.test.ts │ │ │ │ ├── lt.test.ts │ │ │ │ ├── ne.test.ts │ │ │ │ ├── not.test.ts │ │ │ │ ├── or.test.ts │ │ │ │ └── select.test.ts │ │ │ ├── matrix │ │ │ │ ├── rotate.test.ts │ │ │ │ ├── scale.test.ts │ │ │ │ └── translate.test.ts │ │ │ ├── numeric │ │ │ │ ├── acos.test.ts │ │ │ │ ├── acosh.test.ts │ │ │ │ ├── add.test.ts │ │ │ │ ├── asin.test.ts │ │ │ │ ├── atan2.test.ts │ │ │ │ ├── cosh.test.ts │ │ │ │ ├── cross.test.ts │ │ │ │ ├── distance.test.ts │ │ │ │ ├── div.test.ts │ │ │ │ ├── dot.test.ts │ │ │ │ ├── exp2.test.ts │ │ │ │ ├── fract.test.ts │ │ │ │ ├── length.test.ts │ │ │ │ ├── mix.test.ts │ │ │ │ ├── mul.test.ts │ │ │ │ ├── normalize.test.ts │ │ │ │ ├── pow.test.ts │ │ │ │ ├── reflect.test.ts │ │ │ │ ├── sign.test.ts │ │ │ │ └── sub.test.ts │ │ │ └── packing.test.ts │ │ ├── struct.test.ts │ │ ├── texture.test.ts │ │ ├── tgsl │ │ │ ├── codeGen.test.ts │ │ │ ├── generationHelpers.test.ts │ │ │ └── wgslGenerator.test.ts │ │ ├── tgslFn.test.ts │ │ ├── unstruct.test.ts │ │ ├── utilityTypes.test.ts │ │ ├── utils │ │ │ ├── extendedIt.ts │ │ │ ├── parseResolved.ts │ │ │ └── webgpuGlobals.ts │ │ ├── variable.test.ts │ │ ├── vector.test.ts │ │ ├── vertexLayout.test.ts │ │ └── wgpuMatrixIntegration.test.ts │ ├── tsconfig.json │ ├── tsconfig.test.json │ ├── tsup.config.ts │ └── vitest.config.mts └── unplugin-typegpu │ ├── README.md │ ├── deno.json │ ├── package.json │ ├── src │ ├── babel.ts │ ├── common.ts │ ├── esbuild.ts │ ├── farm.ts │ ├── filter.ts │ ├── index.ts │ ├── rolldown.ts │ ├── rollup.ts │ ├── rspack.ts │ ├── vite.ts │ └── webpack.ts │ ├── test │ ├── aliasing.test.ts │ ├── kernel-and-js-directive.test.ts │ ├── kernel-directive.test.ts │ ├── parser-options.test.ts │ ├── tgsl-transpiling-with-does.test.ts │ ├── tgsl-transpiling.test.ts │ └── transform.ts │ ├── tsconfig.json │ └── tsup.config.ts ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── projects-using-typegpu.md ├── tsconfig.base.json ├── tsconfig.json ├── vitest.config.mts └── vitest.workspace.ts /.gitattributes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/.gitattributes -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: software-mansion 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Please see the documentation for all configuration options: 2 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file 3 | 4 | version: 2 5 | updates: 6 | - package-ecosystem: 'npm' 7 | directories: 8 | - / 9 | - /packages/* 10 | - /apps/* 11 | schedule: 12 | interval: 'weekly' 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | node_modules 3 | .pnp 4 | .pnp.js 5 | 6 | # testing 7 | coverage 8 | 9 | # development 10 | .devcontainer 11 | .attest 12 | .zed 13 | 14 | # production 15 | dist 16 | build 17 | 18 | # dotenv environment variables file 19 | .env 20 | .env.local 21 | .env.development.local 22 | .env.test.local 23 | .env.production.local 24 | 25 | # logs 26 | npm-debug.log* 27 | yarn-debug.log* 28 | yarn-error.log* 29 | 30 | # misc 31 | .DS_Store 32 | .idea 33 | .husky 34 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "emeraldwalk.runonsave" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib", 3 | "[astro]": { 4 | "editor.defaultFormatter": "astro-build.astro-vscode" 5 | }, 6 | "[typescript]": { 7 | "editor.defaultFormatter": null 8 | }, 9 | "[javascript]": { 10 | "editor.defaultFormatter": null 11 | }, 12 | "emeraldwalk.runonsave": { 13 | "commands": [ 14 | { 15 | "match": ".*", 16 | "cmd": "echo \"Formatting ${relativeFile}\" && deno fmt ./${relativeFile}" 17 | } 18 | ] 19 | }, 20 | "deno.enable": false, 21 | "typescript.preferences.importModuleSpecifier": "relative" 22 | } 23 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Software Mansion 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /apps/infra-benchmarks/deno.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": ["."], 3 | "fmt": { 4 | "exclude": ["!."], 5 | "singleQuote": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /apps/infra-benchmarks/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "infra-benchmarks", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "discriminated-union": "node --experimental-strip-types --expose-gc src/discriminated-union.ts" 7 | }, 8 | "license": "MIT", 9 | "devDependencies": { 10 | "tinybench": "^3.1.0" 11 | }, 12 | "packageManager": "pnpm@10.4.1+sha512.c753b6c3ad7afa13af388fa6d808035a008e30ea9993f58c6663e2bc5ff21679aa834db094987129aa4d488b86df57f7b634981b2f827cdcacc698cc0cfb88af" 13 | } 14 | -------------------------------------------------------------------------------- /apps/typegpu-docs/.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | # generated types 4 | .astro/ 5 | 6 | # dependencies 7 | node_modules/ 8 | 9 | # logs 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | pnpm-debug.log* 14 | 15 | 16 | # environment variables 17 | .env 18 | .env.production 19 | 20 | # macOS-specific files 21 | .DS_Store 22 | 23 | # autogenerated by typedoc 24 | src/content/docs/api 25 | -------------------------------------------------------------------------------- /apps/typegpu-docs/deno.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": ["."], 3 | "fmt": { 4 | "exclude": ["!."], 5 | "singleQuote": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /apps/typegpu-docs/ec.config.mjs: -------------------------------------------------------------------------------- 1 | import ecTwoSlash from 'expressive-code-twoslash'; 2 | import ts from 'typescript'; 3 | 4 | /** @type {import('@astrojs/starlight/expressive-code').StarlightExpressiveCodeOptions} */ 5 | export default { 6 | plugins: [ 7 | ecTwoSlash({ 8 | twoslashOptions: { 9 | strict: true, 10 | compilerOptions: { moduleResolution: ts.ModuleResolutionKind.Bundler }, 11 | }, 12 | }), 13 | ], 14 | }; 15 | -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/3d-fish/fish.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/3d-fish/fish.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/3d-fish/ocean_floor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/3d-fish/ocean_floor.png -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/beach/negx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/beach/negx.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/beach/negy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/beach/negy.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/beach/negz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/beach/negz.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/beach/posx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/beach/posx.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/beach/posy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/beach/posy.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/beach/posz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/beach/posz.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/campsite/negx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/campsite/negx.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/campsite/negy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/campsite/negy.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/campsite/negz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/campsite/negz.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/campsite/posx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/campsite/posx.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/campsite/posy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/campsite/posy.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/campsite/posz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/campsite/posz.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/chapel/negx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/chapel/negx.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/chapel/negy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/chapel/negy.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/chapel/negz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/chapel/negz.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/chapel/posx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/chapel/posx.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/chapel/posy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/chapel/posy.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/chapel/posz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/chapel/posz.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/city/negx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/city/negx.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/city/negy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/city/negy.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/city/negz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/city/negz.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/city/posx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/city/posx.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/city/posy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/city/posy.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/cubemap-reflection/city/posz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/cubemap-reflection/city/posz.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/doublechevron-down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/gravity/skyboxes/milky-way/negx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/gravity/skyboxes/milky-way/negx.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/gravity/skyboxes/milky-way/negy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/gravity/skyboxes/milky-way/negy.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/gravity/skyboxes/milky-way/negz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/gravity/skyboxes/milky-way/negz.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/gravity/skyboxes/milky-way/posx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/gravity/skyboxes/milky-way/posx.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/gravity/skyboxes/milky-way/posy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/gravity/skyboxes/milky-way/posy.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/gravity/skyboxes/milky-way/posz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/gravity/skyboxes/milky-way/posz.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/gravity/textures/ceres-fictional.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/gravity/textures/ceres-fictional.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/gravity/textures/earth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/gravity/textures/earth.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/gravity/textures/haumea-fictional.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/gravity/textures/haumea-fictional.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/gravity/textures/jupiter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/gravity/textures/jupiter.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/gravity/textures/mars.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/gravity/textures/mars.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/gravity/textures/mercury.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/gravity/textures/mercury.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/gravity/textures/moon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/gravity/textures/moon.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/gravity/textures/neptune.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/gravity/textures/neptune.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/gravity/textures/saturn.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/gravity/textures/saturn.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/gravity/textures/sun.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/gravity/textures/sun.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/gravity/textures/uranus.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/gravity/textures/uranus.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/gravity/textures/venus.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/gravity/textures/venus.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/key-alt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/label-alt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/migration.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/migration.mp4 -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/mnist-weights/layer0.bias.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/mnist-weights/layer0.bias.npy -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/mnist-weights/layer0.weight.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/mnist-weights/layer0.weight.npy -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/mnist-weights/layer1.bias.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/mnist-weights/layer1.bias.npy -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/mnist-weights/layer1.weight.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/mnist-weights/layer1.weight.npy -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/mnist-weights/layer2.bias.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/mnist-weights/layer2.bias.npy -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/mnist-weights/layer2.weight.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/mnist-weights/layer2.weight.npy -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/mnist-weights/layer3.bias.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/mnist-weights/layer3.bias.npy -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/mnist-weights/layer3.weight.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/mnist-weights/layer3.weight.npy -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/mnist-weights/layer4.bias.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/mnist-weights/layer4.bias.npy -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/mnist-weights/layer4.weight.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/mnist-weights/layer4.weight.npy -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/mnist-weights/layer5.bias.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/mnist-weights/layer5.bias.npy -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/mnist-weights/layer5.weight.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/mnist-weights/layer5.weight.npy -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/mnist-weights/layer6.bias.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/mnist-weights/layer6.bias.npy -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/mnist-weights/layer6.weight.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/mnist-weights/layer6.weight.npy -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/mnist-weights/layer7.bias.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/mnist-weights/layer7.bias.npy -------------------------------------------------------------------------------- /apps/typegpu-docs/public/assets/mnist-weights/layer7.weight.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/assets/mnist-weights/layer7.weight.npy -------------------------------------------------------------------------------- /apps/typegpu-docs/public/plums.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/public/plums.jpg -------------------------------------------------------------------------------- /apps/typegpu-docs/public/typegpu-logomark-monodark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /apps/typegpu-docs/public/typegpu-logomark-monolight.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/assets/cross.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 12 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/assets/discord-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/assets/github-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/assets/hamburger.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 8 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/assets/selected-dot.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/assets/troubleshooting_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/assets/troubleshooting_thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/assets/typegpu-logomark-monodark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/assets/typegpu-logomark-monolight.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/components/ExampleNotFound.tsx: -------------------------------------------------------------------------------- 1 | import { useSetAtom } from 'jotai'; 2 | import type { MouseEvent } from 'react'; 3 | import { currentExampleAtom } from '../utils/examples/currentExampleAtom.ts'; 4 | import useEvent from '../utils/useEvent.ts'; 5 | 6 | export function ExampleNotFound() { 7 | const setCurrentExample = useSetAtom(currentExampleAtom); 8 | 9 | const handleGoHome = useEvent((e: MouseEvent) => { 10 | e.preventDefault(); 11 | setCurrentExample(undefined); 12 | }); 13 | 14 | return ( 15 |
16 |

404 Example Not Found

17 | 24 |
25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/components/FeatureCard.astro: -------------------------------------------------------------------------------- 1 | --- 2 | const { image, header, class: className } = Astro.props; 3 | --- 4 | 5 |
10 |
12 | {image} 13 |
14 |
15 |

16 | {header} 17 |

18 |

19 |
20 |
21 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/components/FileDiff.astro: -------------------------------------------------------------------------------- 1 | --- 2 | const { add, del } = Astro.props; 3 | const content = await Astro.slots.render('default'); 4 | 5 | const addStyles = { 6 | statusColor: 'dark:before:bg-green-900 before:bg-green-300', 7 | borderColor: 'before:border-green-600', 8 | contentColor: 'before:text-green-600', 9 | plusOrMinus: 'before:content-["+"]' 10 | } 11 | 12 | const delStyles = { 13 | statusColor: 'dark:before:bg-red-900 before:bg-red-300', 14 | borderColor: 'before:border-red-600', 15 | contentColor: 'before:text-red-600', 16 | plusOrMinus: 'before:content-["-"]' 17 | } 18 | 19 | if (!add && !del) { 20 | throw new Error('You must provide either `add` or `del` prop'); 21 | } 22 | 23 | const styles = add ? addStyles : delStyles; 24 | --- 25 | 26 |
35 | 36 |
37 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/components/FooterLink.astro: -------------------------------------------------------------------------------- 1 | --- 2 | const { label, callToAction, href } = Astro.props; 3 | --- 4 | 5 |
6 |

{label}

7 | 12 | {callToAction} 13 | 14 |
15 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/components/GetStartedButton.astro: -------------------------------------------------------------------------------- 1 | 8 | Get started 9 | 14 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/components/ListItem.astro: -------------------------------------------------------------------------------- 1 | --- 2 | const content = await Astro.slots.render('default'); 3 | const { idx } = Astro.props; 4 | --- 5 | 6 |
  • 7 |
    10 | {idx} 11 |
    12 | 13 |
  • -------------------------------------------------------------------------------- /apps/typegpu-docs/src/components/TryInPlaygroundButton.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { LinkCard } from '@astrojs/starlight/components'; 3 | import pkg from 'lz-string'; 4 | const { compressToEncodedURIComponent } = pkg; 5 | 6 | const { code } = Astro.props; 7 | const encodedCode = compressToEncodedURIComponent(code); 8 | const url = `/typegpu/examples#example=playground__${encodedCode}`; 9 | --- 10 | 11 | 12 | 17 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/components/design/Button.tsx: -------------------------------------------------------------------------------- 1 | import cs from 'classnames'; 2 | import { forwardRef, type ReactNode } from 'react'; 3 | 4 | type Props = { 5 | accent?: boolean; 6 | onClick?: () => void; 7 | children?: ReactNode; 8 | }; 9 | 10 | export const Button = forwardRef((props, ref) => { 11 | const { onClick, accent, children } = props; 12 | 13 | return ( 14 | 27 | ); 28 | }); 29 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/components/design/ColorPicker.tsx: -------------------------------------------------------------------------------- 1 | function hexToRgb(hex: string) { 2 | return [ 3 | Number.parseInt(hex.slice(1, 3), 16) / 255, 4 | Number.parseInt(hex.slice(3, 5), 16) / 255, 5 | Number.parseInt(hex.slice(5, 7), 16) / 255, 6 | ] as const; 7 | } 8 | 9 | function componentToHex(c: number) { 10 | const hex = (c * 255).toString(16); 11 | return hex.length === 1 ? `0${hex}` : hex; 12 | } 13 | 14 | function rgbToHex(rgb: readonly [number, number, number]) { 15 | return `#${rgb.map(componentToHex).join('')}`; 16 | } 17 | 18 | type Props = { 19 | /** 20 | * RGB 0-1 21 | */ 22 | value: readonly [number, number, number]; 23 | onChange: (value: readonly [number, number, number]) => void; 24 | }; 25 | 26 | export function ColorPicker({ value, onChange }: Props) { 27 | return ( 28 | onChange(hexToRgb(e.target.value))} 33 | /> 34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/components/design/Slider.tsx: -------------------------------------------------------------------------------- 1 | import * as RadixSlider from '@radix-ui/react-slider'; 2 | 3 | type Props = { 4 | min: number; 5 | max: number; 6 | step: number; 7 | value: number; 8 | onChange: (value: number) => void; 9 | }; 10 | 11 | export function Slider({ min, max, step, value, onChange }: Props) { 12 | return ( 13 | { 19 | onChange(value[0]); 20 | }} 21 | className='relative flex h-10 touch-none overflow-hidden rounded bg-grayscale-20' 22 | > 23 | 24 | 25 | 26 |
    27 | {value} 28 |
    29 |
    30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/components/design/Snackbar.tsx: -------------------------------------------------------------------------------- 1 | export function Snackbar(props: { text: string }) { 2 | const { text } = props; 3 | 4 | return ( 5 |
    9 |
    10 | 19 | Error icon 20 |
    21 | 22 |
    {text}
    23 |
    24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/components/design/TextArea.tsx: -------------------------------------------------------------------------------- 1 | type Props = { 2 | value: string; 3 | onChange: (value: string) => void; 4 | }; 5 | 6 | export function TextArea({ value, onChange }: Props) { 7 | return ( 8 | onChange(event.target.value)} 13 | /> 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/components/design/Toggle.tsx: -------------------------------------------------------------------------------- 1 | import type { ChangeEventHandler } from 'react'; 2 | 3 | type Props = { 4 | checked: boolean; 5 | id?: string; 6 | onChange?: ChangeEventHandler; 7 | }; 8 | 9 | export function Toggle(props: Props) { 10 | return ( 11 | <> 12 | 13 |
    14 | 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/components/starlight/Head.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import StarlightHead from '@astrojs/starlight/components/Head.astro'; 3 | import VtbotStarlight from 'astro-vtbot/components/starlight/Base.astro'; 4 | --- 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/components/starlight/Sidebar.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import VanillaSidebar from "@astrojs/starlight/components/Sidebar.astro"; 3 | --- 4 | 5 |
    6 | Documentation 7 |
    8 |
    9 | Examples 10 |
    11 |
    12 | Blog 13 |
    14 | 15 | 16 | 17 | 30 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/components/starlight/ThemeSelect.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import StarlightThemeSelect from "@astrojs/starlight/components/ThemeSelect.astro"; 3 | --- 4 | 5 |
    6 | Documentation 7 |
    8 |
    9 | Examples 10 |
    11 |
    12 | Blog 13 |
    14 | 15 | 16 | 17 | 18 | 37 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content.config.ts: -------------------------------------------------------------------------------- 1 | import { defineCollection } from 'astro:content'; 2 | import { docsLoader } from '@astrojs/starlight/loaders'; 3 | import { docsSchema } from '@astrojs/starlight/schema'; 4 | import { blogSchema } from 'starlight-blog/schema'; 5 | 6 | export const collections = { 7 | docs: defineCollection({ 8 | loader: docsLoader(), 9 | schema: docsSchema({ extend: (context) => blogSchema(context) }), 10 | }), 11 | }; 12 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/docs/ecosystem/third-party.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Third party" 3 | --- 4 | 5 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/docs/ecosystem/typegpu-color.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "@typegpu/color" 3 | --- 4 | 5 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/docs/ecosystem/typegpu-noise.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "@typegpu/noise" 3 | --- 4 | 5 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/docs/fundamentals/functions/triangle-result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/docs/fundamentals/functions/triangle-result.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/docs/integration/react-native/example-fish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/docs/integration/react-native/example-fish.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/docs/integration/react-native/example-fluid-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/docs/integration/react-native/example-fluid-1.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/docs/integration/react-native/example-fluid-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/docs/integration/react-native/example-fluid-2.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/docs/tutorials/game-of-life/images/effect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/docs/tutorials/game-of-life/images/effect.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/docs/tutorials/triangle-to-boids/images/ttbt-boids.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/docs/tutorials/triangle-to-boids/images/ttbt-boids.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/docs/tutorials/triangle-to-boids/images/ttbt-triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/docs/tutorials/triangle-to-boids/images/ttbt-triangle.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/algorithms/matrix-multiplication/index.html: -------------------------------------------------------------------------------- 1 |
    2 |
    first matrix
    3 |
    4 |
    5 | 6 |
    7 |
    second matrix
    8 |
    9 |
    10 | 11 |
    12 |
    result matrix
    13 |
    14 |
    15 | 16 | 34 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/algorithms/matrix-multiplication/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Matrix Multiplication", 3 | "category": "algorithms", 4 | "tags": ["compute"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/algorithms/matrix-multiplication/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/algorithms/matrix-multiplication/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/algorithms/mnist-inference/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "MNIST Inference", 3 | "category": "algorithms", 4 | "tags": ["ai", "compute", "inference"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/algorithms/mnist-inference/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/algorithms/mnist-inference/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/image-processing/blur/index.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/image-processing/blur/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Image Blur", 3 | "category": "image-processing", 4 | "tags": ["experimental", "compute", "filtering"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/image-processing/blur/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/image-processing/blur/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/image-processing/camera-thresholding/index.html: -------------------------------------------------------------------------------- 1 |
    2 |
    Loading...
    3 |
    4 | 5 | 6 | 7 | 8 | 34 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/image-processing/camera-thresholding/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Camera Thresholding", 3 | "category": "image-processing", 4 | "tags": ["camera", "filtering", "external texture"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/image-processing/camera-thresholding/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/image-processing/camera-thresholding/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/image-processing/chroma-keying-next/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/image-processing/chroma-keying-next/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Chroma Keying (next)", 3 | "category": "image-processing", 4 | "tags": ["camera", "experimental", "filtering", "MediaStreamTrack API"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/image-processing/chroma-keying-next/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/image-processing/chroma-keying-next/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/image-processing/chroma-keying/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/image-processing/chroma-keying/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Chroma Keying", 3 | "category": "image-processing", 4 | "tags": ["camera", "filtering", "MediaStreamTrack API"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/image-processing/chroma-keying/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/image-processing/chroma-keying/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/rendering/3d-fish/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "3D Fish", 3 | "category": "rendering", 4 | "tags": ["experimental", "3d", "rasterization", "compute", "double buffering"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/rendering/3d-fish/params.ts: -------------------------------------------------------------------------------- 1 | import * as d from 'typegpu/data'; 2 | import * as std from 'typegpu/std'; 3 | 4 | export const workGroupSize = 256; 5 | 6 | export const fishAmount = 1024 * 8; 7 | export const fishModelScale = 0.07; 8 | 9 | export const fishWallRepulsionDistance = 0.1; 10 | export const fishWallRepulsionStrength = 0.0001; 11 | export const fishMouseRayRepulsionDistance = 0.9; 12 | export const fishMouseRayRepulsionStrength = 0.0005; 13 | 14 | export const aquariumSize = d.vec3f(10, 4, 10); 15 | 16 | export const cameraInitialPosition = d.vec4f(-5.2, 0, -5.2, 1); 17 | export const cameraInitialTarget = d.vec4f(0, 0, 0, 1); 18 | 19 | export const lightColor = d.vec3f(0.8, 0.8, 1); 20 | export const lightDirection = std.normalize(d.vec3f(-1.0, 4.0, -1.0)); 21 | export const backgroundColor = std.mul(1 / 255, d.vec3f(0x00, 0x7a, 0xcc)); 22 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/rendering/3d-fish/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/rendering/3d-fish/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/rendering/box-raytracing/index.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/rendering/box-raytracing/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Box Raytracing", 3 | "category": "rendering", 4 | "tags": ["experimental", "3d", "raytracing"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/rendering/box-raytracing/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/rendering/box-raytracing/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/rendering/cubemap-reflection/dataTypes.ts: -------------------------------------------------------------------------------- 1 | import * as d from 'typegpu/data'; 2 | 3 | export const Camera = d.struct({ 4 | view: d.mat4x4f, 5 | projection: d.mat4x4f, 6 | position: d.vec4f, 7 | }); 8 | 9 | export const Vertex = d.unstruct({ 10 | position: d.float16x4, 11 | normal: d.float16x4, 12 | }); 13 | 14 | export const ComputeVertex = d.struct({ 15 | position: d.vec2u, // four packed 16-bit floats 16 | normal: d.vec2u, // four packed 16-bit floats 17 | }); 18 | 19 | export const CubeVertex = d.struct({ 20 | position: d.vec3f, 21 | uv: d.vec2f, 22 | }); 23 | 24 | export const DirectionalLight = d.struct({ 25 | direction: d.vec3f, 26 | color: d.vec3f, 27 | intensity: d.f32, 28 | }); 29 | 30 | export const Material = d.struct({ 31 | ambient: d.vec3f, 32 | diffuse: d.vec3f, 33 | specular: d.vec3f, 34 | shininess: d.f32, 35 | reflectivity: d.f32, 36 | }); 37 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/rendering/cubemap-reflection/helpers.ts: -------------------------------------------------------------------------------- 1 | import tgpu from 'typegpu'; 2 | import * as d from 'typegpu/data'; 3 | import * as std from 'typegpu/std'; 4 | 5 | export const unpackVec2u = tgpu['~unstable'].fn([d.vec2u], d.vec4f)( 6 | (packed) => { 7 | const xy = std.unpack2x16float(packed.x); 8 | const zw = std.unpack2x16float(packed.y); 9 | return d.vec4f(xy, zw); 10 | }, 11 | ); 12 | 13 | export const packVec2u = tgpu['~unstable'].fn([d.vec4f], d.vec2u)((toPack) => { 14 | const xy = std.pack2x16float(toPack.xy); 15 | const zw = std.pack2x16float(toPack.zw); 16 | return d.vec2u(xy, zw); 17 | }); 18 | 19 | export const getAverageNormal = tgpu['~unstable'].fn([ 20 | d.vec4f, 21 | d.vec4f, 22 | d.vec4f, 23 | ], d.vec4f)((v1, v2, v3) => { 24 | 'kernel & js'; 25 | const edge1 = std.sub(v2.xyz, v1.xyz); 26 | const edge2 = std.sub(v3.xyz, v1.xyz); 27 | return std.normalize(d.vec4f(std.cross(edge1, edge2), 0)); 28 | }); 29 | 30 | export const calculateMidpoint = tgpu['~unstable'].fn( 31 | [d.vec4f, d.vec4f], 32 | d.vec4f, 33 | )((v1, v2) => { 34 | return d.vec4f(std.mul(0.5, std.add(v1.xyz, v2.xyz)), 1); 35 | }); 36 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/rendering/cubemap-reflection/index.html: -------------------------------------------------------------------------------- 1 | 31 |
    32 |

    Controls (click to dismiss)

    33 |

    Left Mouse Button: Look around

    34 |

    Scroll Wheel: Zoom in/out

    35 | 36 |

    37 | Uses textures by Emil "Humus" Persson
    38 | under CC BY 4.0 / Modified from original 39 |

    40 |
    41 | 42 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/rendering/cubemap-reflection/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Cubemap Reflection", 3 | "category": "rendering", 4 | "tags": ["experimental", "3d", "rasterization", "compute"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/rendering/cubemap-reflection/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/rendering/cubemap-reflection/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/rendering/function-visualizer/index.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/rendering/function-visualizer/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Function Visualizer", 3 | "category": "rendering", 4 | "tags": ["compute"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/rendering/function-visualizer/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/rendering/function-visualizer/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/rendering/perlin-noise/index.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/rendering/perlin-noise/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Perlin Noise", 3 | "category": "rendering", 4 | "tags": ["experimental"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/rendering/perlin-noise/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/rendering/perlin-noise/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/rendering/two-boxes/index.html: -------------------------------------------------------------------------------- 1 | 24 |
    25 |

    Controls

    26 |

    Left Mouse Button / Drag: Orbit camera

    27 |

    28 | Right Mouse Button / Two-Finger Drag: Rotate cubes 29 |

    30 |

    Scroll: Zoom

    31 |
    32 | 33 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/rendering/two-boxes/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Two Boxes", 3 | "category": "rendering", 4 | "tags": ["experimental", "3d", "rasterization"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/rendering/two-boxes/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/rendering/two-boxes/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simple/gradient-tiles/index.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simple/gradient-tiles/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Gradient Tiles", 3 | "category": "simple" 4 | } 5 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simple/gradient-tiles/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/simple/gradient-tiles/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simple/increment-tgsl/index.html: -------------------------------------------------------------------------------- 1 | I am incremented on the GPU! 2 |
    0 1 0
    3 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simple/increment-tgsl/index.ts: -------------------------------------------------------------------------------- 1 | import tgpu from 'typegpu'; 2 | import * as d from 'typegpu/data'; 3 | 4 | const table = document.querySelector('.counter') as HTMLDivElement; 5 | 6 | const root = await tgpu.init(); 7 | 8 | const counterBuffer = root 9 | .createBuffer(d.vec3f, d.vec3f(0, 1, 0)) 10 | .$usage('storage'); 11 | const counter = counterBuffer.as('mutable'); 12 | 13 | const increment = tgpu['~unstable'].computeFn({ 14 | in: { num: d.builtin.numWorkgroups }, 15 | workgroupSize: [1], 16 | })((input) => { 17 | const tmp = counter.value.x; 18 | counter.value.x = counter.value.y; 19 | counter.value.y += tmp; 20 | counter.value.z += d.f32(input.num.x); 21 | }); 22 | 23 | const pipeline = root['~unstable'].withCompute(increment).createPipeline(); 24 | 25 | async function doIncrement() { 26 | pipeline.dispatchWorkgroups(1); 27 | return await counterBuffer.read(); 28 | } 29 | 30 | export const controls = { 31 | Increment: { 32 | onButtonClick: async () => { 33 | const result = await doIncrement(); 34 | table.innerText = `${result.x} ${result.y} ${result.z}`; 35 | }, 36 | }, 37 | }; 38 | 39 | export function onCleanup() { 40 | root.destroy(); 41 | } 42 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simple/increment-tgsl/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Increment (TGSL)", 3 | "category": "simple", 4 | "tags": ["experimental", "compute"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simple/increment-tgsl/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/simple/increment-tgsl/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simple/increment/index.html: -------------------------------------------------------------------------------- 1 | I am incremented on the GPU! 2 |
    0
    3 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simple/increment/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Increment", 3 | "category": "simple", 4 | "tags": ["compute"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simple/increment/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/simple/increment/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simple/oklab/index.html: -------------------------------------------------------------------------------- 1 | 29 | 30 |
    31 |
    32 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simple/oklab/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Oklab (Color Space)", 3 | "category": "simple", 4 | "tags": ["experimental"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simple/oklab/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/simple/oklab/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simple/triangle/index.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simple/triangle/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Triangle", 3 | "category": "simple", 4 | "tags": ["experimental"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simple/triangle/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/simple/triangle/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/boids-next/index.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/boids-next/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Boids (next)", 3 | "category": "simulation", 4 | "tags": ["experimental", "compute", "instancing", "double buffering"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/boids-next/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/simulation/boids-next/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/boids/index.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/boids/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Boids", 3 | "category": "simulation", 4 | "tags": ["compute", "instancing", "double buffering"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/boids/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/simulation/boids/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/confetti/index.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/confetti/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Confetti", 3 | "category": "simulation", 4 | "tags": ["experimental", "compute", "instancing"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/confetti/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/simulation/confetti/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/fluid-double-buffering/index.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/fluid-double-buffering/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Fluid (double-buffering)", 3 | "category": "simulation", 4 | "tags": ["experimental", "compute", "cellular automata", "double buffering"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/fluid-double-buffering/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/simulation/fluid-double-buffering/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/fluid-with-atomics/index.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/fluid-with-atomics/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Fluid (with atomics)", 3 | "category": "simulation", 4 | "tags": ["experimental", "compute", "cellular automata", "atomic operations"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/fluid-with-atomics/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/simulation/fluid-with-atomics/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/game-of-life/index.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/game-of-life/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Game of Life", 3 | "category": "simulation", 4 | "tags": ["cellular automata", "compute", "double buffering"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/game-of-life/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/simulation/game-of-life/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/gravity/enums.ts: -------------------------------------------------------------------------------- 1 | export const collisionBehaviors = { 2 | none: 0, 3 | bounce: 1, 4 | merge: 2, 5 | } as const; 6 | export type CollisionBehavior = keyof typeof collisionBehaviors; 7 | 8 | export const sphereTextureNames = [ 9 | 'sun', 10 | 'mercury', 11 | 'venus', 12 | 'earth', 13 | 'mars', 14 | 'jupiter', 15 | 'saturn', 16 | 'uranus', 17 | 'neptune', 18 | 'moon', 19 | 'ceres-fictional', 20 | 'haumea-fictional', 21 | ] as const; 22 | export type SphereTextureName = (typeof sphereTextureNames)[number]; 23 | 24 | export const presets = [ 25 | 'Solar System', 26 | 'Asteroids', 27 | 'Colliding asteroids', 28 | 'Bouncy dust', 29 | 'Merging dust', 30 | ] as const; 31 | export type Preset = (typeof presets)[number]; 32 | export const initialPreset: Preset = 'Solar System'; 33 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/gravity/index.html: -------------------------------------------------------------------------------- 1 | 31 |
    32 |

    Controls (click to dismiss)

    33 |

    Left Mouse Button: Look around

    34 |

    Scroll Wheel: Zoom in/out

    35 | 36 |

    37 | Uses textures by Solar System Scope
    38 | under CC BY 4.0 39 |

    40 |
    41 | 42 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/gravity/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Gravity", 3 | "category": "simulation", 4 | "tags": ["experimental"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/gravity/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/simulation/gravity/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/stable-fluid/index.html: -------------------------------------------------------------------------------- 1 | 26 |
    27 |

    Controls (click to dismiss)

    28 |

    Drag to stir the fluid.

    29 |
    30 | 31 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/stable-fluid/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Stable Fluids", 3 | "category": "simulation", 4 | "tags": ["experimental", "double buffering"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/stable-fluid/params.ts: -------------------------------------------------------------------------------- 1 | import * as d from 'typegpu/data'; 2 | import type { SimulationParams } from './types.ts'; 3 | 4 | export const N = 2048; 5 | export const SIM_N = N / 4; 6 | export const [WORKGROUP_SIZE_X, WORKGROUP_SIZE_Y] = [16, 16]; 7 | export const FORCE_SCALE = 1; 8 | export const RADIUS = SIM_N / 16; 9 | export const INK_AMOUNT = 0.02; 10 | 11 | export const params: SimulationParams = { 12 | dt: 0.5, 13 | viscosity: 0.000001, 14 | jacobiIter: 10, 15 | displayMode: 'image', 16 | paused: false, 17 | }; 18 | 19 | export const BrushParams = d.struct({ 20 | pos: d.vec2i, 21 | delta: d.vec2f, 22 | radius: d.f32, 23 | forceScale: d.f32, 24 | inkAmount: d.f32, 25 | }); 26 | 27 | export const ShaderParams = d.struct({ 28 | dt: d.f32, 29 | viscosity: d.f32, 30 | }); 31 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/stable-fluid/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/content/examples/simulation/stable-fluid/thumbnail.png -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/simulation/stable-fluid/types.ts: -------------------------------------------------------------------------------- 1 | export type DisplayMode = 'ink' | 'velocity' | 'image'; 2 | 3 | export type SimulationParams = { 4 | dt: number; 5 | viscosity: number; 6 | jacobiIter: number; 7 | displayMode: DisplayMode; 8 | paused: boolean; 9 | }; 10 | 11 | export type BrushState = { 12 | pos: [number, number]; 13 | delta: [number, number]; 14 | isDown: boolean; 15 | }; 16 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/tests/tgsl-parsing-test/index.html: -------------------------------------------------------------------------------- 1 | Press the button to run the tests! 2 |
    3 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/content/examples/tests/tgsl-parsing-test/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "TGSL parsing test", 3 | "category": "tests", 4 | "tags": ["experimental"] 5 | } 6 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/fonts/Aeonik-Air.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/fonts/Aeonik-Air.otf -------------------------------------------------------------------------------- /apps/typegpu-docs/src/fonts/Aeonik-AirItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/fonts/Aeonik-AirItalic.otf -------------------------------------------------------------------------------- /apps/typegpu-docs/src/fonts/Aeonik-Black.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/fonts/Aeonik-Black.otf -------------------------------------------------------------------------------- /apps/typegpu-docs/src/fonts/Aeonik-BlackItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/fonts/Aeonik-BlackItalic.otf -------------------------------------------------------------------------------- /apps/typegpu-docs/src/fonts/Aeonik-Bold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/fonts/Aeonik-Bold.otf -------------------------------------------------------------------------------- /apps/typegpu-docs/src/fonts/Aeonik-BoldItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/fonts/Aeonik-BoldItalic.otf -------------------------------------------------------------------------------- /apps/typegpu-docs/src/fonts/Aeonik-Light.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/fonts/Aeonik-Light.otf -------------------------------------------------------------------------------- /apps/typegpu-docs/src/fonts/Aeonik-LightItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/fonts/Aeonik-LightItalic.otf -------------------------------------------------------------------------------- /apps/typegpu-docs/src/fonts/Aeonik-Medium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/fonts/Aeonik-Medium.otf -------------------------------------------------------------------------------- /apps/typegpu-docs/src/fonts/Aeonik-MediumItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/fonts/Aeonik-MediumItalic.otf -------------------------------------------------------------------------------- /apps/typegpu-docs/src/fonts/Aeonik-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/fonts/Aeonik-Regular.otf -------------------------------------------------------------------------------- /apps/typegpu-docs/src/fonts/Aeonik-RegularItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/fonts/Aeonik-RegularItalic.otf -------------------------------------------------------------------------------- /apps/typegpu-docs/src/fonts/Aeonik-Thin.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/fonts/Aeonik-Thin.otf -------------------------------------------------------------------------------- /apps/typegpu-docs/src/fonts/Aeonik-ThinItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/apps/typegpu-docs/src/fonts/Aeonik-ThinItalic.otf -------------------------------------------------------------------------------- /apps/typegpu-docs/src/pages/benchmark/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { Image } from 'astro:assets'; 3 | import PageLayout from '../../layouts/PageLayout.astro'; 4 | import BenchmarkApp from './benchmark-app.tsx'; 5 | import TypeGPULogoDark from '../../assets/typegpu-logo-dark.svg'; 6 | --- 7 | 8 | 9 |

    10 | TypeGPU Logo 15 |

    — benchmark

    16 |

    17 | 18 | 19 |
    20 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/pages/examples/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { ExampleLayout } from '../../components/ExampleLayout'; 3 | import PageLayout from '../../layouts/PageLayout.astro'; 4 | --- 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/utils/examples/codeEditorShownAtom.ts: -------------------------------------------------------------------------------- 1 | import { atomWithStorage } from 'jotai/utils'; 2 | 3 | export const codeEditorShownAtom = atomWithStorage('code-editor-shown', true); 4 | export const codeEditorShownMobileAtom = atomWithStorage( 5 | 'code-editor-mobile-shown', 6 | false, 7 | ); 8 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/utils/examples/currentSnackbarAtom.ts: -------------------------------------------------------------------------------- 1 | import { atom } from 'jotai'; 2 | 3 | export const currentSnackbarAtom = atom(undefined); 4 | 5 | export const runWithCatchAtom = atom( 6 | null, 7 | async (_get, set, callback: () => unknown) => { 8 | try { 9 | await callback(); 10 | set(currentSnackbarAtom, undefined); 11 | } catch (err) { 12 | if (err instanceof Error) { 13 | set(currentSnackbarAtom, `${err.name}: ${err.message}`); 14 | } 15 | console.log(err); 16 | } 17 | }, 18 | ); 19 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/utils/examples/errors.ts: -------------------------------------------------------------------------------- 1 | export class ExecutionCancelledError extends Error { 2 | constructor() { 3 | super('Sandbox cancelled execution.'); 4 | 5 | // Set the prototype explicitly. 6 | Object.setPrototypeOf(this, ExecutionCancelledError.prototype); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/utils/examples/exampleState.ts: -------------------------------------------------------------------------------- 1 | import type { ExampleControlParam } from './exampleControlAtom.ts'; 2 | 3 | export type ExampleState = { 4 | dispose: () => void; 5 | controlParams: ExampleControlParam[]; 6 | }; 7 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/utils/examples/menuShownAtom.ts: -------------------------------------------------------------------------------- 1 | import { atomWithStorage } from 'jotai/utils'; 2 | 3 | export const menuShownAtom = atomWithStorage('menu-shown', true); 4 | export const menuShownMobileAtom = atomWithStorage('menu-shown-mobile', false); 5 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/utils/examples/types.ts: -------------------------------------------------------------------------------- 1 | import { type } from 'arktype'; 2 | 3 | export type ExampleMetadata = typeof ExampleMetadata.infer; 4 | export const ExampleMetadata = type({ 5 | title: 'string', 6 | category: 'string', 7 | 'tags?': 'string[]', 8 | }); 9 | 10 | export const exampleCategories = [ 11 | { key: 'simple', label: 'Simple' }, 12 | { key: 'rendering', label: 'Rendering' }, 13 | { key: 'image-processing', label: 'Image processing' }, 14 | { key: 'simulation', label: 'Simulation' }, 15 | { key: 'algorithms', label: 'Algorithms' }, 16 | { key: 'tests', label: 'Tests' }, 17 | ]; 18 | 19 | export type ExampleSrcFile = { 20 | exampleKey: string; 21 | path: string; 22 | content: string; 23 | }; 24 | 25 | export interface ThumbnailPair { 26 | small: string; 27 | large: string; 28 | } 29 | 30 | export type Example = { 31 | key: string; 32 | tsFiles: ExampleSrcFile[]; 33 | tsImport: () => Promise; 34 | htmlFile: ExampleSrcFile; 35 | metadata: ExampleMetadata; 36 | thumbnails?: ThumbnailPair; 37 | }; 38 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/utils/isGPUSupported.ts: -------------------------------------------------------------------------------- 1 | const adapter = await navigator.gpu?.requestAdapter(); 2 | adapter?.requestDevice().then((device) => device.destroy()); 3 | 4 | export const isGPUSupported = !!adapter; 5 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/utils/liveEditor/embeddedTypeScript.ts: -------------------------------------------------------------------------------- 1 | import { languages } from 'monaco-editor'; 2 | 3 | export const tsCompilerOptions: languages.typescript.CompilerOptions = { 4 | target: languages.typescript.ScriptTarget.ESNext, 5 | allowNonTsExtensions: true, 6 | strict: true, 7 | esModuleInterop: true, 8 | module: languages.typescript.ModuleKind.ESNext, 9 | noEmit: true, 10 | skipLibCheck: true, 11 | exactOptionalPropertyTypes: true, 12 | baseUrl: '.', 13 | lib: ['dom', 'es2021'], 14 | }; 15 | -------------------------------------------------------------------------------- /apps/typegpu-docs/src/utils/useEvent.ts: -------------------------------------------------------------------------------- 1 | import { useCallback, useLayoutEffect, useRef } from 'react'; 2 | 3 | /** 4 | * Approximate behavior of the upcoming `useEvent` React hook. 5 | * WARNING: Do not use in the render phase, nor in `useLayoutEffect` calls. 6 | * @param handler 7 | * @returns A stable reference of the passed in function. 8 | */ 9 | 10 | // biome-ignore lint/suspicious/noExplicitAny: 11 | function useEvent any>( 12 | handler: TFunction, 13 | ) { 14 | const handlerRef = useRef(handler); 15 | 16 | // In a real implementation, this would run before layout effects 17 | useLayoutEffect(() => { 18 | handlerRef.current = handler; 19 | }); 20 | 21 | return useCallback((...args: Parameters) => { 22 | // In a real implementation, this would throw if called during render 23 | const fn = handlerRef.current; 24 | return fn(...args); 25 | }, []) as TFunction; 26 | } 27 | 28 | export default useEvent; 29 | -------------------------------------------------------------------------------- /apps/typegpu-docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict", 3 | "compilerOptions": { 4 | "jsx": "react-jsx", 5 | "jsxImportSource": "react", 6 | "typeRoots": [ 7 | "./node_modules/@webgpu/types", 8 | "./node_modules/@types", 9 | "src/types" 10 | ] 11 | }, 12 | "include": [".astro/types.d.ts", "**/*"], 13 | "exclude": ["dist"] 14 | } 15 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = (api, targets) => { 2 | // https://babeljs.io/docs/en/config-files#config-function-api 3 | const isTestEnv = api.env('test'); 4 | 5 | return { 6 | babelrc: false, 7 | ignore: ['./node_modules'], 8 | presets: [ 9 | [ 10 | '@babel/preset-env', 11 | { 12 | loose: true, 13 | modules: isTestEnv ? 'commonjs' : false, 14 | targets: isTestEnv ? { node: 'current' } : targets, 15 | }, 16 | ], 17 | ], 18 | plugins: [['@babel/plugin-transform-typescript', { isTSX: true }]], 19 | }; 20 | }; 21 | -------------------------------------------------------------------------------- /biome.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", 3 | "organizeImports": { 4 | "enabled": true 5 | }, 6 | "files": { 7 | "ignore": [ 8 | "**/dist/*", 9 | "**/coverage/*", 10 | "**/*.d.ts", 11 | "packages/tgpu-wgsl-parser/src/grammar.ts", 12 | "**/*.astro" 13 | ] 14 | }, 15 | "linter": { 16 | "enabled": true, 17 | "rules": { 18 | "recommended": true, 19 | "correctness": { 20 | "noUnusedImports": "error", 21 | "useImportExtensions": "error" 22 | }, 23 | "nursery": { 24 | "useSortedClasses": { 25 | "level": "error", 26 | "fix": "safe", 27 | "options": { 28 | "attributes": ["className"], 29 | "functions": ["cs"] 30 | } 31 | } 32 | } 33 | } 34 | }, 35 | "json": { 36 | "formatter": { 37 | "indentStyle": "space" 38 | } 39 | }, 40 | "javascript": { 41 | "formatter": { 42 | "indentStyle": "space", 43 | "quoteStyle": "single" 44 | } 45 | }, 46 | "css": { 47 | "formatter": { 48 | "indentStyle": "space", 49 | "quoteStyle": "single" 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /deno.json: -------------------------------------------------------------------------------- 1 | { 2 | "fmt": { 3 | "singleQuote": true, 4 | "exclude": ["pnpm-lock.yaml"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/tgpu-dev-cli/colors.mjs: -------------------------------------------------------------------------------- 1 | const colors = { 2 | Reset: '\u001b[0m', 3 | 4 | Black: '\u001b[30m', 5 | Red: '\u001b[31m', 6 | Green: '\u001b[32m', 7 | Yellow: '\u001b[33m', 8 | Blue: '\u001b[34m', 9 | Magenta: '\u001b[35m', 10 | Cyan: '\u001b[36m', 11 | White: '\u001b[37m', 12 | 13 | BrightBlack: '\u001b[30;1m', 14 | BrightRed: '\u001b[31;1m', 15 | BrightGreen: '\u001b[32;1m', 16 | BrightYellow: '\u001b[33;1m', 17 | BrightBlue: '\u001b[34;1m', 18 | BrightMagenta: '\u001b[35;1m', 19 | BrightCyan: '\u001b[36;1m', 20 | BrightWhite: '\u001b[37;1m', 21 | 22 | BgBlack: '\u001b[40m', 23 | BgRed: '\u001b[41m', 24 | BgGreen: '\u001b[42m', 25 | BgYellow: '\u001b[43m', 26 | BgBlue: '\u001b[44m', 27 | BgMagenta: '\u001b[45m', 28 | BgCyan: '\u001b[46m', 29 | BgWhite: '\u001b[47m', 30 | 31 | BgBrightBlack: '\u001b[40;1m', 32 | BgBrightRed: '\u001b[41;1m', 33 | BgBrightGreen: '\u001b[42;1m', 34 | BgBrightYellow: '\u001b[43;1m', 35 | BgBrightBlue: '\u001b[44;1m', 36 | BgBrightMagenta: '\u001b[45;1m', 37 | BgBrightCyan: '\u001b[46;1m', 38 | BgBrightWhite: '\u001b[47;1m', 39 | 40 | Bold: '\u001b[1m', 41 | }; 42 | 43 | export default colors; 44 | -------------------------------------------------------------------------------- /packages/tgpu-dev-cli/deno.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": ["."], 3 | "fmt": { 4 | "exclude": ["!."], 5 | "singleQuote": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/tgpu-dev-cli/icons.mjs: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | import isUnicodeSupported from 'is-unicode-supported'; 4 | 5 | const unicode = isUnicodeSupported(); 6 | const s = (/** @type {string} */ c, /** @type {string} */ fallback) => 7 | unicode ? c : fallback; 8 | 9 | export const IN_PROGRESS = s('◐', 'o'); 10 | export const SUCCESS = s('✔', '√'); 11 | export const FAIL = s('✖', '×'); 12 | -------------------------------------------------------------------------------- /packages/tgpu-dev-cli/index.mjs: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | /** 4 | * @typedef {Object} BuildScriptEnv 5 | * @prop {boolean} inDevMode 6 | */ 7 | 8 | /** 9 | * @returns {BuildScriptEnv} 10 | */ 11 | export function initBuildScript() { 12 | const inDevMode = process.env.DEV === 'true'; 13 | 14 | console.log(`-= ${inDevMode ? 'DEVELOPMENT' : 'PRODUCTION'} MODE =-`); 15 | 16 | return { 17 | inDevMode, 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /packages/tgpu-dev-cli/log.mjs: -------------------------------------------------------------------------------- 1 | export const Frog = '( ◦°^°◦)'; 2 | -------------------------------------------------------------------------------- /packages/tgpu-dev-cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@typegpu/tgpu-dev-cli", 3 | "private": true, 4 | "version": "0.0.0", 5 | "description": "A set of tools used to aid in developing TypeGPU.", 6 | "license": "MIT", 7 | "bin": { 8 | "tgpu-dev-cli": "./tgpu-dev-cli.mjs" 9 | }, 10 | "type": "module", 11 | "main": "./index.mjs", 12 | "sideEffects": false, 13 | "engines": { 14 | "node": ">=12.20.0" 15 | }, 16 | "dependencies": { 17 | "arg": "^5.0.2", 18 | "arktype": "catalog:", 19 | "consola": "^3.4.0", 20 | "execa": "^9.6.0", 21 | "is-unicode-supported": "^2.1.0", 22 | "pkg-types": "^2.1.0", 23 | "remeda": "^2.21.2" 24 | }, 25 | "packageManager": "pnpm@10.4.1+sha512.c753b6c3ad7afa13af388fa6d808035a008e30ea9993f58c6663e2bc5ff21679aa834db094987129aa4d488b86df57f7b634981b2f827cdcacc698cc0cfb88af" 26 | } 27 | -------------------------------------------------------------------------------- /packages/tgpu-dev-cli/progress.mjs: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | /** 4 | * @typedef {object} ProgressTracker 5 | * @prop {string} value 6 | * @prop {() => void} end 7 | */ 8 | 9 | /** 10 | * @template T 11 | * @param {string} initial 12 | * @param {(update: (val: string) => void) => Promise} task 13 | * @returns {Promise} 14 | */ 15 | export async function progress(initial, task) { 16 | const ciMode = typeof process.stdout.clearLine !== 'function' || 17 | typeof process.stdout.cursorTo !== 'function'; 18 | 19 | if (ciMode) { 20 | console.log(initial); 21 | return await task((val) => { 22 | console.log(val); 23 | }); 24 | } 25 | 26 | process.stdout.write(initial); 27 | 28 | try { 29 | return await task((val) => { 30 | if ( 31 | process.stdout.clearLine && 32 | typeof process.stdout.clearLine === 'function' 33 | ) { 34 | process.stdout.clearLine(0); 35 | } 36 | process.stdout.cursorTo(0); 37 | process.stdout.write(val); 38 | }); 39 | } finally { 40 | process.stdout.write('\n'); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/tgpu-dev-cli/tgpu-dev-cli.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import { exit } from 'node:process'; 3 | import arg from 'arg'; 4 | 5 | import color from './colors.mjs'; 6 | import { Frog } from './log.mjs'; 7 | import prepack from './prepack.mjs'; 8 | 9 | if (!process.env.npm_config_user_agent.startsWith('pnpm')) { 10 | console.error( 11 | 'This script must be executed by pnpm! Make sure to `pnpm run ...` instead of `npm run ...`', 12 | ); 13 | process.exit(1); 14 | } 15 | 16 | const args = arg({}, { permissive: true }); 17 | 18 | const COMMANDS = { 19 | prepack: { 20 | execute: prepack, 21 | }, 22 | }; 23 | 24 | function printHelp() { 25 | console.log(`${color.Blue}\ 26 | ---------------------------- 27 | 28 | ${Frog} TypeGPU Dev CLI 29 | 30 | ---------------------------- 31 | ${color.Reset} 32 | 33 | ${color.Bold}Commands:${color.Reset} 34 | tgpu-dev-cli prepack Builds and prepares a package for publishing. 35 | `); 36 | } 37 | 38 | /** @type {keyof typeof COMMANDS} */ 39 | const command = args._[0]; // first positional argument 40 | if (!command) { 41 | printHelp(); 42 | exit(1); 43 | } 44 | 45 | if (!(command in COMMANDS)) { 46 | console.log( 47 | `\n${Frog}: Unknown command: ${color.Yellow}${command}${color.Reset}\n`, 48 | ); 49 | exit(1); 50 | } 51 | 52 | await COMMANDS[command].execute(); 53 | -------------------------------------------------------------------------------- /packages/tgpu-dev-cli/verify-publish-tag.mjs: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | import { type } from 'arktype'; 4 | import { readPackageJSON } from 'pkg-types'; 5 | 6 | const PublishTags = /** @type {const} */ (['alpha', 'beta']); 7 | 8 | const PublishTag = type.or( 9 | 'undefined', 10 | ...PublishTags.map((tag) => /** @type {const} */ (`"${tag}"`)), 11 | ); 12 | 13 | const packageJSON = await readPackageJSON(); 14 | const chosenPublishTag = PublishTag.assert(process.env.npm_config_tag); 15 | 16 | export function verifyPublishTag() { 17 | let tagVerified = false; 18 | for (const tag of PublishTags) { 19 | if (packageJSON.version?.includes(tag)) { 20 | if (tag !== chosenPublishTag) { 21 | throw new Error( 22 | `Publishing under a mismatched tag "${chosenPublishTag}" for version ${packageJSON.version}. Use --tag ${tag}`, 23 | ); 24 | } 25 | 26 | tagVerified = true; 27 | break; 28 | } 29 | } 30 | 31 | if (!tagVerified && chosenPublishTag !== undefined) { 32 | throw new Error( 33 | `Publishing under a mismatched tag "${chosenPublishTag}" for version ${packageJSON.version}.`, 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/tgpu-gen/LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Software Mansion 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /packages/tgpu-gen/README.md: -------------------------------------------------------------------------------- 1 | # tgpu-gen 2 | 3 | A CLI tool for automatic [TypeGPU](https://docs.swmansion.com/TypeGPU) code 4 | generation. 5 | 6 | ## Documentation 7 | 8 | To see the full usage documentation, visit our chapter on 9 | [Generator CLI](https://docs.swmansion.com/TypeGPU/tooling/tgpu-gen) in the 10 | TypeGPU docs. 11 | 12 | ## TypeGPU is created by Software Mansion 13 | 14 | [![swm](https://logo.swmansion.com/logo?color=white&variant=desktop&width=150&tag=typegpu-github 'Software Mansion')](https://swmansion.com) 15 | 16 | Since 2012 [Software Mansion](https://swmansion.com) is a software agency with 17 | experience in building web and mobile apps. We are Core React Native 18 | Contributors and experts in dealing with all kinds of React Native issues. We 19 | can help you build your next dream product – 20 | [Hire us](https://swmansion.com/contact/projects?utm_source=typegpu&utm_medium=readme). 21 | -------------------------------------------------------------------------------- /packages/tgpu-gen/colors.mjs: -------------------------------------------------------------------------------- 1 | const colors = { 2 | Reset: '\u001b[0m', 3 | 4 | Black: '\u001b[30m', 5 | Red: '\u001b[31m', 6 | Green: '\u001b[32m', 7 | Yellow: '\u001b[33m', 8 | Blue: '\u001b[34m', 9 | Magenta: '\u001b[35m', 10 | Cyan: '\u001b[36m', 11 | White: '\u001b[37m', 12 | 13 | BrightBlack: '\u001b[30;1m', 14 | BrightRed: '\u001b[31;1m', 15 | BrightGreen: '\u001b[32;1m', 16 | BrightYellow: '\u001b[33;1m', 17 | BrightBlue: '\u001b[34;1m', 18 | BrightMagenta: '\u001b[35;1m', 19 | BrightCyan: '\u001b[36;1m', 20 | BrightWhite: '\u001b[37;1m', 21 | 22 | BgBlack: '\u001b[40m', 23 | BgRed: '\u001b[41m', 24 | BgGreen: '\u001b[42m', 25 | BgYellow: '\u001b[43m', 26 | BgBlue: '\u001b[44m', 27 | BgMagenta: '\u001b[45m', 28 | BgCyan: '\u001b[46m', 29 | BgWhite: '\u001b[47m', 30 | 31 | BgBrightBlack: '\u001b[40;1m', 32 | BgBrightRed: '\u001b[41;1m', 33 | BgBrightGreen: '\u001b[42;1m', 34 | BgBrightYellow: '\u001b[43;1m', 35 | BgBrightBlue: '\u001b[44;1m', 36 | BgBrightMagenta: '\u001b[45;1m', 37 | BgBrightCyan: '\u001b[46;1m', 38 | BgBrightWhite: '\u001b[47;1m', 39 | 40 | Bold: '\u001b[1m', 41 | }; 42 | 43 | export default colors; 44 | -------------------------------------------------------------------------------- /packages/tgpu-gen/deno.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": ["."], 3 | "fmt": { 4 | "exclude": ["!."], 5 | "singleQuote": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/tgpu-gen/outputPathCompiler.mjs: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | import path from 'node:path'; 4 | 5 | /** 6 | * @param {string} input 7 | * @param {string} output 8 | * @returns {(file: string) => string} 9 | */ 10 | export const createOutputPathCompiler = (input, output) => { 11 | return output.includes(path.sep) 12 | ? /\*\*\/.*\*.*/.test(output) // "**/" and "*" used in pattern 13 | ? (file) => { 14 | // retrieve what ** was matched as 15 | const matched = new RegExp( 16 | input 17 | .replace(/\*/g, '\\*') 18 | .replace('\\*\\*', '(?.*)') 19 | .replace('\\*', '.*'), 20 | ).exec(file); 21 | const dir = matched ? matched[1] : undefined; 22 | 23 | return ( 24 | dir === undefined 25 | ? output.replace('**/', '') 26 | : output.replace('**', dir) 27 | ).replace('*', path.parse(file).name); 28 | } 29 | : (file) => output.replace('*', path.parse(file).name) // no "**"" placeholder, flattening to the same directory 30 | : (file) => { 31 | const parsed = path.parse(file); 32 | return path.join(parsed.dir, output.replace('*', parsed.name)); // no path separator -> output in the same directory as input 33 | }; 34 | }; 35 | -------------------------------------------------------------------------------- /packages/tgpu-gen/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tgpu-gen", 3 | "version": "0.1.2", 4 | "description": "A CLI tool for automatic TypeGPU code generation.", 5 | "license": "MIT", 6 | "bin": { 7 | "tgpu-gen": "./tgpu-gen.mjs" 8 | }, 9 | "sideEffects": false, 10 | "engines": { 11 | "node": ">=12.20.0" 12 | }, 13 | "dependencies": { 14 | "arg": "^5.0.2", 15 | "chokidar": "^4.0.1", 16 | "glob": "^11.0.2", 17 | "remeda": "^2.21.2", 18 | "wgsl_reflect": "git://github.com/mhawryluk/wgsl_reflect.git#85994fdc8d8a3abbb4f79baf3891e54eed0c1c63" 19 | }, 20 | "peerDependencies": { 21 | "typegpu": "workspace:^0.5.8" 22 | }, 23 | "files": ["README.md", "LICENSE.md", "package.json", "**/*.mjs"], 24 | "devDependencies": { 25 | "vitest": "catalog:" 26 | }, 27 | "packageManager": "pnpm@10.4.1+sha512.c753b6c3ad7afa13af388fa6d808035a008e30ea9993f58c6663e2bc5ff21679aa834db094987129aa4d488b86df57f7b634981b2f827cdcacc698cc0cfb88af" 28 | } 29 | -------------------------------------------------------------------------------- /packages/tgpu-gen/tests/alias.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { generate } from '../gen.mjs'; 3 | 4 | describe('aliases generator', () => { 5 | it('generates alias definitions from wgsl', () => { 6 | const wgsl = ` 7 | struct TriangleData { 8 | pos: vec3f, 9 | } 10 | 11 | alias Triangle = TriangleData; 12 | alias u = u32; 13 | alias ArrayDoubleU32 = array; 14 | `; 15 | const generated = generate(wgsl); 16 | 17 | expect(generated).toContain('const Triangle = TriangleData;'); 18 | expect(generated).toContain('const u = d.u32;'); 19 | expect(generated).toContain('const ArrayDoubleU32 = d.arrayOf(d.u32, 2);'); 20 | }); 21 | 22 | it('replaces types with predeclared aliases', () => { 23 | expect(generate('alias v3u = vec3;')).toContain('const v3u = d.vec3u'); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/tgpu-gen/tests/functions.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { generate } from '../gen.mjs'; 3 | 4 | describe('functions generator', () => { 5 | it('generates function definitions from wgsl', () => { 6 | const wgsl = `\ 7 | fn rotate(v: vec2f, angle: f32) -> vec2f { 8 | let pos = vec2( 9 | (v.x * cos(angle)) - (v.y * sin(angle)), 10 | (v.x * sin(angle)) + (v.y * cos(angle)), 11 | ); 12 | return pos; 13 | }`; 14 | 15 | expect(generate(wgsl)).toContain(`\ 16 | export const rotate = tgpu['~unstable'].fn([d.vec2f, d.f32], d.vec2f)(/* wgsl */ \`(v: vec2f, angle: f32) -> vec2f { 17 | let pos = vec2( 18 | (v.x * cos(angle)) - (v.y * sin(angle)), 19 | (v.x * sin(angle)) + (v.y * cos(angle)), 20 | ); 21 | return pos; 22 | }\`);`); 23 | }); 24 | 25 | it('generates function with no arguments and return type', () => { 26 | const wgsl = `\ 27 | fn foo() { 28 | let x = vec3f(); 29 | }`; 30 | 31 | expect(generate(wgsl)).toContain(`\ 32 | export const foo = tgpu['~unstable'].fn([])(/* wgsl */ \`() { 33 | let x = vec3f(); 34 | }\`);`); 35 | }); 36 | 37 | it('adds tgpu import', () => { 38 | const wgsl = 'fn f() {}'; 39 | expect(generate(wgsl)).toContain("import tgpu from 'typegpu';"); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /packages/tgpu-gen/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["**/*"], 4 | "exclude": ["node_modules"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/tgpu-jit/README.md: -------------------------------------------------------------------------------- 1 | # tgpu-jit 2 | 3 | A Just-In-Time (JIT) transpiler for TypeGPU. Allows users to test out TestGPU 4 | without a build-step at the cost of memory and efficiency. 5 | -------------------------------------------------------------------------------- /packages/tgpu-jit/deno.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": ["."], 3 | "fmt": { 4 | "exclude": ["!."], 5 | "singleQuote": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/tgpu-jit/src/index.ts: -------------------------------------------------------------------------------- 1 | import { parse } from 'acorn'; 2 | import type { AnyNode, Block, FuncParameter } from 'tinyest'; 3 | import { transpileFn, transpileNode } from 'tinyest-for-wgsl'; 4 | 5 | /** 6 | * Information extracted from transpiling a JS function. 7 | */ 8 | type TranspilationResult = { 9 | params: FuncParameter[]; 10 | body: Block; 11 | /** 12 | * All identifiers found in the function code that are not declared in the 13 | * function itself, or in the block that is accessing that identifier. 14 | */ 15 | externalNames: string[]; 16 | }; 17 | 18 | /** 19 | * Used to transpile JS resources into tinyest on demand. 20 | */ 21 | interface IJitTranspiler { 22 | transpileFn(rawJs: string): TranspilationResult; 23 | transpile(rawJs: string): AnyNode; 24 | } 25 | 26 | export class JitTranspiler implements IJitTranspiler { 27 | transpileFn(rawJs: string): TranspilationResult { 28 | const program = parse(rawJs, { ecmaVersion: 'latest' }); 29 | return transpileFn(program); 30 | } 31 | 32 | transpile(rawJs: string): AnyNode { 33 | const program = parse(rawJs, { ecmaVersion: 'latest' }); 34 | return transpileNode(program); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/tgpu-jit/tests/foo.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | 3 | // TODO: Test things 4 | describe('foo', () => { 5 | it('works', () => { 6 | expect(1 + 1).toBe(2); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/tgpu-jit/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "typeRoots": ["./node_modules/@types"] 5 | }, 6 | "include": ["src/**/*"], 7 | "exclude": ["node_modules", "dist"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/tgpu-jit/tsconfig.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "typeRoots": ["./node_modules/@types"] 5 | }, 6 | "include": ["src/**/*", "tests/**/*"], 7 | "exclude": ["node_modules", "dist"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/tgpu-jit/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { initBuildScript } from '@typegpu/tgpu-dev-cli'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | const { inDevMode } = initBuildScript(); 5 | 6 | export default defineConfig({ 7 | entry: ['src/index.ts'], 8 | outDir: 'dist', 9 | format: ['cjs', 'esm'], 10 | tsconfig: './tsconfig.json', 11 | target: 'es2017', 12 | splitting: true, 13 | sourcemap: true, 14 | minify: !inDevMode, 15 | clean: !inDevMode, 16 | dts: true, 17 | }); 18 | -------------------------------------------------------------------------------- /packages/tgpu-wgsl-parser/deno.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": ["."], 3 | "fmt": { 4 | "exclude": ["!."], 5 | "singleQuote": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/tgpu-wgsl-parser/nearley-redirect-plugin.mjs: -------------------------------------------------------------------------------- 1 | import * as path from 'node:path'; 2 | 3 | /** 4 | * Redirects all imports of files that end in '.ne' 5 | * into imports of their corresponding '.ts' files. 6 | */ 7 | export default function nearleyRedirectPlugin() { 8 | return { 9 | name: 'nearley-redirect', 10 | enforce: /** @type {const} */ ('pre'), 11 | 12 | /** 13 | * @param {string} source 14 | * @param {string=} importer 15 | * @returns {{ id: string } | undefined} 16 | */ 17 | resolveId(source, importer) { 18 | if (source.endsWith('.ne')) { 19 | const abs = importer 20 | ? path.join(path.dirname(importer), source) 21 | : source; 22 | 23 | return { 24 | id: abs.replace(/\.ne$/, '.ts'), 25 | }; 26 | } 27 | }, 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /packages/tgpu-wgsl-parser/src/grammar.ne.d.ts: -------------------------------------------------------------------------------- 1 | export * from './grammar'; 2 | export { default } from './grammar'; 3 | -------------------------------------------------------------------------------- /packages/tgpu-wgsl-parser/src/index.ts: -------------------------------------------------------------------------------- 1 | import nearley from 'nearley'; 2 | import grammar, { type Main } from './grammar.ne'; 3 | 4 | export function parse(code: string): Main { 5 | const parser = new nearley.Parser(nearley.Grammar.fromCompiled(grammar)); 6 | parser.feed(code); 7 | 8 | return parser.results[0]; 9 | } 10 | 11 | export type * from './grammar.ne'; 12 | -------------------------------------------------------------------------------- /packages/tgpu-wgsl-parser/tests/boolLiteral.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import type { BoolLiteral } from '../src/grammar.ts'; 3 | import { parse } from '../src/index.ts'; 4 | 5 | describe('bool_literal', () => { 6 | it('parses "true"', () => { 7 | expect(parse('true')).toStrictEqual( 8 | { 9 | type: 'bool_literal', 10 | value: 'true', 11 | } satisfies BoolLiteral, 12 | ); 13 | }); 14 | 15 | it('parses "false"', () => { 16 | expect(parse('false')).toStrictEqual( 17 | { 18 | type: 'bool_literal', 19 | value: 'false', 20 | } satisfies BoolLiteral, 21 | ); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/tgpu-wgsl-parser/tests/floatLiteral.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import type { FloatLiteral } from '../src/grammar.ts'; 3 | import { parse } from '../src/index.ts'; 4 | 5 | describe('float_literal', () => { 6 | const EXAMPLE_FLOAT_LITERALS = [ 7 | // decimal 8 | '0.e+4f', 9 | '01.', 10 | '.01', 11 | '12.34', 12 | '.0f', 13 | '0h', 14 | '1e-3', 15 | // hex 16 | '0xa.fp+2', 17 | '0x1P+4f', 18 | '0X.3', 19 | '0x3p+2h', 20 | '0X1.fp-4', 21 | '0x3.2p+2h', 22 | ]; 23 | 24 | it('parses float', () => { 25 | for (const exampleFloat of EXAMPLE_FLOAT_LITERALS) { 26 | expect(parse(exampleFloat)).toStrictEqual( 27 | { 28 | type: 'float_literal', 29 | value: exampleFloat, 30 | } satisfies FloatLiteral, 31 | ); 32 | } 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /packages/tgpu-wgsl-parser/tests/intLiteral.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import type { IntLiteral } from '../src/grammar.ts'; 3 | import { parse } from '../src/index.ts'; 4 | 5 | describe('int_literal', () => { 6 | it('parses decimal unsigned ints', () => { 7 | expect(parse('0u')).toStrictEqual( 8 | { 9 | type: 'int_literal', 10 | value: '0u', 11 | } satisfies IntLiteral, 12 | ); 13 | 14 | expect(parse('123u')).toStrictEqual( 15 | { 16 | type: 'int_literal', 17 | value: '123u', 18 | } satisfies IntLiteral, 19 | ); 20 | }); 21 | 22 | it('parses decimal signed ints', () => { 23 | expect(parse('0')).toStrictEqual( 24 | { 25 | type: 'int_literal', 26 | value: '0', 27 | } satisfies IntLiteral, 28 | ); 29 | 30 | expect(parse('0i')).toStrictEqual( 31 | { 32 | type: 'int_literal', 33 | value: '0i', 34 | } satisfies IntLiteral, 35 | ); 36 | 37 | expect(parse('123')).toStrictEqual( 38 | { 39 | type: 'int_literal', 40 | value: '123', 41 | } satisfies IntLiteral, 42 | ); 43 | 44 | expect(parse('123i')).toStrictEqual( 45 | { 46 | type: 'int_literal', 47 | value: '123i', 48 | } satisfies IntLiteral, 49 | ); 50 | }); 51 | }); 52 | -------------------------------------------------------------------------------- /packages/tgpu-wgsl-parser/tests/returnStatement.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import type { ReturnStatement } from '../src/grammar.ts'; 3 | import { parse } from '../src/index.ts'; 4 | 5 | describe('return_statement', () => { 6 | it('parses empty return', () => { 7 | expect(parse('return;')).toStrictEqual( 8 | { 9 | type: 'return_statement', 10 | expression: null, 11 | } satisfies ReturnStatement, 12 | ); 13 | }); 14 | 15 | it('parses return of literal', () => { 16 | expect(parse('return 123;')).toStrictEqual( 17 | { 18 | type: 'return_statement', 19 | expression: { 20 | type: 'int_literal', 21 | value: '123', 22 | }, 23 | } satisfies ReturnStatement, 24 | ); 25 | }); 26 | 27 | it('parses return of math operation', () => { 28 | expect(parse('return 10. * 0.5;')).toStrictEqual( 29 | { 30 | type: 'return_statement', 31 | expression: { 32 | type: 'multiply', 33 | lhs: { type: 'float_literal', value: '10.' }, 34 | rhs: { type: 'float_literal', value: '0.5' }, 35 | }, 36 | } satisfies ReturnStatement, 37 | ); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /packages/tgpu-wgsl-parser/tests/valueDecl.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import type { ValueDecl } from '../src/grammar.ts'; 3 | import { parse } from '../src/index.ts'; 4 | 5 | describe('value_decl', () => { 6 | it('parses non-typed', () => { 7 | expect(parse('const example = 123;')).toStrictEqual( 8 | { 9 | type: 'value_decl', 10 | ident: 'example', 11 | typespec: null, 12 | expr: { 13 | type: 'int_literal', 14 | value: '123', 15 | }, 16 | } satisfies ValueDecl, 17 | ); 18 | }); 19 | 20 | it('parses typed', () => { 21 | expect(parse('const example: i32 = 123;')).toStrictEqual( 22 | { 23 | type: 'value_decl', 24 | ident: 'example', 25 | typespec: { 26 | type: 'template_elaborated_ident', 27 | ident: 'i32', 28 | template_list: null, 29 | }, 30 | expr: { 31 | type: 'int_literal', 32 | value: '123', 33 | }, 34 | } satisfies ValueDecl, 35 | ); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /packages/tgpu-wgsl-parser/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "typeRoots": ["./node_modules/@webgpu/types", "./node_modules/@types"] 5 | }, 6 | "include": ["src/**/*", "tests/**/*"], 7 | "exclude": ["node_modules", "dist"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/tgpu-wgsl-parser/vitest.config.mts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config'; 2 | import nearleyRedirectPlugin from './nearley-redirect-plugin.mjs'; 3 | 4 | export default defineConfig({ 5 | plugins: [nearleyRedirectPlugin()], 6 | }); 7 | -------------------------------------------------------------------------------- /packages/tinyest-for-wgsl/README.md: -------------------------------------------------------------------------------- 1 | # tinyest-for-wgsl 2 | 3 | Transforms JavaScript into its 'tinyest' form, to be used in generating 4 | equivalent (or close to) WGSL code. Used by 5 | [**TypeGPU**](https://docs.swmansion.com/TypeGPU) to allow for shaders to be 6 | written in JS. 7 | 8 | ## Basic principles 9 | 10 | `tinyest-for-wgsl` is responsible for transforming JS function bodies of TypeGPU 11 | declarations (e.g., `tgpu.fn`) into an embeddable syntax tree, gathering 12 | external names outside of the scope of the function. 13 | 14 | ```ts 15 | `(a, b) => { 16 | return a + b + double(a); 17 | }`; 18 | ``` 19 | 20 | This can then be used to generate the following Embeddable Syntax Tree: 21 | 22 | ```js 23 | // Can be injected with a simple JSON.stringify of a value that can be computed in the Rollup plugin. 24 | { 25 | b: [{ r: { x: [{ x: ['a', '+', 'b'] }, '+', { f: ['double', ['a']] }] } }]; 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /packages/tinyest-for-wgsl/deno.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": ["."], 3 | "fmt": { 4 | "exclude": ["!."], 5 | "singleQuote": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/tinyest-for-wgsl/src/index.ts: -------------------------------------------------------------------------------- 1 | export { transpileFn, transpileNode } from './parsers.ts'; 2 | -------------------------------------------------------------------------------- /packages/tinyest-for-wgsl/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": {}, 4 | "include": ["src/**/*"], 5 | "exclude": ["node_modules", "dist"] 6 | } 7 | -------------------------------------------------------------------------------- /packages/tinyest-for-wgsl/tsconfig.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": {}, 4 | "include": ["src/**/*", "tests/**/*"], 5 | "exclude": ["node_modules", "dist"] 6 | } 7 | -------------------------------------------------------------------------------- /packages/tinyest-for-wgsl/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { initBuildScript } from '@typegpu/tgpu-dev-cli'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | const { inDevMode } = initBuildScript(); 5 | 6 | export default defineConfig({ 7 | entry: ['src/index.ts'], 8 | outDir: 'dist', 9 | format: ['cjs', 'esm'], 10 | tsconfig: './tsconfig.json', 11 | target: 'es2017', 12 | splitting: true, 13 | sourcemap: true, 14 | minify: !inDevMode, 15 | clean: !inDevMode, 16 | dts: true, 17 | }); 18 | -------------------------------------------------------------------------------- /packages/tinyest/README.md: -------------------------------------------------------------------------------- 1 |
    2 | 3 | # tinyest 4 | 5 | Tiny Embeddable Syntax Tree - 6 | [GitHub](https://github.com/software-mansion/TypeGPU/tree/main/packages/tinyest) 7 | 8 |
    9 | 10 | **WIP: Under Construction** 11 | 12 | A compact, fast, and embeddable JavaScript AST for transpilation. 13 | 14 | ### Projects using tinyest 15 | 16 | - [TypeGPU](https://typegpu.com) - A TypeScript library that enhances the WebGPU 17 | API, allowing resource management in a type-safe way. 18 | 19 | ## tinyest is created by Software Mansion 20 | 21 | [![swm](https://logo.swmansion.com/logo?color=white&variant=desktop&width=150&tag=typegpu-github 'Software Mansion')](https://swmansion.com) 22 | 23 | Since 2012 [Software Mansion](https://swmansion.com) is a software agency with 24 | experience in building web and mobile apps. We are Core React Native 25 | Contributors and experts in dealing with all kinds of React Native issues. We 26 | can help you build your next dream product – 27 | [Hire us](https://swmansion.com/contact/projects?utm_source=tinyest&utm_medium=readme). 28 | -------------------------------------------------------------------------------- /packages/tinyest/deno.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": ["."], 3 | "fmt": { 4 | "exclude": ["!."], 5 | "singleQuote": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/tinyest/jsr.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@typegpu/tinyest", 3 | "version": "0.1.1`", 4 | "license": "MIT", 5 | "exports": "./src/index.ts", 6 | "publish": { 7 | "include": ["README.md", "src/**/*.ts"] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/tinyest/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Each breaking change to the format requires a bump to this number. 3 | * It's used at runtime by `typegpu` to determine how to interpret 4 | * a function's AST. It gets embedded by `unplugin-typegpu` into 5 | * the source code at build time. 6 | */ 7 | export const FORMAT_VERSION = 1; 8 | 9 | export * from './nodes.ts'; 10 | -------------------------------------------------------------------------------- /packages/tinyest/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json" 3 | } 4 | -------------------------------------------------------------------------------- /packages/tinyest/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { initBuildScript } from '@typegpu/tgpu-dev-cli'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | const { inDevMode } = initBuildScript(); 5 | 6 | export default defineConfig({ 7 | entry: ['src/index.ts'], 8 | outDir: 'dist', 9 | format: ['cjs', 'esm'], 10 | tsconfig: './tsconfig.json', 11 | target: 'es2017', 12 | splitting: true, 13 | sourcemap: true, 14 | minify: !inDevMode, 15 | clean: !inDevMode, 16 | dts: true, 17 | }); 18 | -------------------------------------------------------------------------------- /packages/typegpu-color/README.md: -------------------------------------------------------------------------------- 1 |
    2 | 3 | # @typegpu/color 4 | 5 | 🚧 **Under Construction** 🚧 6 | 7 |
    8 | 9 | A set of color helper functions for use in WebGPU/TypeGPU apps. 10 | -------------------------------------------------------------------------------- /packages/typegpu-color/build.config.ts: -------------------------------------------------------------------------------- 1 | import { type BuildConfig, defineBuildConfig } from 'unbuild'; 2 | import typegpu from 'unplugin-typegpu/rollup'; 3 | 4 | const Config: BuildConfig[] = defineBuildConfig({ 5 | hooks: { 6 | 'rollup:options': (_options, config) => { 7 | config.plugins.push(typegpu({ include: [/\.ts$/] })); 8 | }, 9 | }, 10 | }); 11 | 12 | export default Config; 13 | -------------------------------------------------------------------------------- /packages/typegpu-color/deno.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": ["."], 3 | "fmt": { 4 | "exclude": ["!."], 5 | "singleQuote": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/typegpu-color/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@typegpu/color", 3 | "type": "module", 4 | "version": "0.0.5", 5 | "description": "A set of color helper functions for use in WebGPU/TypeGPU apps.", 6 | "exports": { 7 | ".": "./src/index.ts", 8 | "./package.json": "./package.json" 9 | }, 10 | "publishConfig": { 11 | "directory": "dist", 12 | "linkDirectory": false, 13 | "main": "./dist/index.mjs", 14 | "types": "./dist/index.d.ts", 15 | "exports": { 16 | "./package.json": "./dist/package.json", 17 | ".": { 18 | "types": "./dist/index.d.ts", 19 | "module": "./dist/index.mjs", 20 | "import": "./dist/index.mjs", 21 | "default": "./dist/index.cjs" 22 | } 23 | } 24 | }, 25 | "sideEffects": false, 26 | "scripts": { 27 | "build": "unbuild", 28 | "test:types": "pnpm tsc --p ./tsconfig.json --noEmit", 29 | "prepublishOnly": "tgpu-dev-cli prepack" 30 | }, 31 | "keywords": [], 32 | "license": "MIT", 33 | "peerDependencies": { 34 | "typegpu": "^0.5.8" 35 | }, 36 | "devDependencies": { 37 | "@typegpu/tgpu-dev-cli": "workspace:*", 38 | "@types/node": "^22.13.14", 39 | "@webgpu/types": "catalog:", 40 | "typegpu": "workspace:*", 41 | "typescript": "catalog:", 42 | "unbuild": "catalog:", 43 | "unplugin-typegpu": "workspace:*" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/typegpu-color/src/index.ts: -------------------------------------------------------------------------------- 1 | export { hsvToRgb, rgbToHsv } from './hsv.ts'; 2 | export { rgbToYcbcr, rgbToYcbcrMatrix } from './ycbcr.ts'; 3 | export { linearToSrgb, srgbToLinear } from './srgb.ts'; 4 | export { 5 | linearRgbToOklab, 6 | oklabGamutClip, 7 | oklabGamutClipAlphaAccess, 8 | oklabGamutClipSlot, 9 | oklabToLinearRgb, 10 | oklabToRgb, 11 | rgbToOklab, 12 | } from './oklab.ts'; 13 | -------------------------------------------------------------------------------- /packages/typegpu-color/src/srgb.ts: -------------------------------------------------------------------------------- 1 | import tgpu from 'typegpu'; 2 | import { vec3f } from 'typegpu/data'; 3 | import { add, gt, mul, pow, select, sub } from 'typegpu/std'; 4 | 5 | export const linearToSrgb = tgpu['~unstable'].fn([vec3f], vec3f)((linear) => { 6 | 'kernel & js'; 7 | return select( 8 | mul(12.92, linear), 9 | sub(mul(1.055, pow(linear, vec3f(1.0 / 2.4))), vec3f(0.055)), 10 | gt(linear, vec3f(0.0031308)), 11 | ); 12 | }); 13 | 14 | export const srgbToLinear = tgpu['~unstable'].fn([vec3f], vec3f)((rgb) => { 15 | 'kernel & js'; 16 | return select( 17 | mul(1.0 / 12.92, rgb), 18 | pow(mul(add(rgb, vec3f(0.055)), vec3f(1 / (1 + 0.055))), vec3f(2.4)), 19 | gt(rgb, vec3f(0.04045)), 20 | ); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/typegpu-color/src/ycbcr.ts: -------------------------------------------------------------------------------- 1 | import tgpu from 'typegpu'; 2 | import { mat3x3f, vec3f } from 'typegpu/data'; 3 | import { mul } from 'typegpu/std'; 4 | 5 | /** 6 | * @example 7 | * import { rgbToYcbcrMatrix } from '@typegpu/color'; 8 | * 9 | * const redInYcbcr = mul(d.vec3f(1, 0, 0), rgbToYcbcrMatrix); 10 | */ 11 | export const rgbToYcbcrMatrix = tgpu['~unstable'].const( 12 | mat3x3f, 13 | mat3x3f( 14 | // row 1 15 | 0.299, 16 | 0.587, 17 | 0.114, 18 | // row 2 19 | -0.168736, 20 | -0.331264, 21 | 0.5, 22 | // row 3 23 | 0.5, 24 | -0.418688, 25 | -0.081312, 26 | ), 27 | ); 28 | 29 | export const rgbToYcbcr = tgpu['~unstable'].fn([vec3f], vec3f)((rgb) => { 30 | return mul(rgb, rgbToYcbcrMatrix.value); 31 | }); 32 | -------------------------------------------------------------------------------- /packages/typegpu-color/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["src/**/*"], 4 | "exclude": ["node_modules", "dist"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/typegpu-noise/README.md: -------------------------------------------------------------------------------- 1 |
    2 | 3 | # @typegpu/noise 4 | 5 | 🚧 **Under Construction** 🚧 6 | 7 |
    8 | 9 | A set of noise/pseudo-random functions for use in WebGPU/TypeGPU apps. 10 | 11 | ```ts 12 | import { randf } from '@typegpu/noise'; 13 | 14 | const timeUniform = root.createUniform(f32); 15 | 16 | const mainFrag = tgpu 17 | .fragmentFn({ in: { pos: builtin.position }, out: vec4f })((input) => { 18 | const time = timeUniform.value; 19 | randf.seed2(add(input.pos.xy, vec2f(time))); 20 | 21 | const val = randf.sample(); // => number 22 | const normal = randf.onUnitSphere(); // => v3f 23 | const dir = randf.inUnitCircle(); // => v2f 24 | }); 25 | ``` 26 | -------------------------------------------------------------------------------- /packages/typegpu-noise/build.config.ts: -------------------------------------------------------------------------------- 1 | import { type BuildConfig, defineBuildConfig } from 'unbuild'; 2 | import typegpu from 'unplugin-typegpu/rollup'; 3 | 4 | const Config: BuildConfig[] = defineBuildConfig({ 5 | hooks: { 6 | 'rollup:options': (_options, config) => { 7 | config.plugins.push(typegpu({ include: [/\.ts$/] })); 8 | }, 9 | }, 10 | }); 11 | 12 | export default Config; 13 | -------------------------------------------------------------------------------- /packages/typegpu-noise/deno.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": ["."], 3 | "fmt": { 4 | "exclude": ["!."], 5 | "singleQuote": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/typegpu-noise/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@typegpu/noise", 3 | "type": "module", 4 | "version": "0.0.8", 5 | "description": "A set of noise/pseudo-random functions for use in WebGPU/TypeGPU apps.", 6 | "exports": { 7 | ".": "./src/index.ts", 8 | "./package.json": "./package.json" 9 | }, 10 | "publishConfig": { 11 | "directory": "dist", 12 | "linkDirectory": false, 13 | "main": "./dist/index.mjs", 14 | "types": "./dist/index.d.ts", 15 | "exports": { 16 | "./package.json": "./dist/package.json", 17 | ".": { 18 | "types": "./dist/index.d.ts", 19 | "module": "./dist/index.mjs", 20 | "import": "./dist/index.mjs", 21 | "default": "./dist/index.cjs" 22 | } 23 | } 24 | }, 25 | "sideEffects": false, 26 | "scripts": { 27 | "build": "unbuild", 28 | "test:types": "pnpm tsc --p ./tsconfig.json --noEmit", 29 | "prepublishOnly": "tgpu-dev-cli prepack" 30 | }, 31 | "keywords": [], 32 | "license": "MIT", 33 | "peerDependencies": { 34 | "typegpu": "^0.5.8" 35 | }, 36 | "devDependencies": { 37 | "@typegpu/tgpu-dev-cli": "workspace:*", 38 | "@types/node": "^22.13.14", 39 | "@webgpu/types": "catalog:", 40 | "unbuild": "catalog:", 41 | "typegpu": "workspace:*", 42 | "typescript": "catalog:", 43 | "unplugin-typegpu": "workspace:*" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/typegpu-noise/src/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | randFloat01, 3 | randInUnitCircle, 4 | randInUnitCube, 5 | randOnUnitHemisphere, 6 | randOnUnitSphere, 7 | randSeed, 8 | randSeed2, 9 | randSeed3, 10 | randSeed4, 11 | } from './random.ts'; 12 | 13 | export const randf: { 14 | seed: typeof randSeed; 15 | seed2: typeof randSeed2; 16 | seed3: typeof randSeed3; 17 | seed4: typeof randSeed4; 18 | sample: typeof randFloat01; 19 | inUnitCircle: typeof randInUnitCircle; 20 | inUnitCube: typeof randInUnitCube; 21 | onHemisphere: typeof randOnUnitHemisphere; 22 | onUnitSphere: typeof randOnUnitSphere; 23 | } = { 24 | seed: randSeed, 25 | seed2: randSeed2, 26 | seed3: randSeed3, 27 | seed4: randSeed4, 28 | sample: randFloat01, 29 | inUnitCircle: randInUnitCircle, 30 | inUnitCube: randInUnitCube, 31 | onHemisphere: randOnUnitHemisphere, 32 | onUnitSphere: randOnUnitSphere, 33 | }; 34 | 35 | export { 36 | // Generators 37 | BPETER, 38 | // --- 39 | // The default (Can change between releases to improve uniformity). 40 | DefaultGenerator, 41 | // --- 42 | randomGeneratorShell, 43 | randomGeneratorSlot, 44 | } from './generator.ts'; 45 | 46 | export * as perlin2d from './perlin-2d.ts'; 47 | export * as perlin3d from './perlin-3d/index.ts'; 48 | -------------------------------------------------------------------------------- /packages/typegpu-noise/src/perlin-3d/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | computeJunctionGradient, 3 | getJunctionGradientSlot, 4 | sample, 5 | } from './algorithm.ts'; 6 | export { 7 | dynamicCacheConfig, 8 | type DynamicPerlin3DCache, 9 | type DynamicPerlin3DCacheConfig, 10 | } from './dynamic-cache.ts'; 11 | export { staticCache, type StaticPerlin3DCache } from './static-cache.ts'; 12 | -------------------------------------------------------------------------------- /packages/typegpu-noise/src/utils.ts: -------------------------------------------------------------------------------- 1 | import tgpu from 'typegpu'; 2 | import * as d from 'typegpu/data'; 3 | import { pow } from 'typegpu/std'; 4 | 5 | export type Prettify = 6 | & { 7 | [K in keyof T]: T[K]; 8 | } 9 | & {}; 10 | 11 | export type PrefixKeys = { 12 | [K in keyof T as K extends string ? `${Prefix}${K}` : K]: T[K]; 13 | }; 14 | 15 | /** 16 | * Works as a replacement for smoothstep, but with a continuous 17 | * second derivative, so lighting is continuous. 18 | */ 19 | export const smootherStep = tgpu['~unstable'].fn([d.f32], d.f32)((x) => { 20 | return 6 * pow(x, 5) - 15 * pow(x, 4) + 10 * pow(x, 3); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/typegpu-noise/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["src/**/*"], 4 | "exclude": ["node_modules", "dist"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/typegpu/deno.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": ["."], 3 | "fmt": { 4 | "exclude": ["!."], 5 | "singleQuote": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/typegpu/scripts/generateSwizzleFunctions.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Prints the swizzling getters to be manually added to the VecBase abstract class. 3 | */ 4 | printSwizzlingFor('xyzw'); 5 | 6 | /** 7 | * Yields combinations of letters from `components` of given `length`. 8 | * 9 | * @example 10 | * vectorComponentCombinations('xyz', 2) // xx, xy, xz, yx, yy ... 11 | */ 12 | function* vectorComponentCombinations( 13 | components: string, 14 | length: number, 15 | ): Generator { 16 | if (length > 1) { 17 | for (const str of vectorComponentCombinations(components, length - 1)) { 18 | for (const component of components) { 19 | yield str + component; 20 | } 21 | } 22 | } else { 23 | yield* components; 24 | } 25 | } 26 | 27 | function printSwizzlingFor(components: string) { 28 | const componentIndex: Record = { x: 0, y: 1, z: 2, w: 3 }; 29 | for (const count of [2, 3, 4] as const) { 30 | const vecClassName = `_Vec${count}`; 31 | for (const swizzle of vectorComponentCombinations(components, count)) { 32 | const implementation = 33 | ` get ${swizzle}() { return new this.${vecClassName}(${ 34 | [ 35 | ...swizzle, 36 | ] 37 | .map((s) => `this[${componentIndex[s]}]`) 38 | .join(', ') 39 | }); }`; 40 | console.log(implementation); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/typegpu/setupVitest.ts: -------------------------------------------------------------------------------- 1 | import { setup } from '@ark/attest'; 2 | 3 | export default () => 4 | setup({ 5 | formatCmd: 'pnpm check', 6 | }); 7 | -------------------------------------------------------------------------------- /packages/typegpu/src/core/function/astUtils.ts: -------------------------------------------------------------------------------- 1 | import type { Block, FuncParameter } from 'tinyest'; 2 | import { setMetaData } from '../../shared/meta.ts'; 3 | 4 | export type Ast = { 5 | params: FuncParameter[]; 6 | body: Block; 7 | externalNames: string[]; 8 | }; 9 | 10 | export function assignAst unknown>( 11 | fn: T, 12 | ast: Ast, 13 | externals?: Record | undefined, 14 | ): T { 15 | setMetaData(fn, { ast, externals }); 16 | return fn; 17 | } 18 | 19 | export function removedJsImpl(name?: string) { 20 | return () => { 21 | throw new Error( 22 | `The function "${ 23 | name ?? '' 24 | }" is invokable only on the GPU. If you want to use it on the CPU, mark it with the "kernel & js" directive.`, 25 | ); 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /packages/typegpu/src/core/function/templateUtils.ts: -------------------------------------------------------------------------------- 1 | import type { Implementation } from './fnTypes.ts'; 2 | 3 | export function stripTemplate( 4 | arg: Implementation | TemplateStringsArray, 5 | ...values: unknown[] 6 | ): Implementation { 7 | return isTemplateStringsArray(arg) 8 | ? templateLiteralIdentity(arg, ...values) 9 | : arg; 10 | } 11 | 12 | function isTemplateStringsArray(value: unknown): value is TemplateStringsArray { 13 | return ( 14 | Array.isArray(value) && 15 | 'raw' in value && 16 | Array.isArray(value.raw) && 17 | value.raw.every((item) => typeof item === 'string') 18 | ); 19 | } 20 | 21 | function templateLiteralIdentity( 22 | strings: TemplateStringsArray, 23 | ...values: unknown[] 24 | ): string { 25 | return strings 26 | .slice(1) 27 | .reduce( 28 | (acc, elem, index) => `${acc}${values[index]}${elem}`, 29 | strings[0] as string, 30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /packages/typegpu/src/core/pipeline/connectAttachmentToShader.ts: -------------------------------------------------------------------------------- 1 | import { isData } from '../../data/dataTypes.ts'; 2 | import type { FragmentOutConstrained } from '../function/tgpuFragmentFn.ts'; 3 | import type { 4 | AnyFragmentColorAttachment, 5 | ColorAttachment, 6 | } from './renderPipeline.ts'; 7 | 8 | function isColorAttachment( 9 | value: unknown | ColorAttachment, 10 | ): value is ColorAttachment { 11 | return typeof (value as ColorAttachment)?.loadOp === 'string'; 12 | } 13 | 14 | export function connectAttachmentToShader( 15 | shaderOutputLayout: FragmentOutConstrained, 16 | attachment: AnyFragmentColorAttachment, 17 | ): ColorAttachment[] { 18 | if (isData(shaderOutputLayout)) { 19 | if (!isColorAttachment(attachment)) { 20 | throw new Error('Expected a single color attachment, not a record.'); 21 | } 22 | 23 | return [attachment]; 24 | } 25 | 26 | const result: ColorAttachment[] = []; 27 | for (const key of Object.keys(shaderOutputLayout)) { 28 | const matching = (attachment as Record)[key]; 29 | 30 | if (!matching) { 31 | throw new Error( 32 | `A color attachment by the name of '${key}' was not provided to the shader.`, 33 | ); 34 | } 35 | 36 | result.push(matching); 37 | } 38 | 39 | return result; 40 | } 41 | -------------------------------------------------------------------------------- /packages/typegpu/src/core/texture/externalTexture.ts: -------------------------------------------------------------------------------- 1 | import { getName, setName } from '../../shared/meta.ts'; 2 | import type { LayoutMembership } from '../../tgpuBindGroupLayout.ts'; 3 | import type { ResolutionCtx, SelfResolvable } from '../../types.ts'; 4 | 5 | // ---------- 6 | // Public API 7 | // ---------- 8 | 9 | export interface TgpuExternalTexture { 10 | readonly resourceType: 'external-texture'; 11 | } 12 | 13 | export function isExternalTexture( 14 | value: unknown | T, 15 | ): value is T { 16 | return (value as T)?.resourceType === 'external-texture'; 17 | } 18 | 19 | // -------------- 20 | // Implementation 21 | // -------------- 22 | 23 | export class TgpuExternalTextureImpl 24 | implements TgpuExternalTexture, SelfResolvable { 25 | public readonly resourceType = 'external-texture'; 26 | 27 | constructor(private readonly _membership: LayoutMembership) { 28 | setName(this, _membership.key); 29 | } 30 | 31 | '~resolve'(ctx: ResolutionCtx): string { 32 | const id = ctx.names.makeUnique(getName(this)); 33 | const group = ctx.allocateLayoutEntry(this._membership.layout); 34 | 35 | ctx.addDeclaration( 36 | `@group(${group}) @binding(${this._membership.idx}) var ${id}: texture_external;`, 37 | ); 38 | 39 | return id; 40 | } 41 | 42 | toString() { 43 | return `${this.resourceType}:${getName(this) ?? ''}`; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/typegpu/src/core/texture/textureProps.ts: -------------------------------------------------------------------------------- 1 | export type TextureProps = { 2 | size: readonly number[]; 3 | format: GPUTextureFormat; 4 | viewFormats?: GPUTextureFormat[] | undefined; 5 | dimension?: GPUTextureDimension | undefined; 6 | mipLevelCount?: number | undefined; 7 | sampleCount?: number | undefined; 8 | }; 9 | -------------------------------------------------------------------------------- /packages/typegpu/src/data/alignIO.ts: -------------------------------------------------------------------------------- 1 | import type { IMeasurer, ISerialInput, ISerialOutput } from 'typed-binary'; 2 | 3 | /** 4 | * @param io the IO to align 5 | * @param baseAlignment must be power of 2 6 | */ 7 | function alignIO( 8 | io: ISerialInput | ISerialOutput | IMeasurer, 9 | baseAlignment: number, 10 | ) { 11 | const currentPos = 'size' in io ? io.size : io.currentByteOffset; 12 | 13 | const bitMask = baseAlignment - 1; 14 | const offset = currentPos & bitMask; 15 | 16 | if ('skipBytes' in io) { 17 | io.skipBytes((baseAlignment - offset) & bitMask); 18 | } else { 19 | io.add((baseAlignment - offset) & bitMask); 20 | } 21 | } 22 | 23 | export default alignIO; 24 | -------------------------------------------------------------------------------- /packages/typegpu/src/data/atomic.ts: -------------------------------------------------------------------------------- 1 | import type { $repr, Infer, MemIdentity } from '../shared/repr.ts'; 2 | import { $internal } from '../shared/symbols.ts'; 3 | import type { Atomic, atomicI32, atomicU32, I32, U32 } from './wgslTypes.ts'; 4 | 5 | // ---------- 6 | // Public API 7 | // ---------- 8 | 9 | /** 10 | * Marks a concrete integer scalar type schema (u32 or i32) as a WGSL atomic. 11 | * 12 | * @example 13 | * const atomicU32 = d.atomic(d.u32); 14 | * const atomicI32 = d.atomic(d.i32); 15 | * 16 | * @param data Underlying type schema. 17 | */ 18 | export function atomic( 19 | data: TSchema, 20 | ): Atomic { 21 | return new AtomicImpl(data); 22 | } 23 | 24 | // -------------- 25 | // Implementation 26 | // -------------- 27 | 28 | class AtomicImpl implements Atomic { 29 | public readonly [$internal] = true; 30 | public readonly type = 'atomic'; 31 | /** Type-token, not available at runtime */ 32 | declare public readonly [$repr]: Infer; 33 | /** Type-token, not available at runtime */ 34 | public readonly '~memIdent'!: MemIdentity; 35 | /** Type-token, not available at runtime */ 36 | public readonly '~gpuRepr': TSchema extends U32 ? atomicU32 : atomicI32; 37 | 38 | constructor(public readonly inner: TSchema) {} 39 | } 40 | -------------------------------------------------------------------------------- /packages/typegpu/src/data/struct.ts: -------------------------------------------------------------------------------- 1 | import { getName, setName } from '../shared/meta.ts'; 2 | import { $internal } from '../shared/symbols.ts'; 3 | import type { AnyWgslData, WgslStruct } from './wgslTypes.ts'; 4 | 5 | // ---------- 6 | // Public API 7 | // ---------- 8 | 9 | /** 10 | * Creates a struct schema that can be used to construct GPU buffers. 11 | * Ensures proper alignment and padding of properties (as opposed to a `d.unstruct` schema). 12 | * The order of members matches the passed in properties object. 13 | * 14 | * @example 15 | * const CircleStruct = d.struct({ radius: d.f32, pos: d.vec3f }); 16 | * 17 | * @param props Record with `string` keys and `TgpuData` values, 18 | * each entry describing one struct member. 19 | */ 20 | export function struct>( 21 | props: TProps, 22 | ): WgslStruct { 23 | const struct = (props: T) => props; 24 | Object.setPrototypeOf(struct, WgslStructImpl); 25 | struct.propTypes = props; 26 | 27 | return struct as WgslStruct; 28 | } 29 | 30 | // -------------- 31 | // Implementation 32 | // -------------- 33 | 34 | const WgslStructImpl = { 35 | [$internal]: true, 36 | type: 'struct', 37 | 38 | $name(label: string) { 39 | setName(this, label); 40 | return this; 41 | }, 42 | 43 | toString(): string { 44 | return `struct:${getName(this) ?? ''}`; 45 | }, 46 | }; 47 | -------------------------------------------------------------------------------- /packages/typegpu/src/extension.ts: -------------------------------------------------------------------------------- 1 | import { getName } from './shared/meta.ts'; 2 | 3 | export interface NotAllowed { 4 | reason: TMsg; 5 | } 6 | 7 | export type ExtensionGuard = boolean extends TFlag 8 | ? NotAllowed | TAllowed 9 | : TAllowed; 10 | 11 | // #region Shared usage extensions 12 | 13 | export interface StorageFlag { 14 | usableAsStorage: true; 15 | } 16 | 17 | /** 18 | * @deprecated Use StorageFlag instead. 19 | */ 20 | export type Storage = StorageFlag; 21 | 22 | export function isUsableAsStorage(value: T): value is T & StorageFlag { 23 | return !!(value as unknown as StorageFlag)?.usableAsStorage; 24 | } 25 | 26 | /** 27 | * @category Errors 28 | */ 29 | export class NotStorageError extends Error { 30 | constructor(value: object) { 31 | super( 32 | `Resource '${ 33 | getName(value) ?? '' 34 | }' cannot be bound as 'storage'. Use .$usage('storage') to allow it.`, 35 | ); 36 | 37 | // Set the prototype explicitly. 38 | Object.setPrototypeOf(this, NotStorageError.prototype); 39 | } 40 | } 41 | 42 | // #endregion 43 | -------------------------------------------------------------------------------- /packages/typegpu/src/extractGpuValueGetter.ts: -------------------------------------------------------------------------------- 1 | import { $gpuValueOf } from './shared/symbols.ts'; 2 | import type { ResolutionCtx } from './types.ts'; 3 | 4 | export type GpuValueGetter = (ctx: ResolutionCtx) => unknown; 5 | 6 | export function extractGpuValueGetter( 7 | object: unknown, 8 | ): GpuValueGetter | undefined { 9 | // biome-ignore lint/suspicious/noExplicitAny: we're inspecting the value 10 | if (typeof (object as any)?.[$gpuValueOf] === 'function') { 11 | return (object as { [$gpuValueOf]: GpuValueGetter })[$gpuValueOf].bind( 12 | object, 13 | ); 14 | } 15 | return undefined; 16 | } 17 | -------------------------------------------------------------------------------- /packages/typegpu/src/globals.d.ts: -------------------------------------------------------------------------------- 1 | declare interface ImportMeta { 2 | env?: { 3 | MODE: string; 4 | }; 5 | } 6 | -------------------------------------------------------------------------------- /packages/typegpu/src/gpuMode.ts: -------------------------------------------------------------------------------- 1 | import { invariant } from './errors.ts'; 2 | import type { ResolutionCtx } from './types.ts'; 3 | 4 | let resolutionCtx: ResolutionCtx | null = null; 5 | 6 | const CPUMode = Symbol('CPU'); 7 | const GPUMode = Symbol('GPU'); 8 | 9 | export const RuntimeMode = { 10 | CPU: CPUMode, 11 | GPU: GPUMode, 12 | } as const; 13 | 14 | const resolutionModeStack: (typeof CPUMode | typeof GPUMode)[] = []; 15 | 16 | export function provideCtx(ctx: ResolutionCtx, callback: () => T): T { 17 | invariant(resolutionCtx === null, 'Cannot nest context providers'); 18 | 19 | resolutionCtx = ctx; 20 | try { 21 | return callback(); 22 | } finally { 23 | resolutionCtx = null; 24 | } 25 | } 26 | 27 | export function getResolutionCtx(): ResolutionCtx | null { 28 | return resolutionCtx; 29 | } 30 | 31 | export function pushMode(mode: typeof CPUMode | typeof GPUMode) { 32 | resolutionModeStack.push(mode); 33 | } 34 | 35 | export function popMode(expected?: typeof CPUMode | typeof GPUMode) { 36 | const mode = resolutionModeStack.pop(); 37 | if (expected !== undefined) { 38 | invariant(mode === expected, 'Unexpected mode'); 39 | } 40 | } 41 | 42 | export const inGPUMode = () => 43 | resolutionModeStack.length > 0 && 44 | resolutionModeStack[resolutionModeStack.length - 1] === RuntimeMode.GPU; 45 | -------------------------------------------------------------------------------- /packages/typegpu/src/jitTranspiler.ts: -------------------------------------------------------------------------------- 1 | import type { TranspilationResult } from './core/function/fnTypes.ts'; 2 | 3 | /** 4 | * Used to transpile JS resources into tinyest on demand. 5 | */ 6 | export interface JitTranspiler { 7 | transpileFn(rawJs: string): TranspilationResult; 8 | } 9 | -------------------------------------------------------------------------------- /packages/typegpu/src/mathUtils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @param value 3 | * @param modulo has to be power of 2 4 | */ 5 | export const roundUp = (value: number, modulo: number) => { 6 | const bitMask = modulo - 1; 7 | const invBitMask = ~bitMask; 8 | return (value & bitMask) === 0 ? value : (value & invBitMask) + modulo; 9 | }; 10 | -------------------------------------------------------------------------------- /packages/typegpu/src/memo.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Caches results of the function passed in as 3 | * the argument to the constructor. 4 | * 5 | * If the key can be garbage collected, it will be. 6 | */ 7 | export class WeakMemo { 8 | private readonly _map = new WeakMap(); 9 | 10 | constructor(private readonly _make: (key: TKey, ...args: TArgs) => TValue) {} 11 | 12 | getOrMake(key: TKey, ...args: TArgs): TValue { 13 | if (this._map.has(key)) { 14 | return this._map.get(key) as TValue; 15 | } 16 | 17 | const value = this._make(key, ...args); 18 | this._map.set(key, value); 19 | return value; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/typegpu/src/namable.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion/TypeGPU/00f8b625835a59d4d911661141c010f6e7bf469e/packages/typegpu/src/namable.ts -------------------------------------------------------------------------------- /packages/typegpu/src/shared/README.md: -------------------------------------------------------------------------------- 1 | # Purpose 2 | 3 | No dependencies to other entrypoints, a place for code shared between 4 | entrypoints. 5 | -------------------------------------------------------------------------------- /packages/typegpu/src/shared/generators.ts: -------------------------------------------------------------------------------- 1 | import type { Snippet, TgpuDualFn } from '../data/dataTypes.ts'; 2 | import { inGPUMode } from '../gpuMode.ts'; 3 | import type { FnArgsConversionHint } from '../types.ts'; 4 | import { $internal } from './symbols.ts'; 5 | 6 | /** 7 | * Yields values in the sequence 0,1,2..∞ except for the ones in the `excluded` set. 8 | */ 9 | export function* naturalsExcept( 10 | excluded: Set, 11 | ): Generator { 12 | let next = 0; 13 | 14 | while (true) { 15 | if (!excluded.has(next)) { 16 | yield next; 17 | } 18 | 19 | next++; 20 | } 21 | } 22 | 23 | type MapValueToSnippet = { [K in keyof T]: Snippet }; 24 | 25 | export function createDualImpl unknown>( 26 | jsImpl: T, 27 | gpuImpl: (...args: MapValueToSnippet>) => Snippet, 28 | argTypes?: FnArgsConversionHint, 29 | ): TgpuDualFn { 30 | const impl = ((...args: Parameters) => { 31 | if (inGPUMode()) { 32 | return gpuImpl(...(args as MapValueToSnippet>)) as Snippet; 33 | } 34 | return jsImpl(...args); 35 | }) as T; 36 | 37 | (impl as TgpuDualFn)[$internal] = { 38 | implementation: jsImpl, 39 | argTypes, 40 | }; 41 | 42 | return impl as TgpuDualFn; 43 | } 44 | -------------------------------------------------------------------------------- /packages/typegpu/src/shared/symbols.ts: -------------------------------------------------------------------------------- 1 | // The version is inlined during build-time 🎉 2 | // It helps us identify problems when two versions of 3 | // TypeGPU are used at the same time. 4 | import { version } from '../../package.json'; 5 | 6 | export const $internal = Symbol(`typegpu:${version}:$internal`); 7 | /** 8 | * A value's data type as seen by the WGSL generator 9 | */ 10 | export const $wgslDataType = Symbol(`typegpu:${version}:$wgslDataType`); 11 | /** 12 | * The getter to the value of this resource, accessible on the GPU 13 | */ 14 | export const $gpuValueOf = Symbol(`typegpu:${version}:$gpuValueOf`); 15 | export const $getNameForward = Symbol(`typegpu:${version}:$getNameForward`); 16 | -------------------------------------------------------------------------------- /packages/typegpu/src/shared/utilityTypes.ts: -------------------------------------------------------------------------------- 1 | export type Default = unknown extends T ? TDefault 2 | : T extends undefined ? TDefault 3 | : T; 4 | 5 | export type UnionToIntersection = 6 | // biome-ignore lint/suspicious/noExplicitAny: 7 | (U extends any ? (x: U) => void : never) extends (x: infer I) => void ? I 8 | : never; 9 | 10 | export type Prettify = 11 | & { 12 | [K in keyof T]: T[K]; 13 | } 14 | & {}; 15 | 16 | /** 17 | * Removes properties from record type that extend `Prop` 18 | */ 19 | export type OmitProps, Prop> = Pick< 20 | T, 21 | { 22 | [Key in keyof T]: T[Key] extends Prop ? never : Key; 23 | }[keyof T] 24 | >; 25 | 26 | /** 27 | * The opposite of Readonly 28 | */ 29 | export type Mutable = { 30 | -readonly [P in keyof T]: T[P]; 31 | }; 32 | 33 | /** 34 | * Any typed array 35 | */ 36 | export type TypedArray = 37 | | Uint8Array 38 | | Uint16Array 39 | | Uint32Array 40 | | Int32Array 41 | | Float32Array 42 | | Float64Array; 43 | 44 | export function assertExhaustive(x: never, location: string): never { 45 | throw new Error(`Failed to handle ${x} at ${location}`); 46 | } 47 | -------------------------------------------------------------------------------- /packages/typegpu/src/std/array.ts: -------------------------------------------------------------------------------- 1 | import { snip } from '../data/dataTypes.ts'; 2 | import { abstractInt, u32 } from '../data/numeric.ts'; 3 | import { ptrFn } from '../data/ptr.ts'; 4 | import type { AnyWgslData } from '../data/wgslTypes.ts'; 5 | import { isPtr, isWgslArray } from '../data/wgslTypes.ts'; 6 | import { createDualImpl } from '../shared/generators.ts'; 7 | 8 | export const arrayLength = createDualImpl( 9 | // CPU implementation 10 | (a: unknown[]) => a.length, 11 | // GPU implementation 12 | (a) => { 13 | if ( 14 | isPtr(a.dataType) && isWgslArray(a.dataType.inner) && 15 | a.dataType.inner.elementCount > 0 16 | ) { 17 | return snip(String(a.dataType.inner.elementCount), abstractInt); 18 | } 19 | return snip(`arrayLength(${a.value})`, u32); 20 | }, 21 | (a) => [ptrFn(a.dataType as AnyWgslData)], 22 | ); 23 | -------------------------------------------------------------------------------- /packages/typegpu/src/std/discard.ts: -------------------------------------------------------------------------------- 1 | import { snip } from '../data/dataTypes.ts'; 2 | import { Void } from '../data/wgslTypes.ts'; 3 | import { createDualImpl } from '../shared/generators.ts'; 4 | 5 | export const discard = createDualImpl( 6 | // CPU 7 | (): never => { 8 | throw new Error('discard() can only be used on the GPU.'); 9 | }, 10 | // GPU 11 | () => snip('discard;', Void), 12 | ); 13 | -------------------------------------------------------------------------------- /packages/typegpu/src/taskQueue.ts: -------------------------------------------------------------------------------- 1 | export class TaskQueue { 2 | private _queue: (() => Promise)[] = []; 3 | private _pending = false; 4 | 5 | enqueue(task: () => Promise): Promise { 6 | return new Promise((resolve, reject) => { 7 | this._queue.push(async () => { 8 | try { 9 | resolve(await task()); 10 | } catch (e) { 11 | reject(e); 12 | } 13 | }); 14 | this._processQueue(); 15 | }); 16 | } 17 | 18 | private async _processQueue() { 19 | if (this._pending) { 20 | return; 21 | } 22 | this._pending = true; 23 | while (this._queue.length > 0) { 24 | const task = this._queue.shift(); 25 | if (task) { 26 | await task(); 27 | } 28 | } 29 | this._pending = false; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/typegpu/src/tgsl/index.ts: -------------------------------------------------------------------------------- 1 | export { generateFunction } from './wgslGenerator.ts'; 2 | export type { GenerationCtx } from './generationHelpers.ts'; 3 | -------------------------------------------------------------------------------- /packages/typegpu/tests/attributes.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, expectTypeOf, it } from 'vitest'; 2 | import * as d from '../src/data/index.ts'; 3 | import tgpu from '../src/index.ts'; 4 | 5 | describe('attributes', () => { 6 | it('adds attributes in the correct order', () => { 7 | const s1 = d 8 | .struct({ 9 | a: d.u32, 10 | b: d.size(8, d.align(16, d.u32)), 11 | c: d.u32, 12 | }); 13 | 14 | expect(tgpu.resolve({ 15 | externals: { s1 }, 16 | names: 'strict', 17 | })).toContain('@size(8) @align(16) b: u32,'); 18 | 19 | expectTypeOf(s1).toEqualTypeOf< 20 | d.WgslStruct<{ 21 | a: d.U32; 22 | b: d.Decorated, d.Align<16>]>; 23 | c: d.U32; 24 | }> 25 | >(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /packages/typegpu/tests/data/atomic.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, expectTypeOf, it } from 'vitest'; 2 | import * as d from '../../src/data/index.ts'; 3 | 4 | describe('d.atomic', () => { 5 | it('creates a u32 atomic schema', () => { 6 | const u32Atomic = d.atomic(d.u32); 7 | 8 | expect(u32Atomic.type).toBe('atomic'); 9 | expect(u32Atomic.inner).toStrictEqual(d.u32); 10 | expectTypeOf(u32Atomic).toEqualTypeOf>(); 11 | }); 12 | 13 | it('creates an i32 atomic schema', () => { 14 | const i32Atomic = d.atomic(d.i32); 15 | 16 | expect(i32Atomic.type).toBe('atomic'); 17 | expect(i32Atomic.inner).toStrictEqual(d.i32); 18 | expectTypeOf(i32Atomic).toEqualTypeOf>(); 19 | }); 20 | }); 21 | 22 | describe('d.isAtomic', () => { 23 | it('accepts atomic schemas', () => { 24 | expect(d.isAtomic(d.atomic(d.u32))).toBe(true); 25 | expect(d.isAtomic(d.atomic(d.i32))).toBe(true); 26 | }); 27 | 28 | it('rejects other schemas', () => { 29 | expect(d.isAtomic(d.u32)).toBe(false); 30 | expect(d.isAtomic(d.f32)).toBe(false); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /packages/typegpu/tests/indentController.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { IndentController } from '../src/resolutionCtx.ts'; 3 | 4 | const INDENT_SPACES_COUNT = 2; 5 | 6 | describe('IndentController', () => { 7 | it('indents properly', () => { 8 | const controller = new IndentController(); 9 | expect(controller.pre.length).toBe(0); 10 | 11 | for (let i = 1; i < 100; i++) { 12 | controller.indent(); 13 | expect(controller.pre.length).toBe(i * INDENT_SPACES_COUNT); 14 | } 15 | }); 16 | 17 | it('dedents properly', () => { 18 | const controller = new IndentController(); 19 | 20 | for (let i = 0; i < 10; i++) { 21 | controller.indent(); 22 | } // -> 10 23 | 24 | for (let i = 0; i < 3; i++) { 25 | controller.dedent(); 26 | } // -> 7 27 | 28 | controller.indent(); // -> 8 29 | controller.dedent(); // -> 7 30 | 31 | controller.dedent(); // -> 6 32 | controller.indent(); // -> 7 33 | 34 | expect(controller.pre.length).toBe(7 * INDENT_SPACES_COUNT); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /packages/typegpu/tests/mathUtils.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { roundUp } from '../src/mathUtils.ts'; 3 | 4 | describe('roundUp', () => { 5 | it('does nothing when value is multiple of modulo', () => { 6 | expect(roundUp(0, 2)).toBe(0); 7 | expect(roundUp(2, 2)).toBe(2); 8 | expect(roundUp(4, 2)).toBe(4); 9 | 10 | expect(roundUp(0, 128)).toBe(0); 11 | expect(roundUp(128, 128)).toBe(128); 12 | expect(roundUp(256, 128)).toBe(256); 13 | }); 14 | 15 | it('rounds positive value up', () => { 16 | expect(roundUp(1, 2)).toBe(2); 17 | 18 | expect(roundUp(1, 128)).toBe(128); 19 | expect(roundUp(127, 128)).toBe(128); 20 | expect(roundUp(200, 128)).toBe(256); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/boolean/all.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { vec2b, vec3b, vec4b } from '../../../src/data/index.ts'; 3 | import { all } from '../../../src/std/boolean.ts'; 4 | 5 | describe('all', () => { 6 | it('calculates for 2 element vectors', () => { 7 | expect(all(vec2b(false, false))).toBe(false); 8 | expect(all(vec2b(true, false))).toBe(false); 9 | expect(all(vec2b(true, true))).toBe(true); 10 | }); 11 | 12 | it('calculates for 3 element vectors', () => { 13 | expect(all(vec3b(false, false, false))).toBe(false); 14 | expect(all(vec3b(false, false, true))).toBe(false); 15 | expect(all(vec3b(true, true, false))).toBe(false); 16 | expect(all(vec3b(true, true, true))).toBe(true); 17 | }); 18 | 19 | it('calculates for 4 element vectors', () => { 20 | expect(all(vec4b(false, false, false, false))).toBe(false); 21 | expect(all(vec4b(false, false, true, false))).toBe(false); 22 | expect(all(vec4b(true, true, false, false))).toBe(false); 23 | expect(all(vec4b(true, true, false, true))).toBe(false); 24 | expect(all(vec4b(true, true, true, true))).toBe(true); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/boolean/allEq.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { 3 | vec2b, 4 | vec2f, 5 | vec2u, 6 | vec4b, 7 | vec4f, 8 | vec4u, 9 | } from '../../../src/data/index.ts'; 10 | import { allEq } from '../../../src/std/index.ts'; 11 | 12 | describe('allEq', () => { 13 | it('compares integer vectors', () => { 14 | expect(allEq(vec2u(1, 0), vec2u(1, 0))).toBe(true); 15 | expect(allEq(vec2u(1, 0), vec2u(0, 0))).toBe(false); 16 | expect(allEq(vec4u(1, 2, 3, 4), vec4u(1, 2, 3, 4))).toBe(true); 17 | expect(allEq(vec4u(1, 2, 3, 4), vec4u(4, 2, 3, 1))).toBe(false); 18 | }); 19 | 20 | it('compares float vectors', () => { 21 | expect(allEq(vec2f(1, 0), vec2f(1, 0))).toBe(true); 22 | expect(allEq(vec2f(1, 0), vec2f(0, 0))).toBe(false); 23 | expect(allEq(vec4f(1, 2, 3, 4), vec4f(1, 2, 3, 4))).toBe(true); 24 | expect(allEq(vec4f(1, 2, 3, 4), vec4f(4, 2, 3, 1))).toBe(false); 25 | }); 26 | 27 | it('compares boolean vectors', () => { 28 | expect(allEq(vec2b(false, true), vec2b(false, true))).toBe(true); 29 | expect(allEq(vec2b(false, false), vec2b(false, true))).toBe(false); 30 | expect( 31 | allEq(vec4b(false, true, true, true), vec4b(false, true, true, true)), 32 | ).toBe(true); 33 | expect( 34 | allEq(vec4b(false, true, true, true), vec4b(false, true, false, true)), 35 | ).toBe(false); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/boolean/and.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { vec2b, vec3b, vec4b } from '../../../src/data/index.ts'; 3 | import { and } from '../../../src/std/boolean.ts'; 4 | 5 | describe('and', () => { 6 | it('and vectors', () => { 7 | expect(and(vec2b(true, true), vec2b(true, false))).toStrictEqual( 8 | vec2b(true, false), 9 | ); 10 | expect( 11 | and(vec3b(false, true, true), vec3b(true, false, true)), 12 | ).toStrictEqual(vec3b(false, false, true)); 13 | expect( 14 | and(vec4b(false, true, false, true), vec4b(false, false, true, true)), 15 | ).toStrictEqual(vec4b(false, false, false, true)); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/boolean/any.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { vec2b, vec3b, vec4b } from '../../../src/data/index.ts'; 3 | import { any } from '../../../src/std/boolean.ts'; 4 | 5 | describe('any', () => { 6 | it('calculates for 2 element vectors', () => { 7 | expect(any(vec2b(false, false))).toBe(false); 8 | expect(any(vec2b(true, false))).toBe(true); 9 | expect(any(vec2b(true, true))).toBe(true); 10 | }); 11 | 12 | it('calculates for 3 element vectors', () => { 13 | expect(any(vec3b(false, false, false))).toBe(false); 14 | expect(any(vec3b(false, false, true))).toBe(true); 15 | expect(any(vec3b(true, true, false))).toBe(true); 16 | expect(any(vec3b(true, true, true))).toBe(true); 17 | }); 18 | 19 | it('calculates for 4 element vectors', () => { 20 | expect(any(vec4b(false, false, false, false))).toBe(false); 21 | expect(any(vec4b(false, false, true, false))).toBe(true); 22 | expect(any(vec4b(true, true, false, false))).toBe(true); 23 | expect(any(vec4b(true, true, false, true))).toBe(true); 24 | expect(any(vec4b(true, true, true, true))).toBe(true); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/boolean/ge.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { 3 | vec2b, 4 | vec2f, 5 | vec2i, 6 | vec3b, 7 | vec3f, 8 | vec3i, 9 | vec4b, 10 | vec4f, 11 | vec4i, 12 | } from '../../../src/data/index.ts'; 13 | import { ge } from '../../../src/std/index.ts'; 14 | 15 | describe('ge', () => { 16 | it('compares integer vectors', () => { 17 | expect(ge(vec2i(1, 0), vec2i(0, 0))).toStrictEqual(vec2b(true, true)); 18 | expect(ge(vec3i(10, 20, 20), vec3i(10, 20, 30))).toStrictEqual( 19 | vec3b(true, true, false), 20 | ); 21 | expect(ge(vec4i(1, 2, 3, 4), vec4i(4, 2, 3, 1))).toStrictEqual( 22 | vec4b(false, true, true, true), 23 | ); 24 | }); 25 | 26 | it('compares float vectors', () => { 27 | expect(ge(vec2f(0.1, 1.1), vec2f(0.1, 2))).toStrictEqual( 28 | vec2b(true, false), 29 | ); 30 | expect(ge(vec3f(1.2, 2.3, 3.4), vec3f(2.3, 3.2, 3.4))).toStrictEqual( 31 | vec3b(false, false, true), 32 | ); 33 | expect( 34 | ge(vec4f(0.11, -0.2, -0.3, 0.4), vec4f(0.1, 0.2, 0.3, 0.4)), 35 | ).toStrictEqual(vec4b(true, false, false, true)); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/boolean/gt.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { 3 | vec2b, 4 | vec2f, 5 | vec2i, 6 | vec3b, 7 | vec3f, 8 | vec3i, 9 | vec4b, 10 | vec4f, 11 | vec4i, 12 | } from '../../../src/data/index.ts'; 13 | import { gt } from '../../../src/std/index.ts'; 14 | 15 | describe('gt', () => { 16 | it('compares integer vectors', () => { 17 | expect(gt(vec2i(1, -1), vec2i(0, 0))).toStrictEqual(vec2b(true, false)); 18 | expect(gt(vec3i(20, 20, 20), vec3i(10, 20, 30))).toStrictEqual( 19 | vec3b(true, false, false), 20 | ); 21 | expect(gt(vec4i(1, 2, 3, 4), vec4i(4, 2, 3, 1))).toStrictEqual( 22 | vec4b(false, false, false, true), 23 | ); 24 | }); 25 | 26 | it('compares float vectors', () => { 27 | expect(gt(vec2f(0.1, 2.1), vec2f(0.1, 2))).toStrictEqual( 28 | vec2b(false, true), 29 | ); 30 | expect(gt(vec3f(1.2, 3.3, 3.4), vec3f(2.3, 3.2, 3.4))).toStrictEqual( 31 | vec3b(false, true, false), 32 | ); 33 | expect( 34 | gt(vec4f(1.1, -1.2, -0.3, 0.4), vec4f(0.1, 0.2, 0.3, 0.4)), 35 | ).toStrictEqual(vec4b(true, false, false, false)); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/boolean/le.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { 3 | vec2b, 4 | vec2f, 5 | vec2i, 6 | vec3b, 7 | vec3f, 8 | vec3i, 9 | vec4b, 10 | vec4f, 11 | vec4i, 12 | } from '../../../src/data/index.ts'; 13 | import { le } from '../../../src/std/index.ts'; 14 | 15 | describe('le', () => { 16 | it('compares integer vectors', () => { 17 | expect(le(vec2i(1, -1), vec2i(0, 0))).toStrictEqual(vec2b(false, true)); 18 | expect(le(vec3i(10, 20, 20), vec3i(10, 20, 30))).toStrictEqual( 19 | vec3b(true, true, true), 20 | ); 21 | expect(le(vec4i(1, 2, 3, 4), vec4i(4, 2, 3, 1))).toStrictEqual( 22 | vec4b(true, true, true, false), 23 | ); 24 | }); 25 | 26 | it('compares float vectors', () => { 27 | expect(le(vec2f(0.1, 1.1), vec2f(0.1, 2))).toStrictEqual(vec2b(true, true)); 28 | expect(le(vec3f(1.2, 2.3, 3.4), vec3f(2.3, 3.2, 3.4))).toStrictEqual( 29 | vec3b(true, true, true), 30 | ); 31 | expect( 32 | le(vec4f(0.11, -0.2, -0.3, 0.4), vec4f(0.1, 0.2, 0.3, 0.4)), 33 | ).toStrictEqual(vec4b(false, true, true, true)); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/boolean/lt.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { 3 | vec2b, 4 | vec2f, 5 | vec2i, 6 | vec3b, 7 | vec3f, 8 | vec3i, 9 | vec4b, 10 | vec4f, 11 | vec4i, 12 | } from '../../../src/data/index.ts'; 13 | import { lt } from '../../../src/std/index.ts'; 14 | 15 | describe('lt', () => { 16 | it('compares integer vectors', () => { 17 | expect(lt(vec2i(1, -1), vec2i(0, 0))).toStrictEqual(vec2b(false, true)); 18 | expect(lt(vec3i(10, 20, 20), vec3i(10, 20, 30))).toStrictEqual( 19 | vec3b(false, false, true), 20 | ); 21 | expect(lt(vec4i(1, 2, 3, 4), vec4i(4, 2, 3, 1))).toStrictEqual( 22 | vec4b(true, false, false, false), 23 | ); 24 | }); 25 | 26 | it('compares float vectors', () => { 27 | expect(lt(vec2f(0.1, 1.1), vec2f(0.1, 2))).toStrictEqual( 28 | vec2b(false, true), 29 | ); 30 | expect(lt(vec3f(1.2, 2.3, 3.4), vec3f(2.3, 3.2, 3.4))).toStrictEqual( 31 | vec3b(true, true, false), 32 | ); 33 | expect( 34 | lt(vec4f(0.1, -0.2, -0.3, 0.4), vec4f(0.1, 0.2, 0.3, 0.4)), 35 | ).toStrictEqual(vec4b(false, true, true, false)); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/boolean/not.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { vec2b, vec3b, vec4b } from '../../../src/data/index.ts'; 3 | import { not } from '../../../src/std/boolean.ts'; 4 | 5 | describe('neg', () => { 6 | it('negates', () => { 7 | expect(not(vec2b(true, false))).toStrictEqual(vec2b(false, true)); 8 | expect(not(vec3b(false, false, true))).toStrictEqual( 9 | vec3b(true, true, false), 10 | ); 11 | expect(not(vec4b(true, true, false, false))).toStrictEqual( 12 | vec4b(false, false, true, true), 13 | ); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/boolean/or.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { vec2b, vec3b, vec4b } from '../../../src/data/index.ts'; 3 | import { or } from '../../../src/std/boolean.ts'; 4 | 5 | describe('or', () => { 6 | it('ors vectors', () => { 7 | expect(or(vec2b(false, false), vec2b(true, false))).toStrictEqual( 8 | vec2b(true, false), 9 | ); 10 | expect( 11 | or(vec3b(false, true, false), vec3b(true, false, false)), 12 | ).toStrictEqual(vec3b(true, true, false)); 13 | expect( 14 | or(vec4b(false, true, false, true), vec4b(false, false, true, true)), 15 | ).toStrictEqual(vec4b(false, true, true, true)); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/numeric/acos.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { vec3f } from '../../../src/data/index.ts'; 3 | import { acos, isCloseTo } from '../../../src/std/index.ts'; 4 | 5 | describe('acos', () => { 6 | it('computes acos of numeric value', () => { 7 | expect(acos(-1)).toBeCloseTo(Math.PI); 8 | expect(acos(0)).toBeCloseTo(Math.PI / 2); 9 | expect(acos(1)).toBeCloseTo(0); 10 | }); 11 | 12 | it('computes acos for two vectors', () => { 13 | expect( 14 | isCloseTo(acos(vec3f(-1, 0, 1)), vec3f(Math.PI, Math.PI / 2, 0)), 15 | ).toBe(true); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/numeric/acosh.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { vec2f, vec3f, vec4f } from '../../../src/data/index.ts'; 3 | import { acosh, isCloseTo } from '../../../src/std/index.ts'; 4 | 5 | describe('acosh', () => { 6 | it('computes acosh of a number', () => { 7 | expect(acosh(1)).toBeCloseTo(0); 8 | expect(acosh(Math.cosh(1))).toBeCloseTo(1); 9 | expect(acosh(Math.cosh(-1))).toBeCloseTo(1); 10 | }); 11 | 12 | it('computes acosh of vec2f', () => { 13 | const input = vec2f(1, Math.cosh(1)); 14 | const expected = vec2f(Math.acosh(1), 1); 15 | expect(isCloseTo(acosh(input), expected)).toBe(true); 16 | }); 17 | 18 | it('tests acosh(cosh())', () => { 19 | const input = vec2f(1, Math.cosh(1)); 20 | const expected = vec2f(Math.acosh(1), Math.acosh(Math.cosh(1))); 21 | expect(isCloseTo(acosh(input), expected)).toBe(true); 22 | }); 23 | 24 | it('computes acosh of vec3f', () => { 25 | const input = vec3f(1, Math.cosh(1), Math.cosh(-1)); 26 | const expected = vec3f(Math.acosh(1), 1, 1); 27 | expect(isCloseTo(acosh(input), expected)).toBe(true); 28 | }); 29 | 30 | it('computes acosh of vec4f', () => { 31 | const input = vec4f(1, Math.cosh(1), Math.cosh(-1), Math.cosh(2)); 32 | const expected = vec4f(Math.acosh(1), 1, 1, 2); 33 | expect(isCloseTo(acosh(input), expected)).toBe(true); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/numeric/asin.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { vec3f } from '../../../src/data/index.ts'; 3 | import { asin, isCloseTo } from '../../../src/std/index.ts'; 4 | 5 | describe('asin', () => { 6 | it('computes asin of numeric value', () => { 7 | expect(asin(-1)).toBeCloseTo(-Math.PI / 2); 8 | expect(asin(0)).toBeCloseTo(0); 9 | expect(asin(1)).toBeCloseTo(Math.PI / 2); 10 | }); 11 | 12 | it('computes acos for two vectors', () => { 13 | expect( 14 | isCloseTo(asin(vec3f(-1, 0, 1)), vec3f(-Math.PI / 2, 0, Math.PI / 2)), 15 | ).toBe(true); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/numeric/atan2.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { vec4f } from '../../../src/data/index.ts'; 3 | import { atan2, isCloseTo } from '../../../src/std/index.ts'; 4 | 5 | describe('atan2', () => { 6 | it('computes atan2 of two values', () => { 7 | expect(atan2(0, 1)).toBeCloseTo(0); 8 | expect(atan2(1, 0)).toBeCloseTo(Math.PI / 2); 9 | expect(atan2(0, -1)).toBeCloseTo(Math.PI); 10 | expect(atan2(-1, 0)).toBeCloseTo(-Math.PI / 2); 11 | }); 12 | 13 | it('computes atan2 for two vectors', () => { 14 | expect( 15 | isCloseTo( 16 | atan2(vec4f(0, 1, 0, -1), vec4f(1, 0, -1, 0)), 17 | vec4f(0, Math.PI / 2, Math.PI, -Math.PI / 2), 18 | ), 19 | ).toBe(true); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/numeric/cosh.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { vec2f, vec3f, vec4f } from '../../../src/data/index.ts'; 3 | import { cosh, isCloseTo } from '../../../src/std/index.ts'; 4 | 5 | describe('cosh', () => { 6 | it('computes cosh of a number', () => { 7 | expect(cosh(0)).toBeCloseTo(1); 8 | expect(cosh(1)).toBeCloseTo(Math.cosh(1)); 9 | expect(cosh(-1)).toBeCloseTo(Math.cosh(-1)); 10 | }); 11 | 12 | it('computes cosh of vec2f', () => { 13 | const input = vec2f(0, 1); 14 | const expected = vec2f(Math.cosh(0), Math.cosh(1)); 15 | expect(isCloseTo(cosh(input), expected)).toBe(true); 16 | }); 17 | 18 | it('computes cosh of vec3f', () => { 19 | const input = vec3f(0, 1, -1); 20 | const expected = vec3f(Math.cosh(0), Math.cosh(1), Math.cosh(-1)); 21 | expect(isCloseTo(cosh(input), expected)).toBe(true); 22 | }); 23 | 24 | it('computes cosh of vec4f', () => { 25 | const input = vec4f(0, 1, -1, 2); 26 | const expected = vec4f( 27 | Math.cosh(0), 28 | Math.cosh(1), 29 | Math.cosh(-1), 30 | Math.cosh(2), 31 | ); 32 | expect(isCloseTo(cosh(input), expected)).toBe(true); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/numeric/cross.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { vec3f, vec3h } from '../../../src/data/index.ts'; 3 | import { cross } from '../../../src/std/index.ts'; 4 | 5 | describe('cross', () => { 6 | it('computes cross product of two vec3f', () => { 7 | expect(cross(vec3f(0, 0, 0), vec3f(0, 1, 0))).toStrictEqual(vec3f()); 8 | expect(cross(vec3f(1.5, 0, 0), vec3f(1.5, 0, 0))).toStrictEqual(vec3f()); 9 | expect(cross(vec3f(-1, 1, 0), vec3f(1, 0, 1))).toStrictEqual( 10 | vec3f(1, 1, -1), 11 | ); 12 | }); 13 | 14 | it('computes cross product of two vec3h', () => { 15 | expect(cross(vec3h(0, 0, 0), vec3h(0, 1, 0))).toStrictEqual(vec3h()); 16 | expect(cross(vec3h(1, 0, 0), vec3h(1, 0, 0))).toStrictEqual(vec3h()); 17 | expect(cross(vec3h(-1, 1, 0), vec3h(1, 0, 1))).toStrictEqual( 18 | vec3h(1, 1, -1), 19 | ); 20 | expect(cross(vec3h(2, 2, 0), vec3h(1, 4, 1))).toStrictEqual( 21 | vec3h(2, -2, 6), 22 | ); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/numeric/distance.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { vec2f, vec3h } from '../../../src/data/index.ts'; 3 | import { distance } from '../../../src/std/index.ts'; 4 | 5 | describe('distance', () => { 6 | it('computes distance between two points', () => { 7 | expect(distance(vec2f(0, 0), vec2f(0, 0))).toBeCloseTo(0); 8 | expect(distance(vec2f(0, 0), vec2f(1, 0))).toBeCloseTo(1); 9 | expect(distance(vec2f(0, 0), vec2f(0, 1))).toBeCloseTo(1); 10 | expect(distance(vec2f(0, 0), vec2f(1, 1))).toBeCloseTo(Math.sqrt(2)); 11 | 12 | expect(distance(vec3h(0, 0, 0), vec3h(0, 0, 0))).toBeCloseTo(0); 13 | expect(distance(vec3h(0, 0, 0), vec3h(1, 0, 0))).toBeCloseTo(1); 14 | expect(distance(vec3h(0, 0, 0), vec3h(0, 1, 0))).toBeCloseTo(1); 15 | expect(distance(vec3h(0, 0, 0), vec3h(0, 0, 1))).toBeCloseTo(1); 16 | expect(distance(vec3h(0, 0, 0), vec3h(1, 1, 1))).toBeCloseTo(Math.sqrt(3)); 17 | 18 | expect(distance(0, 2)).toBeCloseTo(2); 19 | expect(distance(-233, 87)).toBeCloseTo(320); 20 | }); 21 | 22 | it('does not accept different types', () => { 23 | // @ts-expect-error 24 | distance(vec2f(0, 0), vec3h(0, 0, 0)); 25 | // @ts-expect-error 26 | distance(vec2f(0, 0), 0); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/numeric/dot.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { vec2f, vec3f } from '../../../src/data/index.ts'; 3 | import { dot } from '../../../src/std/index.ts'; 4 | 5 | describe('dot', () => { 6 | it('computes dot product of two vec2f', () => { 7 | expect(dot(vec2f(0, 0), vec2f(0, 0))).toBe(0); 8 | expect(dot(vec2f(1, 0), vec2f(1, 0))).toBe(1); 9 | expect(dot(vec2f(-1, 1), vec2f(1, 0))).toBe(-1); 10 | }); 11 | 12 | it('computes dot product of two vec3f', () => { 13 | expect(dot(vec3f(0, 0, 0), vec3f(0, 1, 0))).toBe(0); 14 | expect(dot(vec3f(1, 0, 0), vec3f(1, 0, 0))).toBe(1); 15 | expect(dot(vec3f(-1, 1, 0), vec3f(1, 0, 1))).toBe(-1); 16 | }); 17 | 18 | it('dot of the same vec2f is its length squared', () => { 19 | const v1 = vec2f(2, 2); 20 | const v2 = vec2f(-1, 1); 21 | 22 | expect(dot(v1, v1)).toBe(8); 23 | expect(dot(v2, v2)).toBe(2); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/numeric/fract.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { fract } from '../../../src/std/index.ts'; 3 | 4 | describe('fract', () => { 5 | it('computes fractional part of a number', () => { 6 | expect(fract(2)).toBeCloseTo(0); 7 | expect(fract(2.2)).toBeCloseTo(0.2); 8 | expect(fract(-0.5)).toBeCloseTo(0.5); 9 | expect(fract(-0.2)).toBeCloseTo(0.8); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/numeric/length.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { vec2f, vec3f, vec4f } from '../../../src/data/index.ts'; 3 | import { length } from '../../../src/std/index.ts'; 4 | 5 | describe('length', () => { 6 | it('computes length of vec2f', () => { 7 | expect(length(vec2f(0, 0))).toBe(0); 8 | expect(length(vec2f(1, 0))).toBe(1); 9 | expect(length(vec2f(-1, 0))).toBe(1); 10 | expect(length(vec2f(0, 1))).toBe(1); 11 | expect(length(vec2f(0, -1))).toBe(1); 12 | expect(length(vec2f(3, 4))).toBe(5); 13 | }); 14 | 15 | it('computes length of vec3f', () => { 16 | expect(length(vec3f(0, 0, 0))).toBe(0); 17 | expect(length(vec3f(1, 0, 0))).toBe(1); 18 | expect(length(vec3f(-1, 0, 0))).toBe(1); 19 | expect(length(vec3f(3, 4, 0))).toBe(5); 20 | expect(length(vec3f(1, 1, 1))).toBeCloseTo(Math.sqrt(3)); 21 | }); 22 | 23 | it('computes length of vec3f', () => { 24 | expect(length(vec4f(0, 0, 0, 0))).toBe(0); 25 | expect(length(vec4f(1, 1, 1, 1))).toBe(2); 26 | expect(length(vec4f(1, 0, 0, 0))).toBe(1); 27 | expect(length(vec4f(-1, 0, 0, 0))).toBe(1); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/numeric/normalize.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { vec2f, vec3f, vec4f } from '../../../src/data/index.ts'; 3 | import { normalize } from '../../../src/std/index.ts'; 4 | 5 | describe('normalize', () => { 6 | it('computes normalized vector from vec2f', () => { 7 | expect(normalize(vec2f(1, 1)).x).toBeCloseTo(Math.sqrt(2) / 2); 8 | expect(normalize(vec2f(3, 4))).toStrictEqual(vec2f(0.6, 0.8)); 9 | }); 10 | 11 | it('computes normalized vector from vec3f', () => { 12 | expect(normalize(vec3f(1, 1, 0)).y).toBeCloseTo(Math.sqrt(2) / 2); 13 | expect(normalize(vec3f(0, 3, 4))).toStrictEqual(vec3f(0, 0.6, 0.8)); 14 | }); 15 | 16 | it('computes normalized vector from vec4f', () => { 17 | expect(normalize(vec4f(1, 0, 1, 0)).z).toBeCloseTo(Math.sqrt(2) / 2); 18 | expect(normalize(vec4f(0, 3, 0, 4))).toStrictEqual(vec4f(0, 0.6, 0, 0.8)); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/numeric/pow.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { vec2f, vec3f, vec4h } from '../../../src/data/index.ts'; 3 | import { pow } from '../../../src/std/index.ts'; 4 | 5 | describe('pow', () => { 6 | it('should return the correct power', () => { 7 | expect(pow(2, 3)).toBe(8); 8 | }); 9 | 10 | it('should return the correct power for vectors', () => { 11 | expect(pow(vec2f(2, 3), vec2f(4, 5))).toStrictEqual(vec2f(16, 243)); 12 | }); 13 | 14 | it('should handle exponent zero for scalars', () => { 15 | expect(pow(5, 0)).toBe(1); 16 | }); 17 | 18 | it('should handle exponent one for scalars', () => { 19 | expect(pow(7, 1)).toBe(7); 20 | }); 21 | 22 | it('should return correct power for vec3f with mixed exponents', () => { 23 | expect(pow(vec3f(2, 3, 4), vec3f(2, 3, 0))).toStrictEqual(vec3f(4, 27, 1)); 24 | }); 25 | 26 | it('should return correct power for float vectors with non integer values', () => { 27 | expect(pow(vec3f(2, 3.3, 4), vec3f(2.5, 3.5, 0.5))).toStrictEqual( 28 | vec3f(2 ** 2.5, 3.3 ** 3.5, 4 ** 0.5), 29 | ); 30 | }); 31 | 32 | it('should return correct power for half precision vectors', () => { 33 | expect(pow(vec4h(2, 3, 4, 5), vec4h(2, 3, 0, 1))).toStrictEqual( 34 | vec4h(4, 27, 1, 5), 35 | ); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/numeric/reflect.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { vec2f, vec3f } from '../../../src/data/index.ts'; 3 | import { reflect } from '../../../src/std/index.ts'; 4 | 5 | describe('reflect', () => { 6 | it('reflects a vec2f vector correctly', () => { 7 | const I = vec2f(1, -1); 8 | const N = vec2f(0, 1); 9 | expect(reflect(I, N)).toStrictEqual(vec2f(1, 1)); 10 | }); 11 | 12 | it('reflects a vec3f vector correctly', () => { 13 | const I = vec3f(1, -1, 0); 14 | const N = vec3f(0, 1, 0); 15 | expect(reflect(I, N)).toStrictEqual(vec3f(1, 1, 0)); 16 | }); 17 | 18 | it('reflects a vec2f vector with no angle change when incident angle is zero', () => { 19 | const I = vec2f(3, 4); 20 | const N = vec2f(0, 1); 21 | expect(reflect(I, N)).toStrictEqual(vec2f(3, -4)); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/numeric/sign.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { vec3f } from '../../../src/data/index.ts'; 3 | import { isCloseTo, sign } from '../../../src/std/index.ts'; 4 | 5 | describe('sign', () => { 6 | it('computes sign of numeric value', () => { 7 | expect(sign(-1000)).toBe(-1); 8 | expect(sign(0)).toBe(0); 9 | expect(sign(2000)).toBe(1); 10 | }); 11 | 12 | it('computes sign of a numeric vector', () => { 13 | expect(isCloseTo(sign(vec3f(-1000, 0, 2000)), vec3f(-1, 0, 1))).toBe(true); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/typegpu/tests/std/packing.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { vec2f, vec4f } from '../../src/data/vector.ts'; 3 | import { 4 | pack2x16float, 5 | pack4x8unorm, 6 | unpack2x16float, 7 | unpack4x8unorm, 8 | } from '../../src/std/packing.ts'; 9 | 10 | describe('packing', () => { 11 | it('packs and unpacks 4x8 unorm', () => { 12 | const packed = pack4x8unorm(vec4f(0.5, 0.25, 0.75, 1)); 13 | const unpacked = unpack4x8unorm(packed); 14 | expect(unpacked.x).toBeCloseTo(0.5); 15 | expect(unpacked.y).toBeCloseTo(0.25); 16 | expect(unpacked.z).toBeCloseTo(0.75); 17 | expect(unpacked.w).toBeCloseTo(1); 18 | }); 19 | 20 | it('packs and unpacks 2x16 float', () => { 21 | const packed = pack2x16float(vec2f(0.5, 0.25)); 22 | const unpacked = unpack2x16float(packed); 23 | expect(unpacked.x).toBeCloseTo(0.5); 24 | expect(unpacked.y).toBeCloseTo(0.25); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/typegpu/tests/tgsl/codeGen.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect } from 'vitest'; 2 | import { it } from '../utils/extendedIt.ts'; 3 | import { parse, parseResolved } from '../utils/parseResolved.ts'; 4 | 5 | // Library entrypoints 6 | import { tgpu } from '../../src/index.ts'; 7 | import * as d from '../../src/data/index.ts'; 8 | 9 | describe('codeGen', () => { 10 | describe('vectors', () => { 11 | it('handles member access for external vectors', () => { 12 | const size = d.vec3f(1, 2, 3); 13 | const main = tgpu['~unstable'].fn([], d.f32)(() => { 14 | return size.x * size.y * size.z; 15 | }); 16 | 17 | expect(parseResolved({ main })).toBe( 18 | parse('fn main() -> f32 { return ((1 * 2) * 3); }'), 19 | ); 20 | }); 21 | 22 | it('handles member access for local vectors', () => { 23 | const main = tgpu['~unstable'].fn([], d.f32)(() => { 24 | const size = d.vec3f(1, 2, 3); 25 | return size.x * size.y * size.z; 26 | }); 27 | 28 | expect(parseResolved({ main })).toBe(parse(` 29 | fn main() -> f32 { 30 | var size = vec3f(1, 2, 3); 31 | return ((size.x * size.y) * size.z); 32 | } 33 | `)); 34 | }); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /packages/typegpu/tests/utils/parseResolved.ts: -------------------------------------------------------------------------------- 1 | import { WeslStream } from 'wesl'; 2 | import type { TgpuResolveOptions } from '../../src/core/resolve/tgpuResolve.ts'; 3 | import tgpu from '../../src/index.ts'; 4 | 5 | export function parse(code: string): string { 6 | const stream = new WeslStream(code); 7 | const firstToken = stream.nextToken(); 8 | if (firstToken === null) { 9 | return ''; 10 | } 11 | 12 | let result = firstToken.text; 13 | let token = stream.nextToken(); 14 | while (token !== null) { 15 | result += ` ${token.text}`; 16 | token = stream.nextToken(); 17 | } 18 | return result; 19 | } 20 | 21 | export function parseResolved( 22 | resolvable: TgpuResolveOptions['externals'], 23 | ): string { 24 | const resolved = tgpu.resolve({ 25 | externals: resolvable, 26 | names: 'strict', 27 | }); 28 | 29 | try { 30 | return parse(resolved); 31 | } catch (e) { 32 | throw new Error( 33 | `Failed to parse the following: \n${resolved}\n\nCause:${ 34 | String(e).substring(0, 128) 35 | }`, 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/typegpu/tests/utils/webgpuGlobals.ts: -------------------------------------------------------------------------------- 1 | global.GPUBufferUsage = { 2 | MAP_READ: 1, 3 | MAP_WRITE: 2, 4 | COPY_SRC: 4, 5 | COPY_DST: 8, 6 | INDEX: 16, 7 | VERTEX: 32, 8 | UNIFORM: 64, 9 | STORAGE: 128, 10 | INDIRECT: 256, 11 | QUERY_RESOLVE: 512, 12 | }; 13 | 14 | global.GPUMapMode = { 15 | READ: 0, 16 | WRITE: 1, 17 | }; 18 | 19 | global.GPUTextureUsage = { 20 | COPY_SRC: 1, 21 | COPY_DST: 2, 22 | TEXTURE_BINDING: 4, 23 | STORAGE_BINDING: 8, 24 | RENDER_ATTACHMENT: 16, 25 | }; 26 | 27 | global.GPUShaderStage = { 28 | VERTEX: 1, 29 | FRAGMENT: 2, 30 | COMPUTE: 4, 31 | }; 32 | -------------------------------------------------------------------------------- /packages/typegpu/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["src/**/*"], 4 | "exclude": ["node_modules", "dist"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/typegpu/tsconfig.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["tests/**/*", "src/**/*"], 4 | "exclude": ["node_modules", "dist"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/typegpu/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { initBuildScript } from '@typegpu/tgpu-dev-cli'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | const { inDevMode } = initBuildScript(); 5 | 6 | const entry = ['src/index.ts', 'src/data/index.ts', 'src/std/index.ts']; 7 | 8 | // TODO: Consider stripping `invariant()` calls of their messages for a smaller bundle size. 9 | export default defineConfig({ 10 | entry, 11 | outDir: 'dist', 12 | format: ['cjs', 'esm'], 13 | target: 'es2024', 14 | splitting: true, 15 | sourcemap: true, 16 | minify: !inDevMode, 17 | clean: true, 18 | dts: true, 19 | define: { 20 | 'process.env.NODE_ENV': JSON.stringify( 21 | inDevMode ? 'development' : 'production', 22 | ), 23 | }, 24 | }); 25 | -------------------------------------------------------------------------------- /packages/typegpu/vitest.config.mts: -------------------------------------------------------------------------------- 1 | import { createJiti } from 'jiti'; 2 | import type TypeGPUPlugin from 'unplugin-typegpu/vite'; 3 | import { defineConfig } from 'vitest/config'; 4 | 5 | const jiti = createJiti(import.meta.url); 6 | const typegpu = await jiti.import( 7 | 'unplugin-typegpu/vite', 8 | { default: true }, 9 | ); 10 | 11 | export default defineConfig({ 12 | plugins: [typegpu({ forceTgpuAlias: 'tgpu' })], 13 | test: { 14 | globalSetup: ['setupVitest.ts'], 15 | }, 16 | }); 17 | -------------------------------------------------------------------------------- /packages/unplugin-typegpu/deno.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": ["."], 3 | "fmt": { 4 | "exclude": ["!."], 5 | "singleQuote": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/unplugin-typegpu/src/esbuild.ts: -------------------------------------------------------------------------------- 1 | import { esbuildPlugin } from './index.ts'; 2 | 3 | export default esbuildPlugin; 4 | -------------------------------------------------------------------------------- /packages/unplugin-typegpu/src/farm.ts: -------------------------------------------------------------------------------- 1 | import { farmPlugin } from './index.ts'; 2 | 3 | export default farmPlugin; 4 | -------------------------------------------------------------------------------- /packages/unplugin-typegpu/src/rolldown.ts: -------------------------------------------------------------------------------- 1 | import { rolldownPlugin } from './index.ts'; 2 | 3 | export default rolldownPlugin; 4 | -------------------------------------------------------------------------------- /packages/unplugin-typegpu/src/rollup.ts: -------------------------------------------------------------------------------- 1 | import { rollupPlugin } from './index.ts'; 2 | 3 | export default rollupPlugin; 4 | -------------------------------------------------------------------------------- /packages/unplugin-typegpu/src/rspack.ts: -------------------------------------------------------------------------------- 1 | import { rspackPlugin } from './index.ts'; 2 | 3 | export default rspackPlugin; 4 | -------------------------------------------------------------------------------- /packages/unplugin-typegpu/src/vite.ts: -------------------------------------------------------------------------------- 1 | import { vitePlugin } from './index.ts'; 2 | 3 | export default vitePlugin; 4 | -------------------------------------------------------------------------------- /packages/unplugin-typegpu/src/webpack.ts: -------------------------------------------------------------------------------- 1 | import { webpackPlugin } from './index.ts'; 2 | 3 | export default webpackPlugin; 4 | -------------------------------------------------------------------------------- /packages/unplugin-typegpu/test/transform.ts: -------------------------------------------------------------------------------- 1 | import Babel from '@babel/standalone'; 2 | import virtual from '@rollup/plugin-virtual'; 3 | import { rollup } from 'rollup'; 4 | import babelPlugin from '../src/babel.ts'; 5 | import type { Options } from '../src/common.ts'; 6 | import rollupPlugin from '../src/rollup.ts'; 7 | 8 | const defaultOptions: Options = { 9 | include: [/\.m?[jt]sx?$/, /virtual:/], 10 | }; 11 | 12 | export const babelTransform = (code: string, options = defaultOptions) => 13 | Babel.transform(code, { 14 | plugins: [[babelPlugin, options]], 15 | parserOpts: { plugins: ['typescript'] }, 16 | }).code; 17 | 18 | export const rollupTransform = (code: string, options = defaultOptions) => 19 | rollup({ 20 | input: 'code', 21 | plugins: [virtual({ code }), rollupPlugin(options)], 22 | external: ['typegpu', /^typegpu\/.*$/], 23 | }) 24 | .then((build) => build.generate({})) 25 | .then((generated) => generated.output[0].code); 26 | -------------------------------------------------------------------------------- /packages/unplugin-typegpu/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["src/**/*", "test/**/*"], 4 | "exclude": ["node_modules", "dist"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/unplugin-typegpu/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { initBuildScript } from '@typegpu/tgpu-dev-cli'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | const { inDevMode } = initBuildScript(); 5 | 6 | export default defineConfig({ 7 | entry: [ 8 | 'src/index.ts', 9 | 'src/rollup.ts', 10 | 'src/babel.ts', 11 | 'src/esbuild.ts', 12 | 'src/farm.ts', 13 | 'src/rolldown.ts', 14 | 'src/rspack.ts', 15 | 'src/vite.ts', 16 | 'src/webpack.ts', 17 | ], 18 | outDir: 'dist', 19 | format: ['cjs', 'esm'], 20 | tsconfig: './tsconfig.json', 21 | target: 'es2017', 22 | splitting: true, 23 | sourcemap: true, 24 | minify: !inDevMode, 25 | clean: !inDevMode, 26 | dts: true, 27 | }); 28 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'packages/*' 3 | - 'apps/*' 4 | 5 | catalog: 6 | arktype: ^2.1.15 7 | typescript: ^5.8.2 8 | tsup: ^8.5.0 9 | unbuild: ^3.5.0 10 | '@webgpu/types': ^0.1.54 11 | vitest: ^3.0.9 12 | -------------------------------------------------------------------------------- /projects-using-typegpu.md: -------------------------------------------------------------------------------- 1 | - [Chaos Master](https://chaos-master.vercel.app) by deluksic & Komediruzecki 2 | - [Apollonian Circles](https://deluksic.github.io/apollonian-circles/) by 3 | deluksic 4 | - [Strange Forms](https://github.com/loganzartman/strangeforms) by Logan Zartman 5 | - [WebGPU Stable Fluids](https://github.com/loganzartman/webgpu-stable-fluids) 6 | by Logan Zartman 7 | - [Visual timer: Calm Jar](https://apps.apple.com/us/app/visual-timer-calm-jar/id6741375962) 8 | by Nathan Schmidt 9 | -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "${configDir}/dist", 4 | "baseUrl": "${configDir}", 5 | "declaration": true, 6 | "declarationMap": true, 7 | "lib": ["ESNext", "DOM"], 8 | "emitDeclarationOnly": true, 9 | "target": "ESNext", 10 | "module": "ESNext", 11 | "strict": true, 12 | "allowImportingTsExtensions": true, 13 | "allowJs": true, 14 | "esModuleInterop": true, 15 | "moduleResolution": "bundler", 16 | "noUncheckedIndexedAccess": true, 17 | "exactOptionalPropertyTypes": true, 18 | "skipLibCheck": true, 19 | "typeRoots": [ 20 | "./node_modules/@types", 21 | "${configDir}/node_modules/@types", 22 | "./node_modules/@webgpu/types" 23 | ] 24 | }, 25 | "exclude": ["${configDir}/dist", "${configDir}/node_modules"] 26 | } 27 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json" 3 | } 4 | -------------------------------------------------------------------------------- /vitest.config.mts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config'; 2 | 3 | export default defineConfig({}); 4 | -------------------------------------------------------------------------------- /vitest.workspace.ts: -------------------------------------------------------------------------------- 1 | export default ['packages/*']; 2 | --------------------------------------------------------------------------------