Skip to content

Commit ebb8350

Browse files
fix: Smoke component
- Reactivity - Default values - Correct random an unpredictable behavior
1 parent 8958ecc commit ebb8350

File tree

3 files changed

+78
-73
lines changed

3 files changed

+78
-73
lines changed

docs/guide/staging/smoke.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ Notice that you can pass a texture in combination with props, to personalize yo
4949
<table><thead><tr class="row-header"><th class="col-name">Name</th><th class="col-type">Type</th><th class="col-description">Description</th><th class="col-default">Default</th><th class="col-required">Required</th></tr></thead><tbody><tr class="row-color"><td class="col-name"><strong><nobr>color</nobr></strong></td><td class="col-type"><code>TresColor</code></td><td class="col-description">The color of the smoke.<br>
5050
</td><td class="col-default"><code>'#ffffff'</code></td><td class="col-required">No</td></tr><tr class="row-opacity"><td class="col-name"><strong><nobr>opacity</nobr></strong></td><td class="col-type"><code>number</code></td><td class="col-description">The strength of the opacity.<br>
5151
</td><td class="col-default"><code>0.5</code></td><td class="col-required">No</td></tr><tr class="row-speed"><td class="col-name"><strong><nobr>speed</nobr></strong></td><td class="col-type"><code>number</code></td><td class="col-description">The rotation speed of the smoke.<br>
52-
</td><td class="col-default"><code>0.4</code></td><td class="col-required">No</td></tr><tr class="row-width"><td class="col-name"><strong><nobr>width</nobr></strong></td><td class="col-type"><code>number</code></td><td class="col-description">The base width.<br>
53-
</td><td class="col-default"><code>10</code></td><td class="col-required">No</td></tr><tr class="row-depth"><td class="col-name"><strong><nobr>depth</nobr></strong></td><td class="col-type"><code>number</code></td><td class="col-description">The base depth.<br>
52+
</td><td class="col-default"><code>0.4</code></td><td class="col-required">No</td></tr><tr class="row-depth"><td class="col-name"><strong><nobr>depth</nobr></strong></td><td class="col-type"><code>number</code></td><td class="col-description">The base depth.<br>
5453
</td><td class="col-default"><code>1.5</code></td><td class="col-required">No</td></tr><tr class="row-segments"><td class="col-name"><strong><nobr>segments</nobr></strong></td><td class="col-type"><code>number</code></td><td class="col-description">The number of smoke to render.<br>
5554
</td><td class="col-default"><code>20</code></td><td class="col-required">No</td></tr><tr class="row-texture"><td class="col-name"><strong><nobr>texture</nobr></strong></td><td class="col-type"><code>string</code></td><td class="col-description">The texture of the smoke.<br>
5655
</td><td class="col-default">default component texture</td><td class="col-required">No</td></tr><tr class="row-depth-test"><td class="col-name"><strong><nobr>depthTest</nobr></strong></td><td class="col-type"><code>boolean</code></td><td class="col-description">The depthTest.<br>

playground/vue/src/pages/staging/SmokeDemo.vue

