mylingo3d
Version:
Lingo3D is a React/Vue 3d game development framework that ships with a complete visual editor
93 lines • 4.1 kB
JavaScript
import { createEffect } from "@lincode/reactivity";
import * as THREE from "three";
//@ts-ignore
import { ProgressiveLightMap } from "three/examples/jsm/misc/ProgressiveLightMap";
import Octahedron from "../display/primitives/Octahedron";
import Plane from "../display/primitives/Plane";
import { onBeforeRender } from "../events/onBeforeRender";
import { getCameraRendered } from "../states/useCameraRendered";
import { getRenderer } from "../states/useRenderer";
// ShadowMap + LightMap Res and Number of Directional Lights
const shadowMapRes = 512, lightMapRes = 1024, lightCount = 8;
let object = new THREE.Mesh(), lightOrigin = null;
const dirLights = [], lightmapObjects = [];
const blurEdges = true;
const blendWindow = 200;
const lightRadius = 50;
const ambientWeight = 0.5;
// directional lighting "origin"
lightOrigin = new THREE.Group();
lightOrigin.position.set(60, 150, 100);
// create 8 directional lights to speed up the convergence
for (let l = 0; l < lightCount; l++) {
const dirLight = new THREE.DirectionalLight(0xffffff, 1.0 / lightCount);
dirLight.name = "Dir. Light " + l;
dirLight.position.set(200, 200, 200);
dirLight.castShadow = true;
// dirLight.shadow.camera.near = 100
// dirLight.shadow.camera.far = 5000
dirLight.shadow.camera.right = 150;
dirLight.shadow.camera.left = -150;
dirLight.shadow.camera.top = 150;
dirLight.shadow.camera.bottom = -150;
dirLight.shadow.mapSize.width = shadowMapRes;
dirLight.shadow.mapSize.height = shadowMapRes;
lightmapObjects.push(dirLight);
dirLights.push(dirLight);
}
const ground = new Plane();
ground.rotationX = -90;
ground.scale = 100;
ground.y = -50;
const groundMesh = ground.object3d;
// const groundMesh = new THREE.Mesh(
// new THREE.PlaneGeometry(999 * scaleDown, 999 * scaleDown),
// new THREE.MeshStandardMaterial({ color: 0xffffff, depthWrite: true })
// )
lightmapObjects.push(groundMesh);
object = new Octahedron().object3d;
object.traverse(function (child) {
if (child.isMesh) {
child.material = new THREE.MeshStandardMaterial();
lightmapObjects.push(child);
}
});
const lightTarget = new THREE.Group();
lightTarget.position.set(0, 20, 0);
for (let l = 0; l < dirLights.length; l++) {
dirLights[l].target = lightTarget;
}
object.add(lightTarget);
createEffect(() => {
const renderer = getRenderer();
if (!renderer)
return;
const camera = getCameraRendered();
const progressiveSurfacemap = new ProgressiveLightMap(renderer, lightMapRes);
progressiveSurfacemap.addObjectsToLightMap(lightmapObjects);
const handle = onBeforeRender(() => {
progressiveSurfacemap.update(camera, blendWindow, blurEdges);
if (!progressiveSurfacemap.firstUpdate)
progressiveSurfacemap.showDebugLightmap(true);
// Manually Update the Directional Lights
for (let l = 0; l < dirLights.length; l++) {
// Sometimes they will be sampled from the target direction
// Sometimes they will be uniformly sampled from the upper hemisphere
if (Math.random() > ambientWeight) {
dirLights[l].position.set(lightOrigin.position.x + Math.random() * lightRadius, lightOrigin.position.y + Math.random() * lightRadius, lightOrigin.position.z + Math.random() * lightRadius);
}
else {
// Uniform Hemispherical Surface Distribution for Ambient Occlusion
const lambda = Math.acos(2 * Math.random() - 1) - 3.14159 / 2.0;
const phi = 2 * 3.14159 * Math.random();
dirLights[l].position.set(Math.cos(lambda) * Math.cos(phi) * 300 + object.position.x, Math.abs(Math.cos(lambda) * Math.sin(phi) * 300) +
object.position.y +
20, Math.sin(lambda) * 300 + object.position.z);
}
}
});
return () => {
handle.cancel();
};
}, [getRenderer, getCameraRendered]);
//# sourceMappingURL=testLightMapper.js.map