Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: pmndrs/drei
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v9.86.1
Choose a base ref
...
head repository: pmndrs/drei
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v9.86.2
Choose a head ref
  • 1 commit
  • 2 files changed
  • 1 contributor

Commits on Sep 29, 2023

  1. fix: custom cloud distribution

    drcmda committed Sep 29, 2023
    1
    Copy the full SHA
    b66ebaa View commit details
Showing with 39 additions and 12 deletions.
  1. +9 −4 README.md
  2. +30 −8 src/core/Cloud.tsx
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -4497,19 +4497,24 @@ type CloudProps = JSX.IntrinsicElements['group'] & {
segments?: number
/** The box3 bounds of the cloud, default: [5, 1, 1] */
bounds?: ReactThreeFiber.Vector3
/** How to arrange segments inside the bounds, default: inside (cloud are smaller are the edges) */
concentrate?: 'inside' | 'outside'
/** How to arrange segment volume inside the bounds, default: inside (cloud are smaller at the edges) */
concentrate?: 'random' | 'inside' | 'outside'
/** The general scale of the segments */
scale?: ReactThreeFiber.Vector3
/** The volume/thickness of the segments, default: 6 */
volume?: number
/** The smallest volume when distributing clouds, default: 0.25 */
smallestVolume?: number
/** An optional function that allows you to distribute points and volumes (overriding all settings), default: null
* Both point and volume are factors, point x/y/z can be between -1 and 1, volume between 0 and 1 */
distribute?: (cloud: CloudState, index: number) => { point: Vector3; volume?: number }
/** Growth factor for animated clouds (speed > 0), default: 4 */
growth?: number
/** Animation factor, default: 0.1 */
/** Animation factor, default: 0 */
speed?: number
/** Camera distance until the segments will fade, default: 10 */
fade?: number
/** Opacity, default: 0.8 */
/** Opacity, default: 1 */
opacity?: number
/** Color, default: white */
color?: ReactThreeFiber.Color
38 changes: 30 additions & 8 deletions src/core/Cloud.tsx
Original file line number Diff line number Diff line change
@@ -65,12 +65,17 @@ type CloudProps = JSX.IntrinsicElements['group'] & {
segments?: number
/** The box3 bounds of the cloud, default: [5, 1, 1] */
bounds?: ReactThreeFiber.Vector3
/** How to arrange segments inside the bounds, default: inside (cloud are smaller are the edges) */
concentrate?: 'inside' | 'outside'
/** How to arrange segment volume inside the bounds, default: inside (cloud are smaller at the edges) */
concentrate?: 'random' | 'inside' | 'outside'
/** The general scale of the segments */
scale?: ReactThreeFiber.Vector3
/** The volume/thickness of the segments, default: 6 */
volume?: number
/** The smallest volume when distributing clouds, default: 0.25 */
smallestVolume?: number
/** An optional function that allows you to distribute points and volumes (overriding all settings), default: null
* Both point and volume are factors, point x/y/z can be between -1 and 1, volume between 0 and 1 */
distribute?: (cloud: CloudState, index: number) => { point: Vector3; volume?: number }
/** Growth factor for animated clouds (speed > 0), default: 4 */
growth?: number
/** Animation factor, default: 0 */
@@ -206,6 +211,8 @@ export const CloudInstance = React.forwardRef<Group, CloudProps>(
color = '#ffffff',
fade = 10,
volume = 6,
smallestVolume = 0.25,
distribute = null,
growth = 4,
concentrate = 'inside',
seed = Math.random(),
@@ -242,6 +249,7 @@ export const CloudInstance = React.forwardRef<Group, CloudProps>(
React.useLayoutEffect(() => {
clouds.forEach((cloud, index) => {
applyProps(cloud as any, {
volume,
color,
speed,
growth,
@@ -252,19 +260,33 @@ export const CloudInstance = React.forwardRef<Group, CloudProps>(
rotationFactor: Math.max(0.2, 0.5 * random()) * speed,
})
// Only distribute randomly if there are multiple segments
if (segments > 1)
cloud.position
.copy(cloud.bounds)
.multiply({ x: random() * 2 - 1, y: random() * 2 - 1, z: random() * 2 - 1 } as Vector3)

const distributed = distribute?.(cloud, index)

if (distributed || segments > 1)
cloud.position.copy(cloud.bounds).multiply(
distributed?.point ??
({
x: random() * 2 - 1,
y: random() * 2 - 1,
z: random() * 2 - 1,
} as Vector3)
)
const xDiff = Math.abs(cloud.position.x)
const yDiff = Math.abs(cloud.position.y)
const zDiff = Math.abs(cloud.position.z)
const max = Math.max(xDiff, yDiff, zDiff)
cloud.length = concentrate === 'inside' ? 1 : -1
cloud.length = 1
if (xDiff === max) cloud.length -= xDiff / cloud.bounds.x
if (yDiff === max) cloud.length -= yDiff / cloud.bounds.y
if (zDiff === max) cloud.length -= zDiff / cloud.bounds.z
cloud.volume = Math.max(0.25, cloud.length) * volume
cloud.volume =
(distributed?.volume !== undefined
? distributed.volume
: Math.max(
Math.max(0, smallestVolume),
concentrate === 'random' ? random() : concentrate === 'inside' ? cloud.length : 1 - cloud.length
)) * volume
})
}, [concentrate, bounds, fade, color, opacity, growth, volume, seed, segments, speed])