diff --git a/docs/.vitepress/theme/components/SmokeDemo.vue b/docs/.vitepress/theme/components/SmokeDemo.vue index a9180fea..10e580a5 100644 --- a/docs/.vitepress/theme/components/SmokeDemo.vue +++ b/docs/.vitepress/theme/components/SmokeDemo.vue @@ -1,7 +1,71 @@ diff --git a/docs/guide/staging/smoke.md b/docs/guide/staging/smoke.md index a0a6d225..e7d33323 100644 --- a/docs/guide/staging/smoke.md +++ b/docs/guide/staging/smoke.md @@ -26,32 +26,20 @@ You can use `` component without passing any props, but still if you wa ``` -Notice that you can pass a texture in combination with props, to personalize your effect - -```vue - -``` ## Props + + + +
NameTypeDescriptionDefaultRequired
colorTresColorThe color of the smoke.
'#ffffff'No
opacitynumberThe strength of the opacity.
0.5No
speednumberThe rotation speed of the smoke.
-
0.4No
widthnumberThe base width.
-
10No
depthnumberThe base depth.
+
0.4No
depthnumberThe base depth.
1.5No
segmentsnumberThe number of smoke to render.
-
20No
texturestringThe texture of the smoke.
+
20No
SpreadXnumberSpread factor on the X axis.
+
20No
SpreadYnumberSpread factor on the Y axis.
+
20No
Scalenumbercontrols the overall size of the smoke segments
+
1No
texturestringThe texture of the smoke.
default component textureNo
depthTestbooleanThe depthTest.
trueNo
diff --git a/playground/vue/src/pages/staging/SmokeDemo.vue b/playground/vue/src/pages/staging/SmokeDemo.vue index 1d2379fc..90e0f9b6 100644 --- a/playground/vue/src/pages/staging/SmokeDemo.vue +++ b/playground/vue/src/pages/staging/SmokeDemo.vue @@ -2,6 +2,70 @@ import { Box, OrbitControls, Smoke } from '@tresjs/cientos' import { TresCanvas } from '@tresjs/core' import { NoToneMapping, SRGBColorSpace } from 'three' +import { TresLeches, useControls } from '@tresjs/leches' +import '@tresjs/leches/styles' + +const { segments, opacity, speed, depth, color, depthTest, spreadY, spreadX, scale } = useControls({ + segments: { + label: 'Segments', + value: 5, + min: 1, + max: 20, + step: 1, + }, + opacity: { + label: 'Opacity', + value: 0.5, + min: 0, + max: 1, + step: 0.1, + }, + speed: { + label: 'Speed', + value: 0.4, + min: 0, + max: 1, + step: 0.1, + }, + depth: { + label: 'Depth', + value: 0.3, + min: 0, + max: 1, + step: 0.1, + }, + color: { + type: 'color', + label: 'Color', + value: '#f7f7f7', + }, + depthTest: { + type: 'boolean', + label: 'Depth Test', + value: false, + }, + spreadY: { + label: 'Spread Y', + value: 0.1, + min: 0, + max: 4, + step: 0.1, + }, + spreadX: { + label: 'Spread X', + value: 0.5, + min: 0, + max: 4, + step: 0.1, + }, + scale: { + label: 'Scale', + value: 1, + min: 0.1, + max: 4, + step: 0.1, + }, +}) const gl = { clearColor: '#333', @@ -12,46 +76,28 @@ const gl = { diff --git a/src/core/staging/Smoke.vue b/src/core/staging/Smoke.vue index b3bd88eb..ec87fe3d 100644 --- a/src/core/staging/Smoke.vue +++ b/src/core/staging/Smoke.vue @@ -19,7 +19,6 @@ export interface SmokeProps { * @default 0.5 * @type {number} * @memberof SmokeProps - * @see https://threejs.org/docs/#api/en/materials/MeshStandardMaterial */ opacity?: number /** @@ -27,23 +26,13 @@ export interface SmokeProps { * @default 0.4 * @type {number} * @memberof SmokeProps - * @see https://threejs.org/docs/#api/en/materials/MeshStandardMaterial */ speed?: number - /** - * The base width. - * @default 4 - * @type {number} - * @memberof SmokeProps - * @see https://threejs.org/docs/#api/en/materials/MeshBasicMaterial - */ - width?: number /** * The base depth. * @default 10 * @type {number} * @memberof SmokeProps - * @see https://threejs.org/docs/#api/en/geometries/PlaneGeometry */ depth?: number /** @@ -51,7 +40,6 @@ export interface SmokeProps { * @default 10 * @type {number} * @memberof SmokeProps - * @see https://threejs.org/docs/#api/en/materials/MeshStandardMaterial */ segments?: number /** @@ -59,7 +47,6 @@ export interface SmokeProps { * @default 'https://raw.githubusercontent.com/Tresjs/assets/main/textures/clouds/defaultCloud.png' * @type {string} * @memberof SmokeProps - * @see https://threejs.org/docs/#api/en/materials/MeshStandardMaterial */ texture?: string /** @@ -67,23 +54,48 @@ export interface SmokeProps { * @default true * @type {boolean} * @memberof SmokeProps - * @see https://threejs.org/docs/#api/en/materials/MeshStandardMaterial */ depthTest?: boolean + /** + * Spread on the Y axis. + * @default 0.1 + * @type {number} + * @memberof SmokeProps + */ + spreadY?: number + /** + * Spread on the X axis. + * @default 0.5 + * @type {number} + * @memberof SmokeProps + */ + spreadX?: number + /** + * Scale. + * @default 1 + * @type {number} + * @memberof SmokeProps + */ + scale?: number } const props = withDefaults(defineProps(), { opacity: 0.5, speed: 0.4, - width: 10, - depth: 1.5, - segments: 20, - texture: 'https://raw.githubusercontent.com/Tresjs/assets/main/textures/clouds/defaultCloud.png', - color: '#ffffff', - depthTest: true, + depth: 0.3, + segments: 10, + texture: + 'https://raw.githubusercontent.com/Tresjs/assets/main/textures/clouds/defaultCloud.png', + color: '#f7f7f7', + depthTest: false, + spreadY: 0.1, + spreadX: 0.5, + scale: 1, }) -const { width, depth, segments, texture, color, depthTest, opacity, speed } = toRefs(props) +const { depth, segments, texture, color, depthTest, opacity, speed, spreadY, spreadX, scale } = toRefs( + props, +) const smokeRef = shallowRef() const groupRef = shallowRef() @@ -92,15 +104,13 @@ defineExpose({ instance: smokeRef, }) -const smoke = [...[segments]].map((_, index) => ({ - x: width.value / 2 - Math.random() * width.value, - y: width.value / 2 - Math.random() * width.value, - scale: 0.4 + Math.sin(((index + 1) / segments.value) * Math.PI) * ((0.2 + Math.random()) * 10), - density: Math.max(0.2, Math.random()), - rotation: Math.max(0.002, 0.005 * Math.random()) * speed.value, -})) - -const calculateOpacity = (scale: number, density: number): number => (scale / 6) * density * opacity.value +const smoke = computed(() => + Array.from({ length: segments.value }, (_, index) => ({ + x: (Math.random() - 0.5) * spreadX.value, + y: (Math.random() - 0.5) * spreadY.value, + scale: Math.sin((index + 1) / segments.value) * scale.value, + })), +) const { state: map } = useTexture(texture.value) @@ -111,8 +121,8 @@ const { onBeforeRender } = useLoop() onBeforeRender(() => { if (smokeRef.value && camera.activeCamera.value && groupRef.value) { - groupRef.value?.children.forEach((child: Object3D, index: number) => { - child.rotation.z += smoke[index].rotation + groupRef.value?.children.forEach((child: Object3D) => { + child.rotation.z += Math.max(0.002, 0.005 * Math.random()) * speed.value }) smokeRef.value.lookAt(camera.activeCamera.value?.position) // TODO: comment this until invalidate is back in the loop callback on v5 @@ -122,23 +132,15 @@ onBeforeRender(() => {