UNPKG

mylingo3d

Version:

Lingo3D is a React/Vue 3d game development framework that ships with a complete visual editor

95 lines 4 kB
import { Reactive } from "@lincode/reactivity"; import { mapRange } from "@tweakpane/core"; import { DirectionalLight as ThreeDirectionalLight } from "three"; import scene from "../../engine/scene"; import { onBeforeRender } from "../../events/onBeforeRender"; import { SHADOW_DISTANCE } from "../../globals"; import { directionalLightDefaults, directionalLightSchema } from "../../interface/IDirectionalLight"; import { getCameraRendered } from "../../states/useCameraRendered"; import { getShadowDistance } from "../../states/useShadowDistance"; import LightBase from "../core/LightBase"; import getWorldPosition from "../utils/getWorldPosition"; import { vec2Point } from "../utils/vec2Point"; export default class DirectionalLight extends LightBase { static componentName = "directionalLight"; static defaults = directionalLightDefaults; static schema = directionalLightSchema; defaultShadowResolution = 1024; constructor() { super(ThreeDirectionalLight); this.createEffect(() => { const light = this.lightState.get(); if (!light) return; scene.add(light.target); scene.attach(light); return () => { scene.remove(light.target); scene.remove(light); }; }, [this.lightState.get]); this.createEffect(() => { const light = this.lightState.get(); if (!light) return; const camManager = getCameraRendered().userData.manager; const offset = camManager ? Math.max(mapRange(camManager.innerZ * (camManager.fov / 75) * (1 / camManager.zoom), 500, 1000, 1, 1.5), 1) : 1; const shadowDistance = this.shadowDistanceState.get() ?? getShadowDistance() ?? SHADOW_DISTANCE; const shadowCamera = light.shadow.camera; shadowCamera.zoom = 500 / offset / shadowDistance; shadowCamera.updateProjectionMatrix(); const shadowBiasComputed = this.shadowBiasComputedState.get(); const shadowResolutionComputed = this.shadowResolutionComputedState.get(); if (!shadowBiasComputed || !shadowResolutionComputed) return; const shadowBias = shadowBiasComputed; light.shadow.bias = shadowBias * offset * (this.defaultShadowResolution / shadowResolutionComputed) * 0.5; return () => { light.shadow.bias = shadowBias; }; }, [ this.lightState.get, this.shadowDistanceState.get, getShadowDistance, getCameraRendered, this.shadowBiasComputedState.get, this.shadowResolutionComputedState.get ]); this.createEffect(() => { const light = this.lightState.get(); if (!light) return; const cam = getCameraRendered(); const handle = onBeforeRender(() => { const camPos = getWorldPosition(cam); const lightPos = getWorldPosition(this.outerObject3d); light.position.copy(camPos).add(lightPos); light.target.position.copy(camPos).sub(lightPos); }); return () => { handle.cancel(); }; }, [getCameraRendered, this.lightState.get]); } getWorldPosition() { return vec2Point(getWorldPosition(this.outerObject3d)); } shadowDistanceState = new Reactive(undefined); get shadowDistance() { return this.shadowDistanceState.get(); } set shadowDistance(val) { this.shadowDistanceState.set(val); } } //# sourceMappingURL=DirectionalLight.js.map