Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ektogamat/lensflare #230

Closed
wants to merge 12 commits into from
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .storybook/public/lensDirtTexture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
90 changes: 90 additions & 0 deletions .storybook/stories/LensFlare.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React, { memo } from 'react'
import * as THREE from 'three'
import type { Meta, StoryObj } from '@storybook/react'
import { BackSide } from 'three'
import { Box, useTexture } from '@react-three/drei'

import { Setup } from '../Setup'
import { EffectComposer, LensFlare, Vignette, Bloom, BrightnessContrast } from '../../src'

function SkyBox() {
const texture = useTexture('/digital_painting_golden_hour_sunset.jpg')

return (
<mesh userData={{ lensflare: 'no-occlusion' }} scale={[-1, 1, 1]} castShadow={false} receiveShadow={false}>
<sphereGeometry args={[50, 32, 32]} />
<meshBasicMaterial toneMapped={false} map={texture} side={BackSide} />
</mesh>
)
}

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
const meta = {
title: 'Effect/LensFlare',
component: LensFlare,
decorators: [
(Story) => (
<Setup cameraPosition={new THREE.Vector3(8, 1, 10)} cameraFov={50}>
{Story()}
</Setup>
),
],
tags: ['autodocs'],
// argTypes: {
// debug: {
// control: { type: 'range', min: 0, max: 1, step: 0.01 },
// },
// },
} satisfies Meta<typeof LensFlare>

export default meta
type Story = StoryObj<typeof meta>

// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
export const Primary: Story = {
render: (args) => (
<>
<color attach="background" args={['#303035']} />

<directionalLight intensity={3} position={[-25, 60, -60]} />

<Box />

<SkyBox />

<EffectComposer multisampling={0} disableNormalPass>
<LensFlare {...args} />
<BrightnessContrast contrast={0.2} />
<Vignette />
</EffectComposer>
</>
),
args: { colorGain: new THREE.Color(56, 21, 9) },
}

function DirtLensFlare(props) {
const texture = useTexture('/lensDirtTexture.png')

return <LensFlare {...props} lensDirtTexture={texture} />
}

export const Secondary: Story = {
render: (args) => (
<>
<color attach="background" args={['#303035']} />

<directionalLight intensity={3} position={[-25, 60, -60]} />

<Box />

<SkyBox />

<EffectComposer multisampling={0} disableNormalPass>
<DirtLensFlare {...args} />
<BrightnessContrast contrast={0.2} />
<Vignette />
</EffectComposer>
</>
),
args: { starBurst: true, colorGain: new THREE.Color(56, 21, 9) },
}
57 changes: 57 additions & 0 deletions docs/effects/lensflare.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
title: Lensflare
nav: 1
---

A Lens Flare adds the optical aberration caused by the dispersion of light entering the lens through its edges.

Based on [ektogamat/R3F-Ultimate-Lens-Flare](https://github.com/ektogamat/R3F-Ultimate-Lens-Flare).

```jsx
import { LensFlare } from '@react-three/postprocessing'

return (
<LensFlare
blendFunction={BlendFunction.Screen} // The blend function of this effect.
enabled={true} // Boolean to enable/disable the effect.
opacity={1.0} // The opacity for this effect. Default: 1.0
starBurst={true} // Boolean to enable/disable the start burst effect. Can be disabled to improve performance.
glareSize={0.96} // The glare size. Default: 0.2
followMouse={false} // Set it to follow the mouse, ignoring the lens position. Default: false
lensPosition={[0, 0.5, 0]} // The position of the lens flare in 3d space.
starPoints={6} // The number of points for the star. Default: 6
flareSize={0.01} // The flare side. Default 0.01
flareSpeed={0.01} // The flare animation speed. Default 0.01
flareShape={0.01} // Changes the appearance to anamorphic. Default 0.01
animated={true} // Animated flare. Default: true
anamorphic={false} //Set the appearance to full anamorphic. Default: false
colorGain={new THREE.Color(70, 70, 70)} // Set the color gain for the lens flare. Must be a THREE.Color in RBG format.
lensDirtTexture={'/lensDirtTexture.png'} // Texture to be used as color dirt for starburst effect.
haloScale={0.5} // The halo scale. Default: 0.5
secondaryGhosts={true} // Option to enable/disable secondary ghosts. Default: true.
ghostScale={0.0} // Option to enable/disable secondary ghosts. Default: true.
aditionalStreaks={true} // Option to enable/disable aditional streaks. Default: true.
smoothTime={0.07} // The time that it takes to fade the occlusion. Default: 0.07
/>
)
```

#### Ignoring occlusion on some objects

To disable the occlusion effect, simply add `userData={{ lensflare: 'no-occlusion' }}` to your object/mesh props.

#### Improving performance

Use bvh `<bvh><Scene></bvh>` to enhance the internal raycaster performance.

#### Limitations

The Ultimate Lens Flare leverages the raycaster to examine the material type of objects and determine if they are `MeshTransmissionMaterial` or `MeshPhysicalMaterial`. It checks for the transmission parameter to identify glass-like materials. Therefore, for an object to behave like glass, its material should have either `transmission = 1` or `transparent = true` and `opacity = NUMBER`. The effect automatically interprets the opacity `NUMBER` value to determine the brightness of the flare.

#### Credits

- https://www.shadertoy.com/view/4sK3W3
- https://www.shadertoy.com/view/4sX3Rs
- https://www.shadertoy.com/view/dllSRX
- https://www.shadertoy.com/view/Xlc3D2
- https://www.shadertoy.com/view/XtKfRV
Loading