Skip to content

Commit

Permalink
docs: attach (#869)
Browse files Browse the repository at this point in the history
* test(utils.resolve): add tests for camelCase, array indices

* docs(attach): add playground demos for attach

* docs(attach): add documentation for attach prop

* Update docs/advanced/attach.md

Co-authored-by: Tino Koch <[email protected]>

---------

Co-authored-by: Alvaro Saburido <[email protected]>
Co-authored-by: Tino Koch <[email protected]>
  • Loading branch information
3 people authored Nov 10, 2024
1 parent 4adc3bc commit fbcbdc3
Show file tree
Hide file tree
Showing 10 changed files with 405 additions and 5 deletions.
1 change: 1 addition & 0 deletions docs/.vitepress/config/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export const enConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
{ text: 'Extending', link: '/advanced/extending' },
{ text: 'Primitives', link: '/advanced/primitive' },
{ text: 'Scaling Performance 🚀', link: '/advanced/performance' },
{ text: 'Attach', link: '/advanced/attach' },
{
text: 'Caveats',
link: '/advanced/caveats',
Expand Down
190 changes: 190 additions & 0 deletions docs/advanced/attach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
# `attach` 🖇

Using the `attach` prop, you can tell Tres exactly where you want to insert a child into its parent.

:::info

The `attach` prop is not required for many common cases. For instance:

* adding a single `<Material>` to a `<Mesh>`
* adding a `<Geometry>` to a `<Mesh>`
* adding one or more `<Mesh>`s to a parent `<Mesh>`

:::

## Background

Tres tries to automatically determine where to insert child tag into its parent. For example, in this code, Tres will:

* automatically insert the geometry into `parent.geometry`
* automatically insert the material into `parent.material`

```vue
<template>
<TresMesh name="parent">
<TresBoxGeometry />
<TresMeshNormalMaterial />
</TresMesh>
</template>
```

## Problem

Tres covers common cases, like above. But it doesn't cover every possible case.

When Tres doesn't automatically choose the proper insertion location for a child, one solution is to fall back to procedural code in `<script>`.

Here's how you might add multiple materials to a mesh using `<script>`:

```vue
<script setup lang="ts">
import { MeshBasicMaterial } from 'three'
import { onMounted, shallowRef } from 'vue'
const meshRef = shallowRef()
onMounted(() => {
meshRef.value.material = [
new MeshBasicMaterial({ color: 'red' }),
new MeshBasicMaterial({ color: 'orange' }),
new MeshBasicMaterial({ color: 'yellow' }),
new MeshBasicMaterial({ color: 'green' }),
new MeshBasicMaterial({ color: 'blue' }),
new MeshBasicMaterial({ color: 'purple' }),
]
})
</script>
<template>
<TresMesh ref="meshRef">
<TresBoxGeometry />
</TresMesh>
</template>
```

But this workaround means:

* your materials aren't managed by Tres
* your code is imperative, not declarative
* your code is non-reactive by default

## Solution

The `attach` prop lets you specify where an object will be added to the parent object using declarative code.

## Usage

Here's the example above, rewritten declaratively using `attach`:

```vue
<template>
<TresMesh>
<TresBoxGeometry />
<TresMeshBasicMaterial color="red" attach="material-0" />
<TresMeshBasicMaterial color="orange" attach="material-1" />
<TresMeshBasicMaterial color="yellow" attach="material-2" />
<TresMeshBasicMaterial color="green" attach="material-3" />
<TresMeshBasicMaterial color="blue" attach="material-4" />
<TresMeshBasicMaterial color="purple" attach="material-5" />
</TresMesh>
</template>
```

## "Pierced" `attach`

You can deeply attach a child to a parent by "piercing" – i.e., using a kebab-case string.

### Pseudocode

First, here are a few simple pseudocode examples. This will attach `bar` at `foo.ab.cd`:

```html
<foo>
<bar attach="ab-cd" />
</foo>
```

This will attach `bar` at `foo.ab.cd.ef`:

```html
<foo>
<bar attach="ab-cd-ef" />
</foo>
```

### Usage

As a concrete example, you can use "pierced" `attach` to add custom `BufferAttribute`s:

```vue
<script setup lang="ts">
import { TresCanvas } from '@tresjs/core'
const positions = new Float32Array([-1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0])
</script>
<template>
<TresCanvas clear-color="gray">
<TresMesh :scale="0.3333">
<TresBufferGeometry>
<TresBufferAttribute
attach="attributes-position"
:count="positions.length / 3"
:array="positions"
:itemSize="3"
/>
</TresBufferGeometry>
<TresMeshBasicMaterial color="red" />
</TresMesh>
</TresCanvas>
</template>
```

## Arrays

You can attach within arrays by using array indices in the `attach` string.

### Usage

For example, you can use array indices to attach `THREE` post-processing passes to the `THREE.EffectComposer.passes` array:

```vue
<script lang="ts" setup>
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer'
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass'
import { OutputPass } from 'three/examples/jsm/postprocessing/OutputPass'
import { UnrealBloomPass } from 'three-stdlib'
import { extend, useLoop, useTres } from '@tresjs/core'
import { shallowRef } from 'vue'
extend({ EffectComposer, OutputPass, UnrealBloomPass, RenderPass })
const { renderer, scene, camera, sizes } = useTres()
const composer = shallowRef<EffectComposer>()
useLoop().render(() => {
if (composer.value) {
composer.value!.render()
}
})
</script>
<template>
<TresEffectComposer
ref="composer"
:args="[renderer]"
:set-size="[sizes.width.value, sizes.height.value]"
>
<TresRenderPass
:args="[scene, camera]"
attach="passes-0"
/>
<TresUnrealBloomPass
:args="[undefined, 0.5, 0.1, 0]"
attach="passes-1"
/>
<TresOutputPass
attach="passes-2"
:set-size="[sizes.width.value, sizes.height.value]"
/>
</TresEffectComposer>
</template>
```
9 changes: 8 additions & 1 deletion playground/vue/.eslintrc-auto-import.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@
"watch": true,
"watchEffect": true,
"watchPostEffect": true,
"watchSyncEffect": true
"watchSyncEffect": true,
"DirectiveBinding": true,
"MaybeRef": true,
"MaybeRefOrGetter": true,
"onWatcherCleanup": true,
"useId": true,
"useModel": true,
"useTemplateRef": true
}
}
7 changes: 6 additions & 1 deletion playground/vue/auto-imports.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
// biome-ignore lint: disable
export {}
declare global {
const EffectScope: typeof import('vue')['EffectScope']
Expand Down Expand Up @@ -35,6 +36,7 @@ declare global {
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
const onUnmounted: typeof import('vue')['onUnmounted']
const onUpdated: typeof import('vue')['onUpdated']
const onWatcherCleanup: typeof import('vue')['onWatcherCleanup']
const provide: typeof import('vue')['provide']
const reactive: typeof import('vue')['reactive']
const readonly: typeof import('vue')['readonly']
Expand All @@ -52,7 +54,10 @@ declare global {
const useAttrs: typeof import('vue')['useAttrs']
const useCssModule: typeof import('vue')['useCssModule']
const useCssVars: typeof import('vue')['useCssVars']
const useId: typeof import('vue')['useId']
const useModel: typeof import('vue')['useModel']
const useSlots: typeof import('vue')['useSlots']
const useTemplateRef: typeof import('vue')['useTemplateRef']
const watch: typeof import('vue')['watch']
const watchEffect: typeof import('vue')['watchEffect']
const watchPostEffect: typeof import('vue')['watchPostEffect']
Expand All @@ -61,6 +66,6 @@ declare global {
// for type re-export
declare global {
// @ts-ignore
export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue'
export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
import('vue')
}
47 changes: 47 additions & 0 deletions playground/vue/src/pages/advanced/attachBufferGeometry/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<script setup lang="ts">
import { TresCanvas } from '@tresjs/core'
const previewDataUri = 'data:image/png;base64,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'
const positions = new Float32Array([
-1.0,
-1.0,
1.0, // v0
1.0,
-1.0,
1.0, // v1
1.0,
1.0,
1.0, // v2
1.0,
1.0,
1.0, // v3
-1.0,
1.0,
1.0, // v4
-1.0,
-1.0,
1.0, // v5
])
</script>

<template>
<TresCanvas clear-color="gray">
<TresMesh :scale="0.3333">
<TresBufferGeometry>
<TresBufferAttribute attach="attributes-position" :count="positions.length / 3" :array="positions" :itemSize="3" />
</TresBufferGeometry>
<TresMeshBasicMaterial color="red" />
</TresMesh>
</TresCanvas>

<OverlayInfo>
<h1><code>attach</code>: BufferGeometry</h1>
<h2>Setup</h2>
<p>
In this scene, there is a Mesh with a BufferGeometry, created with JSX. The BufferGeometry has a JSX BufferAttribute, attached to the BufferGeometry's <code>attributes.position</code> using <code>attach</code>.
</p>
<h2>Preview</h2>
<img :src="previewDataUri" />
</OverlayInfo>
</template>
Loading

0 comments on commit fbcbdc3

Please sign in to comment.