diff --git a/src/core/renderer.ts b/src/core/renderer.ts index 65ff5f9..462f14d 100644 --- a/src/core/renderer.ts +++ b/src/core/renderer.ts @@ -129,7 +129,11 @@ export class Renderer { const lightningColor = new Color(0, 0, 0, 1); for (const light of lights) { - light.applyLight(polygon, normal, lightningColor); + const needApplyLight = light.layers.length == 0 || object3d.layers.some((layer) => light.layers.includes(layer)); + + if (needApplyLight) { + light.applyLight(polygon, normal, lightningColor); + } } const color = object3d.color.copy(); diff --git a/src/core/scene.ts b/src/core/scene.ts index be7bee1..5adc86c 100644 --- a/src/core/scene.ts +++ b/src/core/scene.ts @@ -32,6 +32,7 @@ export abstract class Scene { geometry, color: new Color(0, 150, 255), backfaceCullingEnabled: true, + layers: [], pivot: Vector3.zero, position: Vector3.zero, diff --git a/src/main.ts b/src/main.ts index 95cb49c..9b87b73 100644 --- a/src/main.ts +++ b/src/main.ts @@ -25,8 +25,8 @@ const engine = new Engine(canvas); // await engine.setScene(CameraRotatingScene); // await engine.setScene(ScaleScene); // await engine.setScene(TranslationScene); - await engine.setScene(UrbanScene); - // await engine.setScene(SolarScene); + // await engine.setScene(UrbanScene); + await engine.setScene(SolarScene); // await engine.setScene(TestScene); // await engine.setScene(CubeScene); // await engine.setScene(DirectLightScene); diff --git a/src/objects/light-source.ts b/src/objects/light-source.ts index 2795775..6f2343c 100644 --- a/src/objects/light-source.ts +++ b/src/objects/light-source.ts @@ -7,6 +7,8 @@ export type LightConfig = { color: Color; intensity: number; + layers: string[]; + pivot: Vector3; position: Vector3; }; @@ -16,11 +18,14 @@ export abstract class LightSource extends SpaceEntity { color: Color; + layers: string[]; + constructor(options: Partial) { super(options.pivot ?? Vector3.zero); this.color = options.color ?? new Color(255, 255, 255, 1); this.intensity = options.intensity ?? 1; + this.layers = options.layers ?? []; this.setPosition(options.position ?? Vector3.zero); } diff --git a/src/objects/object3d.ts b/src/objects/object3d.ts index 22ab94f..678c7e6 100644 --- a/src/objects/object3d.ts +++ b/src/objects/object3d.ts @@ -10,6 +10,7 @@ export type Object3DConfig = { geometry: Geometry; color: Color; backfaceCullingEnabled: boolean; + layers: string[]; name?: string; pivot: Vector3; @@ -27,7 +28,9 @@ export class Object3D extends SpaceEntity { backfaceCullingEnabled: boolean; - constructor({ name, geometry, color, pivot, position, scale, direction, backfaceCullingEnabled }: Object3DConfig) { + layers: string[]; + + constructor({ name, geometry, color, layers, pivot, position, scale, direction, backfaceCullingEnabled }: Object3DConfig) { super(pivot); this.name = name ?? 'entity'; @@ -35,6 +38,7 @@ export class Object3D extends SpaceEntity { this.geometry = geometry; this.color = color; this.backfaceCullingEnabled = backfaceCullingEnabled; + this.layers = layers; this.setScale(scale); this.setPosition(position); @@ -89,6 +93,10 @@ export class Object3D extends SpaceEntity { const transformMatrix = translateTo.mmul(rotation).mmul(translateFrom); + if (pivot) { + this.position.mmul(transformMatrix); + } + for (const vertex of this.geometry.vertexes) { vertex.mmul(transformMatrix); } diff --git a/src/scenes/solar-scene.ts b/src/scenes/solar-scene.ts index e2f8861..1cc5ddd 100644 --- a/src/scenes/solar-scene.ts +++ b/src/scenes/solar-scene.ts @@ -1,6 +1,6 @@ import { Scene } from '../core/scene'; import { Camera } from '../objects/camera'; -import { DirectLight } from '../objects/light-source'; +import { DirectLight, SpotLight } from '../objects/light-source'; import { Object3D } from '../objects/object3d'; import { Color } from '../structures/color'; import { Vector3 } from '../structures/vector'; @@ -27,65 +27,92 @@ export class SolarScene extends Scene { saturn?: Object3D; uranus?: Object3D; neptune?: Object3D; + moon?: Object3D; configureScene(): void { - const camera = (this.mainCamera = new Camera({ backgroundColor: new Color(19, 15, 64) }, new Vector3(0, 0, -800))); + const camera = (this.mainCamera = new Camera({ backgroundColor: new Color(30, 39, 46) }, new Vector3(0, 300, -1300))); + + // rgb(30, 39, 46) + camera.rotate(Vector3.left, 0.4); this.sun = this.createObject(OBJ_NAMES[0], { position: Vector3.zero, scale: new Vector3(50, 50, 50), color: new Color(253, 224, 71), + layers: ['sun'], }); this.mercury = this.createObject(OBJ_NAMES[1], { - position: new Vector3(0, 0, 130), - scale: new Vector3(50, 50, 50), + position: new Vector3(0, 0, 250), + scale: new Vector3(150, 150, 150), color: new Color(177, 173, 173), }); this.venus = this.createObject(OBJ_NAMES[2], { - position: new Vector3(0, 0, 150), - scale: new Vector3(50, 50, 50), + position: new Vector3(350, 0, 0), + scale: new Vector3(150, 150, 150), color: new Color(249, 194, 26), }); this.earth = this.createObject(OBJ_NAMES[3], { - position: new Vector3(0, 0, 180), - scale: new Vector3(0.025, 0.025, 0.025), + position: new Vector3(0, -20, 450), + scale: new Vector3(0.05, 0.05, 0.05), color: new Color(79, 76, 176), }); + this.moon = this.createObject(OBJ_NAMES[3], { + position: new Vector3(0, -10, 480), + scale: new Vector3(0.02, 0.02, 0.02), + color: new Color(223, 230, 233), + }); + this.mars = this.createObject(OBJ_NAMES[4], { - position: new Vector3(0, 0, 200), - scale: new Vector3(3e-5, 3e-5, 3e-5), + position: new Vector3(0, 0, 600), + scale: new Vector3(1e-4, 1e-4, 1e-4), color: new Color(193, 68, 14), }); this.jupiter = this.createObject(OBJ_NAMES[5], { - position: new Vector3(0, 0, -300), - // scale: new Vector3(0.1, 0.1, 0.1), + position: new Vector3(0, -23, -750), + scale: new Vector3(0.7, 0.7, 0.7), color: new Color(201, 144, 57), }); this.saturn = this.createObject(OBJ_NAMES[6], { - position: new Vector3(0, 0, -400), + position: new Vector3(0, 0, -900), scale: new Vector3(0.1, 0.1, 0.1), color: new Color(234, 214, 184), }); this.uranus = this.createObject(OBJ_NAMES[7], { - position: new Vector3(0, 0, -500), + position: new Vector3(0, 0, -1000), scale: new Vector3(50, 50, 50), color: new Color(209, 231, 231), }); this.neptune = this.createObject(OBJ_NAMES[8], { - position: new Vector3(0, 0, -600), + position: new Vector3(0, 0, -1300), scale: new Vector3(1e-4, 1e-4, 1e-4), color: new Color(63, 84, 186), }); - this.lights.push(new DirectLight({})); + this.lights.push(new SpotLight({ position: Vector3.zero, radius: 5000, intensity: 1.2 })); + this.lights.push(new DirectLight({ direction: new Vector3(1, -2, 1).unit(), intensity: 0.3 })); + this.lights.push(new DirectLight({ direction: new Vector3(-1, -2, 1).unit(), intensity: 0.3 })); + // light for the sun + const sunLightsIntensity = 0.35; + + this.lights.push(new DirectLight({ direction: Vector3.forward, intensity: sunLightsIntensity, layers: ['sun'] })); + this.lights.push(new DirectLight({ direction: Vector3.backward, intensity: sunLightsIntensity, layers: ['sun'] })); + this.lights.push(new DirectLight({ direction: Vector3.left, intensity: sunLightsIntensity, layers: ['sun'] })); + this.lights.push(new DirectLight({ direction: Vector3.right, intensity: sunLightsIntensity, layers: ['sun'] })); + + this.lights.push(new DirectLight({ direction: new Vector3(1, 0, 1).unit(), intensity: sunLightsIntensity, layers: ['sun'] })); + this.lights.push(new DirectLight({ direction: new Vector3(1, 0, -1).unit(), intensity: sunLightsIntensity, layers: ['sun'] })); + this.lights.push(new DirectLight({ direction: new Vector3(-1, 0, -1).unit(), intensity: sunLightsIntensity, layers: ['sun'] })); + this.lights.push(new DirectLight({ direction: new Vector3(-1, 0, 1).unit(), intensity: sunLightsIntensity, layers: ['sun'] })); + + this.lights.push(new DirectLight({ direction: Vector3.up, intensity: sunLightsIntensity + 0.1, layers: ['sun'] })); addEventListener('keydown', (e) => { const speed = 30; @@ -127,16 +154,24 @@ export class SolarScene extends Scene { this.venus?.rotate(Vector3.up, 1.2 * speed, Vector3.zero); this.earth?.rotate(Vector3.down, 1.3 * speed, Vector3.zero); + this.earth?.rotate(Vector3.down, 1.3 * speed); this.mars?.rotate(Vector3.down, 1.4 * speed, Vector3.zero); + this.mars?.rotate(Vector3.down, 0.4 * speed); this.jupiter?.rotate(Vector3.down, 1.7 * speed, Vector3.zero); + this.jupiter?.rotate(Vector3.down, 0.7 * speed); + + this.saturn?.rotate(Vector3.down, 0.4 * speed, Vector3.zero); + this.saturn?.rotate(Vector3.down, 0.6 * speed); - this.saturn?.rotate(Vector3.down, 1.8 * speed, Vector3.zero); + this.uranus?.rotate(Vector3.up, 1.3 * speed, Vector3.zero); - this.uranus?.rotate(Vector3.up, 1.9 * speed, Vector3.zero); + this.neptune?.rotate(Vector3.down, 1 * speed, Vector3.zero); - this.neptune?.rotate(Vector3.down, 2 * speed, Vector3.zero); + // this.moon?.setPosition(Vector3.add(this.earth!.position, new Vector3(0, 0, 50))); + this.moon?.rotate(Vector3.down, 1.3 * speed, Vector3.zero); + this.moon?.rotate(Vector3.down, 8 * speed, this.earth?.position); } async prepareResources(): Promise {