Skip to content

Commit

Permalink
feat(Lensflare): add color, distance, size, texture to component
Browse files Browse the repository at this point in the history
  • Loading branch information
andretchen0 committed Sep 10, 2023
1 parent 59c4b7e commit f90988e
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 133 deletions.
88 changes: 41 additions & 47 deletions playground/src/pages/LensflareDemo.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { shallowRef, watch } from 'vue'
import type { TresColor } from '@tresjs/core'
import { TresCanvas, useRenderLoop } from '@tresjs/core'
import { Levioso, Lensflare, Dodecahedron, OrbitControls } from '@tresjs/cientos'
import { Color, MeshPhongMaterial } from 'three'
Expand All @@ -12,41 +13,35 @@ const gl = {
alpha: false,
}
function easeInOutQuint(x: number): number {
return x < 0.5 ? 16 * x * x * x * x * x : 1 - (-2 * x + 2) ** 5 / 2
}
const colors = ['white', 'yellow', 'red', 'orange', 'purple']
const randomColor = () => colors[Math.trunc(Math.random() * colors.length)]
const color = randomColor()
const randomColor = () => new Color(colors[Math.trunc(Math.random() * colors.length)])
const lightRef = shallowRef()
const colorRef = shallowRef(randomColor() as TresColor)
const seedPropsRef = shallowRef()
const elementsRef = shallowRef([{ color, size: 1 }])
elementsRef.value = new Array(11).fill(0).map((_, i) => ({ size: Math.min(256 / (1 + i * i)), color }))
const speedRef = shallowRef(1)
const { onLoop } = useRenderLoop()
onLoop(() => {
if (!lightRef.value) return
if (Math.random() > 0.99) {
lightRef.value.color = new Color(randomColor())
elementsRef.value = getFlareProps()
let cooldown = 5
onLoop(({ delta }) => {
cooldown -= delta
while (cooldown < 0) {
colorRef.value = randomColor()
cooldown += 5
}
})
function getFlareProps() {
const NUM_ELEMENTS = 15
return new Array(NUM_ELEMENTS).fill(0).map(
(_, i) => ({
size: 216 * (1 - easeInOutQuint(i / NUM_ELEMENTS)),
distance: i < 5 ? 0 : easeInOutQuint(i / NUM_ELEMENTS),
color: lightRef.value?.color ?? 'white',
}))
}
elementsRef.value = getFlareProps()
const TEXTURE_PATH
= 'https://raw.githubusercontent.com/andretchen0/tresjs_assets/'
+ 'b1bc3780de73a9328a530767c9a7f4cbab060396/textures/lensflare/'
const circle = `${TEXTURE_PATH}circle.png`
const circleBlur = `${TEXTURE_PATH}cirlceBlur.png`
const circleRainbow = `${TEXTURE_PATH}circleRainbow.png`
const line = `${TEXTURE_PATH}line.png`
const poly6 = `${TEXTURE_PATH}poly6.png`
const polyStroke6 = `${TEXTURE_PATH}polyStroke6.png`
const rays6 = `${TEXTURE_PATH}rays6.png`
const ring = `${TEXTURE_PATH}ring.png`
const float = (lo: number, hi: number) => Math.random() * (hi - lo) + lo
const floatSpread = (range: number) => Math.random() * range - range * 0.5
Expand All @@ -64,23 +59,11 @@ const rockMaterial = new MeshPhongMaterial({ color: 0x123141, specular: 0xffffff
const [seedRef, scaleRef] = useControls(
{
seed: { value: 847 },
seed: { value: 847, min: 0, max: 2 ** 31, step: 1 },
scale: { value: 1, min: 0, max: 2, step: 0.01 },
})
{
const TEXTURE_PATH
= 'https://raw.githubusercontent.com/andretchen0/tresjs_assets/'
+ 'b1bc3780de73a9328a530767c9a7f4cbab060396/textures/lensflare/'
const circle = `${TEXTURE_PATH}circle.png`
const circleBlur = `${TEXTURE_PATH}cirlceBlur.png`
const circleRainbow = `${TEXTURE_PATH}circleRainbow.png`
const line = `${TEXTURE_PATH}line.png`
const poly6 = `${TEXTURE_PATH}poly6.png`
const polyStroke6 = `${TEXTURE_PATH}polyStroke6.png`
const rays6 = `${TEXTURE_PATH}rays6.png`
const ring = `${TEXTURE_PATH}ring.png`
const [oversizeSize, oversizeSizeRand, oversizeNumElements,
oversizeNumElementsRand, oversizeColorA, oversizeColorB, oversizeColorC, oversizeSeed] = useControls(
'Oversize',
Expand Down Expand Up @@ -237,7 +220,7 @@ const [seedRef, scaleRef] = useControls(
<template>
<TresLeches class="important-fixed" />
<TresCanvas v-bind="gl">
<Levioso :speed="1">
<Levioso :speed="speedRef">
<TresPerspectiveCamera :position="[11, 11, 100]" />
</Levioso>
<OrbitControls />
Expand All @@ -247,29 +230,40 @@ const [seedRef, scaleRef] = useControls(
:rotation-factor="10"
>
<TresPointLight
ref="lightRef"
:color="color"
:color="colorRef"
:intensity="1000"
:position="[10, 0, 0]"
>
<Lensflare
:seed="seedRef.value.value"
:scale="0.5"
:elements="elementsRef"
:color="colorRef"
:texture="circleBlur"
:distance="1"
:size="216"
:scale="0.75"
:elements="[
{ texture: ring, size: 512, distance: 0 },
{ texture: rays6, distance: 0, color: 'white' },
{ distance: 0 },
{ distance: 0.2 },
{ distance: 0.5 },
{},
]"
/>
</TresPointLight>
</Levioso>

<TresPointLight
:color="new Color(1, 1, 1)"
color="white"
:intensity="2000"
:position="[10, 5, 0]"
>
<Lensflare
:scale="scaleRef.value.value"
:seed="seedRef.value.value"
:seed-props="seedPropsRef"
:scale="scaleRef.value.value"
/>
</TresPointLight>

<Dodecahedron
v-for="{ key, position, rotation, scale } in rocks"
:key="key"
Expand Down
44 changes: 29 additions & 15 deletions src/core/abstractions/Lensflare/component.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import { TextureLoader } from 'three'
import { watch, shallowRef, onMounted, onUnmounted } from 'vue'
import { normalizeColor } from '@tresjs/core'
import type { LensflareElementProps, SeedProps } from '.'
import { partialLensflarePropsArrayToLensflarePropsArray as fillInProps } from '.'
import { partialLensflarePropsArrayToLensflarePropsArray as fillInProps,
partialLensflareElementPropsFromComponentProps as userDefaultLensflarePropsFromProps } from '.'
const props = withDefaults(
defineProps<{
defineProps<Partial<LensflareElementProps> & {
elements?: Partial<LensflareElementProps>[]
scale?: number
seed?: number
Expand All @@ -23,7 +24,9 @@ const props = withDefaults(
)
const lensflareRef = shallowRef<Lensflare>()
const lensflareElementPropsArray = shallowRef<LensflareElementProps[]>([])
const lensflareElementPropsArrayRef = shallowRef<LensflareElementProps[]>([])
const userDefaultLensflareElementPropsRef
= shallowRef<Partial<LensflareElementProps>>(userDefaultLensflarePropsFromProps(props))
defineExpose({
value: lensflareRef,
Expand All @@ -38,9 +41,9 @@ const threeElements: LensflareElement[] = []
const dispose = () => {
while (threeElements.length) threeElements.pop()
lensflareRef.value?.children.forEach((c: any) => {
lensflareRef.value?.children.forEach((c: any) => {
if ('dispose' in c) {
c.dispose()
c.dispose()
}
})
lensflareRef.value?.remove(...lensflareRef.value.children)
Expand All @@ -58,14 +61,14 @@ const lensflareElementPropsToLensflareElement = (p: LensflareElementProps) => {
}
const updateThreeElements = () => {
while (lensflareElementPropsArray.value.length > threeElements.length) {
const element = lensflareElementPropsToLensflareElement(lensflareElementPropsArray.value[threeElements.length])
const copy = { ... element }
while (lensflareElementPropsArrayRef.value.length > threeElements.length) {
const element = lensflareElementPropsToLensflareElement(lensflareElementPropsArrayRef.value[threeElements.length])
const copy = { ...element }
threeElements.push(copy)
threeLensflare.addElement(copy)
}
lensflareElementPropsArray.value.forEach((elementProps, i) => {
lensflareElementPropsArrayRef.value.forEach((elementProps, i) => {
const threeElement = threeElements[i]
const { texture, size, distance, color } = elementProps
if (typeof texture === 'string') {
Expand Down Expand Up @@ -95,11 +98,11 @@ const scaleThreeElements = () => {
// NOTE: We can't remove already added elements from the THREE lensflare.
// So if we've previously added more elements than are currently needed,
// make those elements too small to display.
for (let i = lensflareElementPropsArray.value.length - 1; i < threeElements.length; i++) {
for (let i = lensflareElementPropsArrayRef.value.length - 1; i < threeElements.length; i++) {
threeElements[i].size = 0
}
lensflareElementPropsArray.value.forEach((elementProps, i) => {
lensflareElementPropsArrayRef.value.forEach((elementProps, i) => {
threeElements[i].size = elementProps.size * props.scale
})
}
Expand All @@ -110,18 +113,29 @@ onUnmounted(() => {
onMounted(() => {
lensflareRef.value?.add(threeLensflare)
lensflareElementPropsArray.value = fillInProps(props.elements, props.seed, props.seedProps)
lensflareElementPropsArrayRef.value
= fillInProps(props.elements, userDefaultLensflareElementPropsRef.value, props.seed, props.seedProps)
})
watch(() => [props.elements, props.seed, props.seedProps], () => {
lensflareElementPropsArray.value = fillInProps(props.elements, props.seed, props.seedProps)
watch(() => [props.color, props.distance, props.size, props.texture], () => {
userDefaultLensflareElementPropsRef.value = {
color: props.color,
distance: props.distance,
size: props.size,
texture: props.texture,
}
})
watch(() => [userDefaultLensflareElementPropsRef.value, props.elements, props.seed, props.seedProps], () => {
lensflareElementPropsArrayRef.value
= fillInProps(props.elements, userDefaultLensflareElementPropsRef.value, props.seed, props.seedProps)
})
watch(() => props.scale, () => {
scaleThreeElements()
})
watch(() => lensflareElementPropsArray.value, () => {
watch(() => lensflareElementPropsArrayRef.value, () => {
updateThreeElements()
})
</script>
Expand Down
11 changes: 9 additions & 2 deletions src/core/abstractions/Lensflare/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { SeedProps } from '.'
import type { LensflareElementProps, SeedProps } from '.'

export const TEXTURE_PATH
= 'https://raw.githubusercontent.com/andretchen0/tresjs_assets/'
Expand Down Expand Up @@ -73,4 +73,11 @@ export const back: SeedProps = {
length: [0, 5],
}

export const defaultSeedProps: SeedProps[] = [oversize, bodyRequired0, bodyRequired1, bodyOptional, front, back]
export const defaultSeedProps: SeedProps[] = [oversize, bodyRequired0, bodyRequired1, bodyOptional, front, back]

export const defaultLensflareElementProps: LensflareElementProps = {
color: 'white',
distance: 0,
size: 512,
texture: circleBlur,
}
Loading

0 comments on commit f90988e

Please sign in to comment.