From 7201a9d1fe9fed3a3ff2497f0ba7a72c36418598 Mon Sep 17 00:00:00 2001 From: Fabian Bormann Date: Sat, 12 Aug 2023 23:20:37 +0200 Subject: [PATCH] feat: add light sources at the ceiling --- src/3d/RoomBuilder.ts | 255 ++++++++++++++++++++++++------------------ src/3d/Scene.tsx | 40 +------ 2 files changed, 152 insertions(+), 143 deletions(-) diff --git a/src/3d/RoomBuilder.ts b/src/3d/RoomBuilder.ts index d398463..d4db58f 100755 --- a/src/3d/RoomBuilder.ts +++ b/src/3d/RoomBuilder.ts @@ -11,9 +11,48 @@ import { Light, SceneLoader, PBRMaterial, + StandardMaterial, + AbstractMesh, + ShadowGenerator, } from '@babylonjs/core'; import { RoomType } from '../global/types'; +const addLamp = ( + scene: Scene, + row: number, + col: number +): Promise<{ lampLight: PointLight; lampMeshes: Array }> => + new Promise((resolve, reject) => { + const pointLight = new PointLight( + 'PointLight', + new Vector3(col * 100, 50, row * 100), + scene + ); + + pointLight.falloffType = Light.FALLOFF_DEFAULT; + pointLight.range = 80; + pointLight.radius = 0.6; + pointLight.intensity = 0.3; + pointLight.diffuse = new Color3(1, 1, 1); + pointLight.specular = new Color3(0.5, 0.5, 0.5); + + SceneLoader.ImportMesh('', '/models/', 'lamp.glb', scene, (meshes) => { + for (const mesh of meshes) { + if (mesh.name.endsWith('primitive2')) { + const material = mesh.material as PBRMaterial; + material.emissiveColor = new Color3(1, 1, 1); + material.emissiveIntensity = 1; + } + + mesh.rotation = new Vector3(0, 0, 0); + mesh.scaling = new Vector3(1, 1, 1); + mesh.position = new Vector3(col * 50, 40.1, row * 50); + } + + resolve({ lampLight: pointLight, lampMeshes: meshes }); + }); + }); + const createRoomTile = ( type: RoomType, row: number, @@ -73,127 +112,125 @@ const createRoomTile = ( probe.renderList.push(ceiling); } - const pointLight = new PointLight( - 'PointLight', - new Vector3(col * 100, 50, row * 100), + const ground = MeshBuilder.CreatePlane( + 'Ground', + { size: 100, sideOrientation: Mesh.FRONTSIDE }, scene ); + ground.rotation = new Vector3(Math.PI / 2, 0, 0); + ground.position = new Vector3(col * 100, 0, row * 100); - pointLight.falloffType = Light.FALLOFF_STANDARD; - pointLight.range = 100; - pointLight.radius = 25; - pointLight.intensity = 1.5; - pointLight.diffuse = new Color3(1, 1, 1); - pointLight.specular = new Color3(0.5, 0.5, 0.5); - - SceneLoader.ImportMesh('', '/models/', 'lamp.glb', scene, (meshes) => { - for (const mesh of meshes) { - if (mesh.name.endsWith('primitive2')) { - const material = mesh.material as PBRMaterial; - material.emissiveColor = new Color3(1, 1, 1); - material.emissiveIntensity = 1; - } + const groundMaterial = new StandardMaterial('ground', scene); + const groundDiffuseTexture = new Texture( + '/textures/Marble_White_006_basecolor.jpg', + scene + ); - mesh.rotation = new Vector3(0, 0, 0); - mesh.scaling = new Vector3(1, 1, 1); - mesh.position = new Vector3(col * 50, 40.1, row * 50); + groundMaterial.diffuseTexture = groundDiffuseTexture; + groundMaterial.ambientColor = new Color3(1, 1, 1); + groundMaterial.reflectionTexture = probe; + ground.material = groundMaterial; + + addLamp(scene, row, col).then(({ lampLight, lampMeshes }) => { + const walls: Array = []; + + if ( + [ + RoomType.TOP_CLOSED, + RoomType.CORNER_LEFT_TOP, + RoomType.CORNER_RIGHT_TOP, + RoomType.HORIZONTAL_FLOOR, + RoomType.LEFT_OPEN, + RoomType.RIGHT_OPEN, + RoomType.BOTTOM_OPEN, + ].includes(type) + ) { + const front = MeshBuilder.CreatePlane( + 'Front Wall', + { width: 100, height: 80, sideOrientation: Mesh.DOUBLESIDE }, + scene + ); + front.position = new Vector3(col * 100, 40, 50 + row * 100); + walls.push(front); } - }); - const walls: Array = []; - - if ( - [ - RoomType.TOP_CLOSED, - RoomType.CORNER_LEFT_TOP, - RoomType.CORNER_RIGHT_TOP, - RoomType.HORIZONTAL_FLOOR, - RoomType.LEFT_OPEN, - RoomType.RIGHT_OPEN, - RoomType.BOTTOM_OPEN, - ].includes(type) - ) { - const front = MeshBuilder.CreatePlane( - 'Front Wall', - { width: 100, height: 80, sideOrientation: Mesh.DOUBLESIDE }, - scene - ); - front.position = new Vector3(col * 100, 40, 50 + row * 100); - walls.push(front); - } + if ( + [ + RoomType.LEFT_CLOSED, + RoomType.CORNER_LEFT_TOP, + RoomType.CORNER_LEFT_BOTTOM, + RoomType.VERTICAL_FLOOR, + RoomType.TOP_OPEN, + RoomType.RIGHT_OPEN, + RoomType.BOTTOM_OPEN, + ].includes(type) + ) { + const left = MeshBuilder.CreatePlane( + 'Left Wall', + { width: 100, height: 80, sideOrientation: Mesh.DOUBLESIDE }, + scene + ); + left.position = new Vector3(-50 + col * 100, 40, row * 100); + left.rotation = new Vector3(0, -Math.PI / 2, 0); + walls.push(left); + } - if ( - [ - RoomType.LEFT_CLOSED, - RoomType.CORNER_LEFT_TOP, - RoomType.CORNER_LEFT_BOTTOM, - RoomType.VERTICAL_FLOOR, - RoomType.TOP_OPEN, - RoomType.RIGHT_OPEN, - RoomType.BOTTOM_OPEN, - ].includes(type) - ) { - const left = MeshBuilder.CreatePlane( - 'Left Wall', - { width: 100, height: 80, sideOrientation: Mesh.DOUBLESIDE }, - scene - ); - left.position = new Vector3(-50 + col * 100, 40, row * 100); - left.rotation = new Vector3(0, -Math.PI / 2, 0); - walls.push(left); - } + if ( + [ + RoomType.RIGHT_CLOSED, + RoomType.CORNER_RIGHT_TOP, + RoomType.CORNER_RIGHT_BOTTOM, + RoomType.VERTICAL_FLOOR, + RoomType.TOP_OPEN, + RoomType.LEFT_OPEN, + RoomType.BOTTOM_OPEN, + ].includes(type) + ) { + const right = MeshBuilder.CreatePlane( + 'Right Wall', + { width: 100, height: 80, sideOrientation: Mesh.DOUBLESIDE }, + scene + ); + right.position = new Vector3(col * 100 + 50, 40, row * 100 + 0); + right.rotation = new Vector3(0, Math.PI / 2, 0); + walls.push(right); + } - if ( - [ - RoomType.RIGHT_CLOSED, - RoomType.CORNER_RIGHT_TOP, - RoomType.CORNER_RIGHT_BOTTOM, - RoomType.VERTICAL_FLOOR, - RoomType.TOP_OPEN, - RoomType.LEFT_OPEN, - RoomType.BOTTOM_OPEN, - ].includes(type) - ) { - const right = MeshBuilder.CreatePlane( - 'Right Wall', - { width: 100, height: 80, sideOrientation: Mesh.DOUBLESIDE }, - scene - ); - right.position = new Vector3(col * 100 + 50, 40, row * 100 + 0); - right.rotation = new Vector3(0, Math.PI / 2, 0); - walls.push(right); - } + if ( + [ + RoomType.BOTTOM_CLOSED, + RoomType.CORNER_LEFT_BOTTOM, + RoomType.CORNER_RIGHT_BOTTOM, + RoomType.HORIZONTAL_FLOOR, + RoomType.TOP_OPEN, + RoomType.LEFT_OPEN, + RoomType.RIGHT_OPEN, + ].includes(type) + ) { + const back = MeshBuilder.CreatePlane( + 'Back Wall', + { width: 100, height: 80, sideOrientation: Mesh.DOUBLESIDE }, + scene + ); + back.position = new Vector3(col * 100, 40, -50 + row * 100); + back.rotation = new Vector3(0, Math.PI, 0); + walls.push(back); + } - if ( - [ - RoomType.BOTTOM_CLOSED, - RoomType.CORNER_LEFT_BOTTOM, - RoomType.CORNER_RIGHT_BOTTOM, - RoomType.HORIZONTAL_FLOOR, - RoomType.TOP_OPEN, - RoomType.LEFT_OPEN, - RoomType.RIGHT_OPEN, - ].includes(type) - ) { - const back = MeshBuilder.CreatePlane( - 'Back Wall', - { width: 100, height: 80, sideOrientation: Mesh.DOUBLESIDE }, - scene - ); - back.position = new Vector3(col * 100, 40, -50 + row * 100); - back.rotation = new Vector3(0, Math.PI, 0); - walls.push(back); - } + probe.renderList?.push(...lampMeshes); - for (const wall of walls) { - wall.checkCollisions = true; - wall.material = wallMaterial; - if (probe.renderList) { - probe.renderList.push(wall); + for (const wall of walls) { + wall.checkCollisions = true; + wall.material = wallMaterial; + wall.receiveShadows = true; + + if (probe.renderList) { + probe.renderList.push(wall); + } } - } - pointLight.includedOnlyMeshes = [ceiling, ...walls]; + lampLight.includedOnlyMeshes = [ceiling, ...lampMeshes, ...walls, ground]; + }); }; export { createRoomTile }; diff --git a/src/3d/Scene.tsx b/src/3d/Scene.tsx index ed86abc..9f917c5 100755 --- a/src/3d/Scene.tsx +++ b/src/3d/Scene.tsx @@ -16,6 +16,8 @@ import { PointerEventTypes, Scene, Color4, + ShadowGenerator, + SSAO2RenderingPipeline, } from '@babylonjs/core'; import SceneComponent from 'babylonjs-hook'; @@ -92,6 +94,8 @@ const MainScene = ({ mainScene ); + mainScene.ambientColor = new Color3(0.2, 0.2, 0.2); + mainScene.shadowsEnabled = true; mainScene.onPrePointerObservable.add((pointerInfo) => { if ( [ @@ -151,40 +155,13 @@ const MainScene = ({ ); light.diffuse = new Color3(1, 1, 1); light.specular = new Color3(0.2, 0.2, 0.2); - light.intensity = 1.5; - - const pointLight = new PointLight( - 'PointLight', - new Vector3(0, 30, 0), - mainScene - ); - pointLight.falloffType = Light.FALLOFF_STANDARD; - pointLight.range = 25; - pointLight.intensity = 1.8; + light.intensity = 1.3; mainScene.clearColor = new Color4(0, 0, 0, 1); - const ground = MeshBuilder.CreatePlane( - 'Ground', - { size: 100 * 20, sideOrientation: Mesh.FRONTSIDE }, - mainScene - ); - ground.rotation = new Vector3(Math.PI / 2, 0, 0); - - const groundMaterial = new StandardMaterial('ground', mainScene); - const groundDiffuseTexture = new Texture( - '/textures/Marble_White_006_basecolor.jpg', - mainScene - ); - - groundDiffuseTexture.uScale = 40; - groundDiffuseTexture.vScale = 40; - groundMaterial.diffuseTexture = groundDiffuseTexture; - groundMaterial.specularColor = new Color3(0, 0, 0); - const reflectionTexture = new MirrorTexture( 'mirror', - 512, + 1024, mainScene, true ); @@ -193,9 +170,6 @@ const MainScene = ({ reflectionTexture.level = 0.2; reflectionTexture.adaptiveBlurKernel = 15; - groundMaterial.reflectionTexture = reflectionTexture; - ground.material = groundMaterial; - for (const room of gallery) { createRoomTile( room.type, @@ -228,8 +202,6 @@ const MainScene = ({ mainScene.executeWhenReady(() => onSceneReady()); mainScene.registerBeforeRender(() => { camera.position.y = CAMERA_HEIGHT; - pointLight.position.x = camera.position.x; - pointLight.position.z = camera.position.z; }); setInitialized(true); }