Claude
Skills
Sign in
Back

threejs-tresjs

Included with Lifetime
$97 forever

3D HUD rendering with Three.js and TresJS for JARVIS AI Assistant

General

What this skill does


# Three.js / TresJS Development Skill

> **File Organization**: This skill uses split structure. See `references/` for advanced patterns and security examples.

## 1. Overview

This skill provides expertise for building 3D HUD interfaces using Three.js and TresJS (Vue 3 integration). It focuses on creating performant, visually stunning holographic displays for the JARVIS AI Assistant.

**Risk Level**: MEDIUM - GPU resource consumption, potential ReDoS in color parsing, WebGL security considerations

**Primary Use Cases**:
- Rendering 3D holographic HUD panels
- Animated status indicators and gauges
- Particle effects for system visualization
- Real-time metric displays with 3D elements

## 2. Core Responsibilities

### 2.1 Fundamental Principles

1. **TDD First**: Write tests before implementation - verify 3D components render correctly
2. **Performance Aware**: Optimize for 60fps with instancing, LOD, and efficient render loops
3. **Resource Management**: Always dispose of geometries, materials, and textures to prevent memory leaks
4. **Vue Reactivity Integration**: Use TresJS for seamless Vue 3 composition API integration
5. **Safe Color Parsing**: Validate color inputs to prevent ReDoS attacks
6. **GPU Protection**: Implement safeguards against GPU resource exhaustion
7. **Accessibility**: Provide fallbacks for devices without WebGL support

## 3. Technology Stack & Versions

### 3.1 Recommended Versions

| Package | Version | Security Notes |
|---------|---------|----------------|
| three | ^0.160.0+ | Latest stable, fixes CVE-2020-28496 ReDoS |
| @tresjs/core | ^4.0.0 | Vue 3 integration |
| @tresjs/cientos | ^3.0.0 | Component library |
| postprocessing | ^6.0.0 | Effects library |

### 3.2 Security-Critical Updates

```json
{
  "dependencies": {
    "three": "^0.160.0",
    "@tresjs/core": "^4.0.0",
    "@tresjs/cientos": "^3.0.0"
  }
}
```

**Note**: Versions before 0.137.0 have XSS vulnerabilities, before 0.125.0 have ReDoS vulnerabilities.

## 4. Implementation Patterns

### 4.1 Basic HUD Scene Setup

```vue
<script setup lang="ts">
import { TresCanvas } from '@tresjs/core'
import { OrbitControls } from '@tresjs/cientos'

const gl = {
  clearColor: '#000011',
  alpha: true,
  antialias: true,
  powerPreference: 'high-performance'
}
</script>

<template>
  <TresCanvas v-bind="gl">
    <TresPerspectiveCamera :position="[0, 0, 5]" />
    <OrbitControls :enable-damping="true" />

    <HUDPanels />
    <MetricsDisplay />
    <ParticleEffects />
  </TresCanvas>
</template>
```

### 4.2 Secure Color Handling

```typescript
// utils/safeColor.ts
import { Color } from 'three'

// ✅ Safe color parsing with validation
export function safeParseColor(input: string): Color {
  // Validate format to prevent ReDoS
  const hexPattern = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/
  const rgbPattern = /^rgb\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*\)$/

  if (!hexPattern.test(input) && !rgbPattern.test(input)) {
    console.warn('Invalid color format, using default')
    return new Color(0x00ff00)  // Default JARVIS green
  }

  return new Color(input)
}

// ❌ DANGEROUS - User input directly to Color
// const color = new Color(userInput)  // Potential ReDoS

// ✅ SECURE - Validated input
const color = safeParseColor(userInput)
```

### 4.3 Memory-Safe Component

```vue
<script setup lang="ts">
import { onUnmounted, shallowRef } from 'vue'
import { Mesh, BoxGeometry, MeshStandardMaterial } from 'three'

// ✅ Use shallowRef for Three.js objects
const meshRef = shallowRef<Mesh | null>(null)

// ✅ Cleanup on unmount
onUnmounted(() => {
  if (meshRef.value) {
    meshRef.value.geometry.dispose()
    if (Array.isArray(meshRef.value.material)) {
      meshRef.value.material.forEach(m => m.dispose())
    } else {
      meshRef.value.material.dispose()
    }
  }
})
</script>

<template>
  <TresMesh ref="meshRef">
    <TresBoxGeometry :args="[1, 1, 1]" />
    <TresMeshStandardMaterial color="#00ff41" />
  </TresMesh>
</template>
```