Lines changed: 53 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,49 @@
22
import { Box, OrbitControls, Smoke } from '@tresjs/cientos'
33
import { TresCanvas } from '@tresjs/core'
44
import { NoToneMapping, SRGBColorSpace } from 'three'
5+
import { TresLeches, useControls } from '@tresjs/leches'
6+
import '@tresjs/leches/styles'
7+
8+
const { segments, opacity, speed, depth, color, depthTest } = useControls({
9+
segments: {
10+
label: 'Segments',
11+
value: 5,
12+
min: 1,
13+
max: 20,
14+
step: 1,
15+
},
16+
opacity: {
17+
label: 'Opacity',
18+
value: 0.5,
19+
min: 0,
20+
max: 1,
21+
step: 0.1,
22+
},
23+
speed: {
24+
label: 'Speed',
25+
value: 0.4,
26+
min: 0,
27+
max: 1,
28+
step: 0.1,
29+
},
30+
depth: {
31+
label: 'Depth',
32+
value: 0.3,
33+
min: 0,
34+
max: 1,
35+
step: 0.1,
36+
},
37+
color: {
38+
type: 'color',
39+
label: 'Color',
40+
value: '#f7f7f7',
41+
},
42+
depthTest: {
43+
type: 'boolean',
44+
label: 'Depth Test',
45+
value: false,
46+
},
47+
})
548
649
const gl = {
750
clearColor: '#333',
@@ -12,46 +55,25 @@ const gl = {
1255
</script>
1356

1457
<template>
15-
<TresCanvas
16-
v-bind="gl"
17-
>
58+
<TresLeches />
59+
<TresCanvas v-bind="gl">
1860
<TresPerspectiveCamera :position="[0, 2, 5]" />
1961
<Suspense>
2062
<Smoke
21-
:position="[-4, -2, 0]"
22-
:segments="8"
23-
/>
24-
</Suspense>
25-
<Suspense>
26-
<Smoke
27-
:position="[-4, 2, 0]"
28-
:segments="8"
29-
/>
30-
</Suspense>
31-
<Suspense>
32-
<Smoke :segments="8" />
33-
</Suspense>
34-
<Suspense>
35-
<Smoke
36-
:position="[4, -2, 0]"
37-
:segments="8"
38-
/>
39-
</Suspense>
40-
<Suspense>
41-
<Smoke
42-
:position="[4, 2, 0]"
43-
:segments="8"
63+
:segments="segments.value"
64+
:opacity="opacity.value"
65+
:speed="speed.value"
66+
:depth="depth.value"
67+
:color="color.value"
68+
:depth-test="depthTest.value"
4469
/>
4570
</Suspense>
4671
<Box :args="[2, 2]">
47-
<TresMeshToonMaterial color="#82DBC5" />
72+
<TresMeshToonMaterial color="#82DBC5" wireframe />
4873
</Box>
4974
<TresGridHelper :args="[10, 10]" />
5075
<TresAmbientLight :intensity="1" />
51-
<TresDirectionalLight
52-
:intensity="1"
53-
:position="[2, 2, 2]"
54-
/>
76+
<TresDirectionalLight :intensity="1" :position="[2, 2, 2]" />
5577
<OrbitControls />
5678
</TresCanvas>
5779
</template>

src/core/staging/Smoke.vue

Lines changed: 24 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,6 @@ export interface SmokeProps {
2929
* @see https://threejs.org/docs/#api/en/materials/MeshStandardMaterial
3030
*/
3131
speed?: number
32-
/**
33-
* The base width.
34-
* @default 4
35-
* @type {number}
36-
* @memberof SmokeProps
37-
* @see https://threejs.org/docs/#api/en/materials/MeshBasicMaterial
38-
*/
39-
width?: number
4032
/**
4133
* The base depth.
4234
* @default 10
@@ -74,15 +66,17 @@ export interface SmokeProps {
7466
const props = withDefaults(defineProps<SmokeProps>(), {
7567
opacity: 0.5,
7668
speed: 0.4,
77-
width: 10,
78-
depth: 1.5,
79-
segments: 20,
80-
texture: 'https://raw.githubusercontent.com/Tresjs/assets/main/textures/clouds/defaultCloud.png',
81-
color: '#ffffff',
82-
depthTest: true,
69+
depth: 0.3,
70+
segments: 10,
71+
texture:
72+
'https://raw.githubusercontent.com/Tresjs/assets/main/textures/clouds/defaultCloud.png',
73+
color: '#f7f7f7',
74+
depthTest: false,
8375
})
8476
85-
const { width, depth, segments, texture, color, depthTest, opacity, speed } = toRefs(props)
77+
const { depth, segments, texture, color, depthTest, opacity, speed } = toRefs(
78+
props,
79+
)
8680
8781
const smokeRef = shallowRef()
8882
const groupRef = shallowRef()
@@ -91,27 +85,26 @@ defineExpose({
9185
instance: smokeRef,
9286
})
9387
94-
const smoke = [...[segments]].map((_, index) => ({
95-
x: width.value / 2 - Math.random() * width.value,
96-
y: width.value / 2 - Math.random() * width.value,
97-
scale: 0.4 + Math.sin(((index + 1) / segments.value) * Math.PI) * ((0.2 + Math.random()) * 10),
98-
density: Math.max(0.2, Math.random()),
99-
rotation: Math.max(0.002, 0.005 * Math.random()) * speed.value,
100-
}))
101-
102-
const calculateOpacity = (scale: number, density: number): number => (scale / 6) * density * opacity.value
88+
const smoke = computed(() =>
89+
Array.from({ length: segments.value }, (_, index) => ({
90+
x: (Math.random() - 0.5) * 0.5,
91+
y: (Math.random() - 0.5) * 0.1,
92+
scale: Math.sin((index + 1) / segments.value),
93+
})),
94+
)
10395
10496
const { map } = (await useTexture({ map: texture.value })) as { map: Texture }
10597
10698
const { renderer, camera } = useTresContext()
99+
107100
const colorSpace = computed(() => renderer.value?.outputColorSpace)
108101
109102
const { onBeforeRender } = useLoop()
110103
111104
onBeforeRender(({ invalidate }) => {
112105
if (smokeRef.value && camera.value && groupRef.value) {
113-
groupRef.value?.children.forEach((child: Object3D, index: number) => {
114-
child.rotation.z += smoke[index].rotation
106+
groupRef.value?.children.forEach((child: Object3D) => {
107+
child.rotation.z += Math.max(0.002, 0.005 * Math.random()) * speed.value
115108
})
116109
smokeRef.value.lookAt(camera.value?.position)
117110
invalidate()
@@ -120,31 +113,22 @@ onBeforeRender(({ invalidate }) => {
120113
</script>
121114

122115
<template>
123-
<TresGroup
124-
ref="smokeRef"
125-
v-bind="$attrs"
126-
>
127-
<TresGroup
128-
ref="groupRef"
129-
:position="[0, 0, (segments / 2) * depth]"
130-
>
116+
<TresGroup ref="smokeRef">
117+
<TresGroup ref="groupRef" :position="[0, 0, (segments / 2) * depth]">
131118
<TresMesh
132-
v-for="({ scale, x, y, density }, index) in smoke"
119+
v-for="({ x, y }, index) in smoke"
133120
:key="`${index}`"
134121
:position="[x, y, -index * depth]"
135122
>
136-
<TresPlaneGeometry
137-
:scale="[scale, scale, scale]"
138-
:rotation="[0, 0, 0]"
139-
/>
123+
<TresPlaneGeometry />
140124
<TresMeshStandardMaterial
141125
:map="map"
142126
:depth-test="depthTest"
143127
:color-space="colorSpace"
144128
:color="color"
145129
:depth-write="false"
146130
transparent
147-
:opacity="calculateOpacity(scale, density)"
131+
:opacity="opacity"
148132
/>
149133
</TresMesh>
150134
</TresGroup>

0 commit comments

Comments
 (0)