Skip to content

feat: texture painter experiment with per-texture canvas editors#88

Open
cnotv wants to merge 10 commits into
mainfrom
feat/87-texture-painter
Open

feat: texture painter experiment with per-texture canvas editors#88
cnotv wants to merge 10 commits into
mainfrom
feat/87-texture-painter

Conversation

@cnotv

@cnotv cnotv commented Apr 28, 2026

Copy link
Copy Markdown
Owner

Closes #87

Summary

  • New Experiments/TexturePainter view: a 3D sphere with live material preview and per-texture painting
  • Extracted buildMaterial from MaterialsList.vue into src/utils/materialBuilder.ts shared utility
  • Both MaterialsList and TexturePainter share the same material-building logic without duplication

Key Changes

  • src/utils/materialBuilder.ts — Shared utility; splits into applyTextureParameters + applyMaterialTypeParameters helpers
  • src/views/Experiments/TexturePainter/config.ts — Re-exports shared constants; adds painter-specific constants (PAINTER_*, TEXTURE_SLOT_*, STORAGE_PREFIX)
  • src/views/Experiments/TexturePainter/TexturePainter.vue — Sphere scene with orthographic camera + orbiting light. Config panel: ButtonSelector for material type + property sliders. Maps toggles in Scene panel via registerSceneConfig. <Teleport to="#config-panel-extra"> injects texture slot selector + colour palette + CanvasEditor; appears immediately below the property sliders. Painted textures backed by offscreen canvases wired as THREE.CanvasTexture, saved to localStorage. Drag to rotate sphere
  • src/views/Experiments/MaterialsList/MaterialsList.vue — Imports buildMaterial from shared utility
  • src/config/viewsMeta.json — Adds "Texture Painter" entry
  • src/components/panels/PanelContainer.vueoverflow-y: auto removed from container (desktop), moved to .sheet-content so panels scroll independently; mobile keeps container scroll

Test Plan

  • Navigate to /experiments/TexturePainter — sphere renders with Standard material
  • Config panel opens automatically; shows Material selector + property sliders; texture editors appear immediately below
  • Scene panel shows Maps toggles; toggling disables/enables a texture on the sphere
  • Select a texture slot (Diffuse, Normal, etc.), pick a colour, paint → sphere updates in real time
  • Reload — painted textures restored from localStorage
  • Drag sphere to rotate it
  • MaterialsList still renders correctly
  • 815 unit tests pass; 0 type errors; 0 lint errors

🤖 Generated with Claude Code

- Extract buildMaterial to src/utils/materialBuilder.ts shared utility
- Create TexturePainter view: sphere preview with all material controls
- Per-texture CanvasEditor with limited 2-4 color palette per slot
- Textures persisted to localStorage via storageSaveLocal
- Remove overflow from PanelContainer except on mobile

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@netlify

netlify Bot commented Apr 28, 2026

Copy link
Copy Markdown

Deploy Preview for cnotv-generative-art ready!

Name Link
🔨 Latest commit f49c060
🔍 Latest deploy log https://app.netlify.com/projects/cnotv-generative-art/deploys/69f6968fd4a6020008b62191
😎 Deploy Preview https://deploy-preview-88--cnotv-generative-art.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

cnotv and others added 9 commits April 29, 2026 08:54
- Add overflow-y: auto to .sheet-content so panels scroll on desktop
- Move maps toggles to Scene panel via registerSceneConfig, reducing
  Config panel height so texture editors are visible without scrolling

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace panel CanvasEditor with direct sphere painting
- Raycast mouse position to sphere UV coordinates, draw strokes on
  the corresponding offscreen canvas, set needsUpdate on the texture
- Config panel: Mode toggle (Paint/Rotate), texture slot selector,
  colour picker, brush size slider
- In Paint mode: left-click drag on sphere paints; cursor is crosshair
- In Rotate mode: left-click drag on sphere rotates; cursor is grab

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New src/components/DrawingToolbar: reusable icon toolbar with
  brush, eraser, fill, rotate, color picker, brush size
- CanvasEditorTools refactored to use DrawingToolbar for core buttons
- TexturePainter: replace Mode text toggle + config sliders with
  DrawingToolbar via Teleport; toolbar shows texture slot tabs,
  icon tool buttons, reset buttons
- activeTool/brushColor/brushSize are local refs, not schema-driven

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…xtures

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…lette

- DrawingToolbar: add canUndo/canRedo props + undo/redo icon buttons
- TexturePainter strengths group in Config panel (normalScale, aoIntensity,
  displacementScale, emissiveIntensity, envMapIntensity) applied after
  buildMaterial to override hardcoded defaults
- Per-slot undo/redo history (max 20 steps); pushes on mouseUp after paint
- Eraser: uses globalCompositeOperation destination-out
- Fill: BFS flood fill at UV hit point
- Per-slot palette swatches in toolbar; auto-selects first palette color
  when switching slots if current color is not in the new slot's palette

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The external getValue/updateValue approach used with registerSceneConfig
was not rendering controls. Maps are now part of the view config schema
so they use the same working path resolution as other controls.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each preset applies materialType, properties, strengths, maps, and
regenerates all six texture slots with matching procedural patterns:
- Glass: MeshPhysicalMaterial, transmission=0.95, subtle wave normals
- Metal: anisotropic scratches on diffuse/normal/roughness
- Rock: sin-wave noise diffuse/normal/displacement, high roughness
- Magic: dark sphere with glowing emissive orbs and energy lines
- Cutout: circular hole displacement + AO shadow mapping effect

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…er-view accordion state

- Remove all presets; keep plain ball with full PBR config controls
- Add image load per texture slot (file input in config panel toolbar)
- Add lake.webp as equirectangular scene background + env map source
- Generate all 6 PBR maps from hyde.webp (Sobel normal, roughness, AO,
  displacement) with seamless offset-blend tiling
- Convert lake.heic → lake.webp (149kb), hyde.jpg → hyde.webp (270kb)
- Config panel auto-opens on mount via openPanel('config')
- Per-view accordion default: __defaultOpenGroups in schema; TexturePainter
  starts collapsed, other views stay fully open
- Fix __vnode crash: replace canvas function-refs with img+dataURL previews
- Fix config.ts export loss: restore all PAINTER_* and TEXTURE_SLOT_* constants

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create experiment to paint textures in browser using canvases

1 participant