Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 86 additions & 31 deletions apps/playground/src/pages/cientos/staging/SmokeDemo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,79 @@
import { Box, OrbitControls, Smoke } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
import { NoToneMapping, SRGBColorSpace } from 'three'
import { TresLeches, useControls } from '@tresjs/leches'

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',
Expand All @@ -12,46 +85,28 @@ const gl = {
</script>

<template>
<TresCanvas
v-bind="gl"
>
<TresLeches />
<TresCanvas v-bind="gl">
<TresPerspectiveCamera :position="[0, 2, 5]" />
<Suspense>
<Smoke
:position="[-4, -2, 0]"
:segments="8"
/>
</Suspense>
<Suspense>
<Smoke
:position="[-4, 2, 0]"
:segments="8"
/>
</Suspense>
<Suspense>
<Smoke :segments="8" />
</Suspense>
<Suspense>
<Smoke
:position="[4, -2, 0]"
:segments="8"
/>
</Suspense>
<Suspense>
<Smoke
:position="[4, 2, 0]"
:segments="8"
:segments="segments"
:opacity="opacity"
:speed="speed"
:depth="depth"
:color="color"
:depth-test="depthTest"
:spreadY="spreadY"
:spreadX="spreadX"
:scale="scale"
/>
</Suspense>
<Box :args="[2, 2]">
<TresMeshToonMaterial color="#82DBC5" />
<TresMeshToonMaterial color="#82DBC5" wireframe />
</Box>
<TresGridHelper :args="[10, 10]" />
<TresAmbientLight :intensity="1" />
<TresDirectionalLight
:intensity="1"
:position="[2, 2, 2]"
/>
<TresDirectionalLight :intensity="1" :position="[2, 2, 2]" />
<OrbitControls />
</TresCanvas>
</template>
93 changes: 48 additions & 45 deletions packages/cientos/src/core/staging/Smoke.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,22 @@ export interface SmokeProps {
* @default 0xffffff
* @type {TresColor}
* @memberof SmokeProps
* @see https://threejs.org/docs/#api/en/materials/MeshStandardMaterial
*/
color?: TresColor
/**
* The strength of the opacity.
* @default 0.5
* @type {number}
* @memberof SmokeProps
* @see https://threejs.org/docs/#api/en/materials/MeshStandardMaterial
*/
opacity?: number
/**
* The rotation speed of the smoke.
* @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
Expand All @@ -51,39 +40,62 @@ export interface SmokeProps {
* @default 10
* @type {number}
* @memberof SmokeProps
* @see https://threejs.org/docs/#api/en/materials/MeshStandardMaterial
*/
segments?: number
/**
* The texture of the smoke.
* @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
/**
* The depthTest.
* @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<SmokeProps>(), {
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()
Expand All @@ -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)

Expand All @@ -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
Expand All @@ -122,30 +132,23 @@ onBeforeRender(() => {
</script>

<template>
<TresGroup
ref="smokeRef"
>
<TresGroup
ref="groupRef"
:position="[0, 0, (segments / 2) * depth]"
>
<TresGroup ref="smokeRef" :scale="scale">
<TresGroup ref="groupRef" :position="[0, 0, (segments / 2) * depth]">
<TresMesh
v-for="({ scale, x, y, density }, index) in smoke"
v-for="({ x, y, scale: smokeScale }, index) in smoke"
:key="`${index}`"
:position="[x, y, -index * depth]"
:scale="smokeScale"
>
<TresPlaneGeometry
:scale="[scale, scale, scale]"
:rotation="[0, 0, 0]"
/>
<TresPlaneGeometry />
<TresMeshStandardMaterial
:map="map"
:depth-test="depthTest"
:color-space="colorSpace"
:color="color"
:depth-write="false"
transparent
:opacity="calculateOpacity(scale, density)"
:opacity="opacity"
/>
</TresMesh>
</TresGroup>
Expand Down
Loading