God Rays
Demo code
vue
<script setup lang="ts">
import { Environment, OrbitControls } from '@tresjs/cientos'
import { TresCanvas, useTexture } from '@tresjs/core'
import { TresLeches, useControls } from '@tresjs/leches'
import type { Mesh } from 'three'
import { BackSide, NoToneMapping } from 'three'
import { BlendFunction, KernelSize } from 'postprocessing'
import { EffectComposerPmndrs, GodRaysPmndrs } from '@tresjs/post-processing'
import { ref, watch } from 'vue'
import { gsap } from 'gsap'
import '@tresjs/leches/styles'
const gl = {
toneMapping: NoToneMapping,
multisampling: 8,
}
const sphereMeshRef = ref<Mesh | null>(null)
const pbrTexture = await useTexture({
map: '/lens-distortion/room-map.png',
})
const { blur, kernelSize, resolutionScale, opacity, blendFunction, density, decay, weight, exposure, samples, clampMax } = useControls({
blendFunction: {
options: Object.keys(BlendFunction).map(key => ({
text: key,
value: BlendFunction[key as keyof typeof BlendFunction],
})),
value: BlendFunction.SCREEN,
},
kernelSize: {
options: Object.keys(KernelSize).map(key => ({
text: key,
value: KernelSize[key as keyof typeof KernelSize],
})),
value: KernelSize.SMALL,
},
opacity: { value: 1, step: 0.01, min: 0, max: 1.0 },
density: { value: 0.96, step: 0.01, min: 0, max: 1.0 },
decay: { value: 0.93, step: 0.01, min: 0, max: 1.0 },
weight: { value: 0.4, step: 0.1, min: 0, max: 1.0 },
exposure: { value: 0.6, step: 0.1, min: 0, max: 1.0 },
samples: { value: 60, step: 1, min: 15, max: 200 },
clampMax: { value: 1.0, step: 0.1, max: 1.0 },
resolutionScale: { value: 0.5, step: 0.1, min: 0.1, max: 1.0 },
blur: true,
})
const torusMeshes = [
{ rotationY: Math.PI / 2, position: [-10, 2, 0], roughness: 0.1, color: '#82DBC5' },
{ rotationY: Math.PI / 2, position: [0, 2, 0], roughness: 0.3, color: '#505050' },
{ rotationY: Math.PI / 2, position: [10, 2, 0], roughness: 0.65, color: '#FC7BAC' },
]
watch(sphereMeshRef, () => {
if (!sphereMeshRef.value) { return }
gsap.to(sphereMeshRef.value.position, {
x: 20,
duration: 3,
repeat: -1,
yoyo: true,
ease: 'sine.inOut',
})
})
</script>
<template>
<div class="aspect-16/9">
<TresCanvas
v-bind="gl"
>
<TresPerspectiveCamera
:position="[0, 5, 35]"
:look-at="[0, 0, 0]"
/>
<OrbitControls auto-rotate />
<TresMesh ref="sphereMeshRef" :position="[-20, 2, 0]">
<TresSphereGeometry :args="[2, 32, 32]" />
<TresMeshBasicMaterial color="#FFDDAA" :transparent="true" />
</TresMesh>
<template v-for="(mesh) in torusMeshes" :key="`demo-god-rays-${mesh.color}`">
<TresMesh :rotation-y="mesh.rotationY" :position="mesh.position">
<TresTorusGeometry :args="[5, 2, 16, 100]" />
<TresMeshPhysicalMaterial :roughness="mesh.roughness" :color="`${mesh.color}`" />
</TresMesh>
</template>
<TresMesh :position="[0, 2, 0]">
<TresBoxGeometry :args="[50, 50, 50]" />
<TresMeshStandardMaterial :side="BackSide" :map="pbrTexture.map" />
</TresMesh>
<Suspense>
<Environment preset="shangai" />
</Suspense>
<Suspense>
<EffectComposerPmndrs>
<GodRaysPmndrs
:opacity="opacity"
:lightSource="sphereMeshRef"
:blendFunction="Number(blendFunction)"
:density="density"
:decay="decay"
:weight="weight"
:exposure="exposure"
:samples="samples"
:clampMax="clampMax"
:resolutionScale="resolutionScale"
:kernelSize="kernelSize"
:blur="blur"
/>
</EffectComposerPmndrs>
</Suspense>
</TresCanvas>
</div>
<TresLeches :float="false" />
</template>
The GodRays
effect is part of the postprocessing
package. It simulates the appearance of light rays shining through objects, creating a volumetric lighting effect. This effect can enhance the visual appeal of your scene by adding a dramatic and realistic lighting effect.
Usage
The <GodRaysPmndrs>
component is easy to use and provides customizable options to suit different visual styles.
vue
<script setup lang="ts">
import { OrbitControls } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
import { NoToneMapping } from 'three'
import { EffectComposerPmndrs, GodRaysPmndrs } from '@tresjs/post-processing'
import '@tresjs/leches/styles'
const gl = {
clearColor: 'blue',
toneMapping: NoToneMapping,
multisampling: 8,
}
const sphereMeshRef = ref(null)
const effectProps = reactive({
opacity: .8,
exposure: .8,
resolutionScale: 0.65
})
</script>
<template>
<TresCanvas v-bind="gl">
<TresPerspectiveCamera :position="[0, 5, 20]" />
<OrbitControls auto-rotate />
<TresMesh ref="sphereMeshRef" :position="[-10, 8, 0]">
<TresSphereGeometry :args="[2, 32, 32]" />
<TresMeshBasicMaterial color="#FFDDAA" :transparent="true" />
</TresMesh>
<TresMesh :position="[0, .5, 0]">
<TresBoxGeometry :args="[2, 2, 2]" />
<TresMeshBasicMaterial color="white" />
</TresMesh>
<Suspense>
<EffectComposerPmndrs>
<GodRaysPmndrs :lightSource="sphereMeshRef" v-bind="effectProps" />
</EffectComposerPmndrs>
</Suspense>
</TresCanvas>
</template>
Props
Prop | Description | Default |
---|---|---|
blendFunction | Defines how the effect blends with the original scene. See the BlendFunction options. | BlendFunction.SCREEN |
lightSource | The light source. Must not write depth and has to be flagged as transparent. This can be a Mesh or a Points . | undefined |
opacity | The opacity of the God Rays. | 1.0 |
density | The density of the light rays. | 0.96 |
decay | The decay of the light rays. | 0.9 |
kernelSize | The blur kernel size. Has no effect if blur props is disabled. See the KernelSize options. | KernelSize.SMALL |
resolutionScale | The resolution scale. | 0.5 |
blur | Whether the god rays should be blurred to reduce artifacts. | true |
resolutionX | The horizontal resolution. | Resolution.AUTO_SIZE |
resolutionY | The vertical resolution. | Resolution.AUTO_SIZE |
weight | The weight of the light rays. | 0.4 |
exposure | A constant attenuation coefficient. | 0.6 |
samples | The number of samples per pixel. | 60 |
clampMax | An upper bound for the saturation of the overall effect. | 1.0 |
Further Reading
For more details, see the GodRays documentation