scene.ts
import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera";
import type { Engine } from "@babylonjs/core/Engines/engine";
import { PointLight } from "@babylonjs/core/Lights/pointLight";
import { ImportMeshAsync } from "@babylonjs/core/Loading/sceneLoader";
import { Color3 } from "@babylonjs/core/Maths/math.color";
import { Vector3 } from "@babylonjs/core/Maths/math.vector";
import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial";
import { Texture } from "@babylonjs/core/Materials/Textures/texture";
import { VolumetricLightScatteringPostProcess } from "@babylonjs/core/PostProcesses/volumetricLightScatteringPostProcess";
import { Scene } from "@babylonjs/core/scene";
import "@babylonjs/core/Loading/Plugins/babylonFileLoader";
export async function createVolumetricLightScatteringScene(engine: Engine, canvas: HTMLCanvasElement): Promise<Scene> {
const scene = new Scene(engine);
scene.clearColor.set(0.02, 0.02, 0.08, 1);
const light = new PointLight("Omni", new Vector3(20, 20, 100), scene);
const camera = new ArcRotateCamera("Camera", -0.5, 2.2, 100, Vector3.Zero(), scene);
camera.attachControl(canvas, true);
const result = await ImportMeshAsync("skull.babylon", scene, {
rootUrl: "/Scenes/Assets/",
meshNames: "",
});
const skull = result.meshes[0];
if (skull) {
camera.target = skull.position;
const material = new StandardMaterial("skull", scene);
material.emissiveColor = new Color3(0.2, 0.2, 0.2);
skull.material = material;
}
const godRays = new VolumetricLightScatteringPostProcess(
"godrays",
1,
camera,
null,
100,
Texture.BILINEAR_SAMPLINGMODE,
engine,
false
);
if (godRays.mesh.material instanceof StandardMaterial) {
const sunTexture = new Texture("/Scenes/Assets/sun.png", scene, true, false, Texture.BILINEAR_SAMPLINGMODE);
sunTexture.hasAlpha = true;
godRays.mesh.material.diffuseTexture = sunTexture;
}
godRays.mesh.position = new Vector3(-150, 150, 150);
godRays.mesh.scaling = new Vector3(350, 350, 350);
light.position = godRays.mesh.position;
scene.registerBeforeRender(() => {
if (skull) {
skull.rotation.y += 0.002 * scene.getAnimationRatio();
}
});
return scene;
}