<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/exploring-procedural-geometry-with-three-js-and-webgpu-fmy1y3gze" -->

---
title: Exploring Procedural Geometry with Three.js and WebGPU
description: A deep technical walkthrough of building a Three.js Geometry Painter using WebGPU and TSL (Three.js Shading Language). The author covers surface picking with...
canonical: https://daily.dev/posts/exploring-procedural-geometry-with-three-js-and-webgpu-fmy1y3gze
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Exploring Procedural Geometry with Three.js and WebGPU | daily.dev
og:description: A deep technical walkthrough of building a Three.js Geometry Painter using WebGPU and TSL (Three.js Shading Language). The author covers surface picking with...
og:url: https://daily.dev/posts/exploring-procedural-geometry-with-three-js-and-webgpu-fmy1y3gze
og:image: https://api.daily.dev/og/posts/fMY1y3gzE.png
og:image:alt: Exploring Procedural Geometry with Three.js and WebGPU
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Exploring Procedural Geometry with Three.js and WebGPU

**[Codrops](https://daily.dev/sources/codrops)** · 27 min read · 1 upvotes · 0 comments

## Summary

A deep technical walkthrough of building a Three.js Geometry Painter using WebGPU and TSL (Three.js Shading Language). The author covers surface picking with BVH raycasting, path resampling to fix pointer-event density issues, a pluggable mode architecture that separates painting infrastructure from geometry generation, and a key constraint — no memory allocation during slider interaction — that drives the entire design. Four painting modes are detailed: transmissive crystal clusters, molten fissure ribbons with GPU-side width, aurora silk curtains with fold-locked lighting, and a bioluminescent reef using a shared world-space pulse wave. WebGPU-specific gotchas (points always render as one pixel, line width is ignored) and post-processing setup with bloom, vignette, and ACES tone mapping are also covered.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://tympanus.net/codrops/2026/08/11/exploring-procedural-geometry-with-three-js-and-webgpu>

## Questions this post answers

### Why does PointsMaterial with sizeAttenuation render as a single pixel in Three.js WebGPU renderer?

Point primitives simply don't support a size attribute under the WebGPU backend, so PointsMaterial with size 0.02 and sizeAttenuation true renders as one pixel per point regardless of settings. The workaround is to use instanced quads with a soft radial sprite texture instead, each given a fixed random orientation at spawn to avoid per-frame billboarding updates.

_Developers hitting silent WebGPU rendering quirks like this can find workaround patterns curated on daily.dev._

### How do you avoid geometry rebuilds when a density slider changes in a Three.js instanced mesh scene?

Generate every instance at the slider's maximum value once, store each as generative parameters plus a stable random rank, then use that rank purely for visibility culling on each settings change. A culled instance gets a zero-scale matrix but stays in the same buffer and draw call, which on modern GPUs costs almost nothing, avoiding reallocation and random-number reshuffling during live dragging.

_Anyone optimizing real-time slider-driven 3D scenes can track performance techniques like this via daily.dev._

### Why does Three.js Line with linewidth not render thick lines in the WebGPU renderer?

Line width is ignored by the WebGPU backend just like point size, so a Line with linewidth 3 renders as a hairline regardless of the value set. The fix is replacing it with an InstancedMesh of overlapping small spheres, one bead per sample, with a radius chosen so consecutive beads overlap enough to read as one continuous stroke.

_Developers porting Three.js scenes to WebGPU can watch for rendering pitfalls like this through daily.dev._

## Similar posts on daily.dev

- [Drawing With Light: An Exploration of Lit GPU Tubes with TSL and WebGPU](https://daily.dev/posts/drawing-with-light-an-exploration-of-lit-gpu-tubes-with-tsl-and-webgpu-hcfish0ru) · Codrops · 0 upvotes · 0 comments
- [Creating an Interactive 3D Cluster with Three.js, TSL and Three Start](https://daily.dev/posts/creating-an-interactive-3d-cluster-with-three-js-tsl-and-three-start-y4sedpfai) · Codrops · 2 upvotes · 0 comments
- [THREE.js-PathTracing-Renderer](https://daily.dev/posts/three-js-pathtracing-renderer-f7kf7vkhm) · Hacker News · 2 upvotes · 0 comments
- [Explore This Tactile UI Powered By Real-Time WebGL Shader](https://daily.dev/posts/explore-this-tactile-ui-powered-by-real-time-webgl-shader-unjsszd7a) · 80 LEVEL · 1 upvotes · 0 comments
- [Graphics Programming weekly - Issue 413 - October 19th, 2025](https://daily.dev/posts/graphics-programming-weekly---issue-413---october-19th-2025-uunemw880) · Jendrik Illner · 2 upvotes · 0 comments

---

Tags: [#threejs](https://daily.dev/tags/threejs), [#webgpu](https://daily.dev/tags/webgpu)

[View this post on daily.dev](https://daily.dev/posts/exploring-procedural-geometry-with-three-js-and-webgpu-fmy1y3gze)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Exploring Procedural Geometry with Three.js and WebGPU","url":"https://daily.dev/posts/exploring-procedural-geometry-with-three-js-and-webgpu-fmy1y3gze","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/exploring-procedural-geometry-with-three-js-and-webgpu-fmy1y3gze"},"datePublished":"2026-08-11T14:30:46.728Z","dateModified":"2026-09-13T19:44:05.633Z","description":"A deep technical walkthrough of building a Three.js Geometry Painter using WebGPU and TSL (Three.js Shading Language). The author covers surface picking with...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/d1230e3e6af8780a34b40da7361df294?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/d1230e3e6af8780a34b40da7361df294?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Codrops","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Codrops","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/codrops","url":"https://daily.dev/sources/codrops"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/exploring-procedural-geometry-with-three-js-and-webgpu-fmy1y3gze","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"threejs,webgpu","timeRequired":"PT27M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Codrops","item":"https://daily.dev/sources/codrops"},{"@type":"ListItem","position":3,"name":"Exploring Procedural Geometry with Three.js and WebGPU"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/exploring-procedural-geometry-with-three-js-and-webgpu-fmy1y3gze#faq","mainEntity":[{"@type":"Question","name":"Why does PointsMaterial with sizeAttenuation render as a single pixel in Three.js WebGPU renderer?","acceptedAnswer":{"@type":"Answer","text":"Point primitives simply don't support a size attribute under the WebGPU backend, so PointsMaterial with size 0.02 and sizeAttenuation true renders as one pixel per point regardless of settings. The workaround is to use instanced quads with a soft radial sprite texture instead, each given a fixed random orientation at spawn to avoid per-frame billboarding updates. Developers hitting silent WebGPU rendering quirks like this can find workaround patterns curated on daily.dev."}},{"@type":"Question","name":"How do you avoid geometry rebuilds when a density slider changes in a Three.js instanced mesh scene?","acceptedAnswer":{"@type":"Answer","text":"Generate every instance at the slider's maximum value once, store each as generative parameters plus a stable random rank, then use that rank purely for visibility culling on each settings change. A culled instance gets a zero-scale matrix but stays in the same buffer and draw call, which on modern GPUs costs almost nothing, avoiding reallocation and random-number reshuffling during live dragging. Anyone optimizing real-time slider-driven 3D scenes can track performance techniques like this via daily.dev."}},{"@type":"Question","name":"Why does Three.js Line with linewidth not render thick lines in the WebGPU renderer?","acceptedAnswer":{"@type":"Answer","text":"Line width is ignored by the WebGPU backend just like point size, so a Line with linewidth 3 renders as a hairline regardless of the value set. The fix is replacing it with an InstancedMesh of overlapping small spheres, one bead per sample, with a radius chosen so consecutive beads overlap enough to read as one continuous stroke. Developers porting Three.js scenes to WebGPU can watch for rendering pitfalls like this through daily.dev."}}]}
```