### 4.4 Performance-Optimized Instancing

```vue
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { InstancedMesh, Object3D, Matrix4 } from 'three'

const instanceCount = 1000
const instancedMeshRef = ref<InstancedMesh | null>(null)

onMounted(() => {
  if (!instancedMeshRef.value) return

  const dummy = new Object3D()
  const matrix = new Matrix4()

  // ✅ Batch updates for performance
  for (let i = 0; i < instanceCount; i++) {
    dummy.position.set(
      Math.random() * 10 - 5,
      Math.random() * 10 - 5,
      Math.random() * 10 - 5
    )
    dummy.updateMatrix()
    instancedMeshRef.value.setMatrixAt(i, dummy.matrix)
  }

  instancedMeshRef.value.instanceMatrix.needsUpdate = true
})
</script>

<template>
  <TresInstancedMesh ref="instancedMeshRef" :args="[null, null, instanceCount]">
    <TresSphereGeometry :args="[0.05, 8, 8]" />
    <TresMeshBasicMaterial color="#00ff41" />
  </TresInstancedMesh>
</template>
```

### 4.5 HUD Panel with Text

```vue
<script setup lang="ts">
import { Text } from '@tresjs/cientos'

const props = defineProps<{
  title: string
  value: number
}>()

// ✅ Sanitize text content
const safeTitle = computed(() =>
  props.title.replace(/[<>]/g, '').slice(0, 50)
)
</script>

<template>
  <TresGroup>
    <!-- Panel background -->
    <TresMesh>
      <TresPlaneGeometry :args="[2, 1]" />
      <TresMeshBasicMaterial
        color="#001122"
        :transparent="true"
        :opacity="0.8"
      />
    </TresMesh>

    <!-- Title text -->
    <Text
      :text="safeTitle"
      :font-size="0.15"
      color="#00ff41"
      :position="[-0.8, 0.3, 0.01]"
    />

    <!-- Value display -->
    <Text
      :text="String(props.value)"
      :font-size="0.3"
      color="#ffffff"
      :position="[0, -0.1, 0.01]"
    />
  </TresGroup>
</template>
```

## 5. Implementation Workflow (TDD)

### 5.1 TDD Process for 3D Components

**Step 1: Write Failing Test First**

```typescript
// tests/components/hud-panel.test.ts
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
import { mount, VueWrapper } from '@vue/test-utils'
import { Scene, WebGLRenderer } from 'three'
import HUDPanel from '~/components/hud/HUDPanel.vue'

describe('HUDPanel', () => {
  let wrapper: VueWrapper

  beforeEach(() => {
    // Mock WebGL context for testing
    const canvas = document.createElement('canvas')
    const gl = canvas.getContext('webgl2')
    vi.spyOn(HTMLCanvasElement.prototype, 'getContext').mockReturnValue(gl)
  })

  afterEach(() => {
    wrapper?.unmount()
    vi.restoreAllMocks()
  })

  it('renders panel with correct dimensions', () => {
    wrapper = mount(HUDPanel, {
      props: { width: 2, height: 1, title: 'Status' }
    })

    // Test fails until component is implemented
    expect(wrapper.exists()).toBe(true)
  })

  it('disposes resources on unmount', async () => {
    wrapper = mount(HUDPanel, {
      props: { width: 2, height: 1, title: 'Status' }
    })

    const disposeSpy = vi.fn()
    wrapper.vm.meshRef.geometry.dispose = disposeSpy

    wrapper.unmount()
    expect(disposeSpy).toHaveBeenCalled()
  })
})
```

**Step 2: Implement Minimum to Pass**

```vue
<script setup lang="ts">
import { shallowRef, onUnmounted } from 'vue'
import { Mesh } from 'three'

const props = defineProps<{
  width: number
  height: number
  title: string
}>()

const meshRef = shallowRef<Mesh | null>(null)

onUnmounted(() => {
  if (meshRef.value) {
    meshRef.value.geometry.dispose()
    ;(meshRef.value.material as any).dispose()
  }
})
</script>

<template>
  <TresMesh ref="meshRef">
    <TresPlaneGeometry :args="[props.width, props.height]" />
    <TresMeshBasicMaterial color="#001122" :transparent="true" :opacity="0.8" />
  </TresMesh>
</template>
```

**Step 3: Refactor Following Patterns**

```typescript
// After tests pass, add performance optimizations
// - Use instancing for multiple panels
// - Add LOD for distant panels
// - Implement texture atlases for text
```

**Step 4: Run Full Verificati

Related in General