Skip to content

Light-schaduwen

Deze gids helpt u aan de slag te gaan met eenvoudig licht en schaduwen in TresJS.

We zullen een eenvoudige scène bouwen met drie meshes en een vlak, maar slechts twee zullen schaduwen hebben.

De scene opzetten (optioneel)

We importeren alle modules die we nodig hebben, voor het comfort kunnen we de orbit-controls van cientos gebruiken, kijk hier om te weten hoe.

Laten we vier objecten in onze scène plaatsen, één zal het vlak zijn dat schaduwen ontvangt, twee ervan zullen schaduwen werpen en de laatste zal helemaal geen schaduw werpen.

Ik ga MeshToonMaterial gebruiken. Simpelweg omdat we de ‘zachte schaduw’ gemakkelijk kunnen zien.

vue
<script setup lang="ts">
import { OrbitControls } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
</script>

<template>
  <TresCanvas
    clear-color="#111"
    window-size
  >
    <OrbitControls />
    <TresPerspectiveCamera :position="[5, 7.5, 7.5]" />

    <TresMesh
      :position="[-2, 2, 0]"
      :rotation="[0, Math.PI, 0]"
    >
      <TresConeGeometry :args="[1, 1.5, 3]" />
      <TresMeshToonMaterial color="#82DBC5" />
    </TresMesh>
    <TresMesh
      :position="[0, 0, 0]"
    >
      <TresBoxGeometry :args="[1.5, 1.5, 1.5]" />
      <TresMeshToonMaterial color="#4F4F4F" />
    </TresMesh>
    <TresMesh
      :position="[2, -2, 0]"
    >
      <TresSphereGeometry />
      <TresMeshToonMaterial color="#FBB03B" />
    </TresMesh>
    <TresMesh
      :position="[0, -3, 0]"
      :rotation="[-Math.PI / 2, 0, 0]"
    >
      <TresPlaneGeometry :args="[10, 10, 10, 10]" />
      <TresMeshStandardMaterial color="#f7f7f7" />
    </TresMesh>
  </TresCanvas>
</template>

Lichten (uitleg)

Zoals u weet is elke instantie in ThreeJs beschikbaar in TresJs, en dat geldt ook voor alle lichttypen. We hoeven alleen maar het voorvoegsel Tres toe te voegen om ze te gebruiken.

Maar niet alle lichten kunnen schaduwen werpen, deze definitie komt rechtstreeks van ThreeJs en is logisch, bijvoorbeeld het doel van een ambientLight is bedoeld om elke kant van uw scène te verlichten, dus het heeft geen zin om schaduwen te werpen, integendeel, een DirectionalLight het imiteren van de zon kan en moet schaduwen werpen.

Schaduwen (uitleg)

Er zijn ook veel soorten schaduwen, de "zachte schaduw" wordt bijvoorbeeld automatisch gegenereerd wanneer een object meer licht van één kant ontvangt, maar kort samengevat moet een "ThreeJS-standaardschaduw" die naar een ander oppervlak is gericht, door een mesh worden geworpen en een ander mesh moet het ontvangen. Zoals we in ons voorbeeld zien, ontvangt het Plane een schaduw, maar werpt deze niet. Houd er rekening mee dat niet alle materialen schaduw kunnen werpen of ontvangen.

Intern genereert ThreeJS automatisch een nieuwe mesh met een ShadowMaterial die in elk frame wordt bijgewerkt, daarom als je animaties toepast, wordt de schaduw ook geanimeerd, maar ook waarom je schaduwen zorgvuldig moet gebruiken, omdat ze je prestaties kunnen vertragen.

WARNING

Als u op deze manier overmatig gebruik maakt van schaduwen, kunnen uw prestaties afnemen. Er zijn echter manieren om uw prestaties te verbeteren. Voor meer informatie kunt u deze video bekijken.

Schaduwen aanzetten

We kunnen dit verdelen in drie stappen:

Activeer schaduwen op de renderer

vue
//...

<template>
  <TresCanvas
    clear-color="#111"
    shadows
    window-size
  />
  //...
</template>

Stel het licht in om schaduwen te werpen

We kunnen simpel de boolean cast-shadow toevoegen, Vue snapt dit als een prop met een waarde van true.

Het AmbientLight genereert hier geen enkele vorm van schaduw

vue
//...

<template>
  <TresAmbientLight :intensity="1" />
  <TresDirectionalLight
    cast-shadow
    :position="[0, 2, 0]"
    :intensity="1"
  />

  //...
</template>

Stel de objecten in om schaduwen te werpen of te ontvangen

Op dezelfde manier als in de vorige stap stellen we de mesh waarop we schaduw willen werpen (onze bol) in met de cast-shadow prop, en stellen we het object in om schaduw te ontvangen (ons vlak) met de receive-shadow prop.

vue
//...

<template>
  <TresMesh
    cast-shadow
    :position="[2, -2, 0]"
  >
    <TresSphereGeometry />
    <TresMeshToonMaterial color="#FBB03B" />
  </TresMesh>
  <TresMesh
    receive-shadow
    :position="[0, -3, 0]"
    :rotation="[-Math.PI / 2, 0, 0]"
  >
    <TresPlaneGeometry :args="[10, 10, 10, 10]" />
    <TresMeshStandardMaterial color="#f7f7f7" />
  </TresMesh>
  //...
</template>

Nu hebben we alle noodzakelijke stappen om schaduwen aan onze scène toe te voegen, en als we toepassen wat we hebben geleerd in basisanimaties, en we voegen beweging toe aan onze kubus, zul je zien dat de schaduw ook geanimeerd is. 🤩

vue
<script setup>
import { TresCanvas, useRenderLoop } from '@tresjs/core'
import { shallowRef } from 'vue'

const boxRef = shallowRef()

const { onLoop } = useRenderLoop()

onLoop(() => {
  if (boxRef.value) {
    boxRef.value.rotation.y += 0.01
  }
})
</script>

<template>
  //...
  <TresMesh
    ref="boxRef"
    cast-shadow
    :position="[0, 0, 0]"
  >
    <TresBoxGeometry :args="[1.5, 1.5, 1.5]" />
    <TresMeshToonMaterial color="#4F4F4F" />
  </TresMesh>
  //...
</template>

Merk op dat ik met opzet geen cast-shadow heb toegepast op de Kegel, zodat deze geen schaduw werpt